package TestCase::ExchangeAPI {
  use TestCase::Point_3b;
  use TestCase::Point_3s;
  use TestCase::Point_3i;
  use TestCase::Point_3l;
  use TestCase::Point_3f;
  use TestCase::Point_3d;
  use TestCase::Minimal;
  use SPVM::Complex_2d;
  use SPVM::Util (INT8_MIN, INT8_MAX, INT16_MIN, INT16_MAX, INT32_MIN, INT32_MAX, INT64_MIN, INT64_MAX, FLT_MIN, FLT_MAX, DBL_MIN, DBL_MAX);
  
  sub FLOAT_PRECICE : float () { return 16384.5f; }
  sub DOUBLE_PRECICE : double () { return 65536.5; }

  sub return_undef : TestCase::Minimal () {
    
    return undef;
  }

  sub return_array : TestCase::Minimal[] () {
    
    my $minimal = new TestCase::Minimal[2];
    $minimal->[0] = new TestCase::Minimal;
    $minimal->[0]->set_x(1);
    $minimal->[0]->set_y(2);
    $minimal->[1] = new TestCase::Minimal;
    $minimal->[1]->set_x(3);
    $minimal->[1]->set_y(4);
    
    return $minimal;
  }

  sub return_oarray : oarray () {
    
    my $minimal = new TestCase::Minimal[2];
    $minimal->[0] = new TestCase::Minimal;
    $minimal->[0]->set_x(1);
    $minimal->[0]->set_y(2);
    $minimal->[1] = new TestCase::Minimal;
    $minimal->[1]->set_x(3);
    $minimal->[1]->set_y(4);
    
    return $minimal;
  }

  sub return_byte_value : TestCase::Point_3b () {
    my $point : TestCase::Point_3b;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = INT8_MIN();
    
    return $point;
  }
  
  sub return_short_value : TestCase::Point_3s () {
    my $point : TestCase::Point_3s;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = INT16_MIN();
    
    return $point;
  }

  sub return_int_value : TestCase::Point_3i () {
    my $point : TestCase::Point_3i;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = INT32_MIN();
    
    return $point;
  }

  sub return_long_value : TestCase::Point_3l () {
    my $point : TestCase::Point_3l;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = INT64_MIN();
    
    return $point;
  }

  sub return_float_value : TestCase::Point_3f () {
    my $point : TestCase::Point_3f;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = FLT_MIN();
    
    return $point;
  }

  sub return_double_value : TestCase::Point_3d () {
    my $point : TestCase::Point_3d;
    $point->{x} = 1;
    $point->{y} = 2;
    $point->{z} = DBL_MIN();
    
    return $point;
  }

  sub return_byte : byte () {
    
    return INT8_MIN();
  }
  
  sub return_short : short () {
    
    return INT16_MIN();
  }

  sub return_int : int () {
    
    return INT32_MIN();
  }

  sub return_long : long () {
    
    return INT64_MIN();
  }

  sub return_float : float () {
    
    return FLT_MIN();
  }

  sub return_double : double () {
    
    return DBL_MIN();
  }

  sub set_exception : int () {
    my $exception = $@;
    
    unless ($exception eq "あいう") {
      return 0;
    }
    
    return 1;
  }

  sub set_exception_undef : int () {
    my $exception = $@;
    
    unless ($exception == undef) {
      return 0;
    }
    
    return 1;
  }
  
  sub any_object_array : oarray ($oarray : oarray) {
    
    my $bytes = (SPVM::Byte[])$oarray;
    
    $bytes->[2] = SPVM::Byte->new(5);
    
    return $bytes;
  }
  
  sub string_argments_and_return_value : string ($string1 : string, $string2 : string) {
    return $string1 . $string2;
  }

  sub call_sub_value_arg_byte : TestCase::Point_3b ($point : TestCase::Point_3b) {
    return $point;
  }

  sub call_sub_value_arg_short : TestCase::Point_3s ($point : TestCase::Point_3s) {
    return $point;
  }

  sub call_sub_value_arg_int : TestCase::Point_3i ($point : TestCase::Point_3i) {
    return $point;
  }

  sub call_sub_value_arg_long : TestCase::Point_3l ($point : TestCase::Point_3l) {
    return $point;
  }

  sub call_sub_value_arg_float : TestCase::Point_3f ($point : TestCase::Point_3f) {
    return $point;
  }

  sub call_sub_value_arg_double : TestCase::Point_3d ($point : TestCase::Point_3d) {
    return $point;
  }
  
  sub call_sub_value_ref_numeric_ref_mixed_arg : void ($point1 : TestCase::Point_3i&, $value1 : int&, $point2 : TestCase::Point_3i&, $value2 : int&) {
    $point1->{x} = (int)($point1->{x} + 1);
    $point1->{y} = (int)($point1->{y} + 1);
    $point1->{z} = (int)($point1->{z} + 1);

    $$value1 = $$value1 + 1;

    $point2->{x} = (int)($point2->{x} + 1);
    $point2->{y} = (int)($point2->{y} + 1);
    $point2->{z} = (int)($point2->{z} + 1);

    $$value2 = $$value2 + 1;
  }

  sub call_sub_value_ref_arg_byte : int ($point : TestCase::Point_3b&) {
    $point->{x} = (byte)($point->{x} + 1);
    $point->{y} = (byte)($point->{y} + 1);
    $point->{z} = (byte)($point->{z} + 1);
  }

  sub call_sub_value_ref_arg_short : int ($point : TestCase::Point_3s&) {
    $point->{x} = (short)($point->{x} + 1);
    $point->{y} = (short)($point->{y} + 1);
    $point->{z} = (short)($point->{z} + 1);
  }

  sub call_sub_value_ref_arg_int : int ($point : TestCase::Point_3i&) {
    $point->{x} = (int)($point->{x} + 1);
    $point->{y} = (int)($point->{y} + 1);
    $point->{z} = (int)($point->{z} + 1);
  }

  sub call_sub_value_ref_arg_long : int ($point : TestCase::Point_3l&) {
    $point->{x} = (long)($point->{x} + 1);
    $point->{y} = (long)($point->{y} + 1);
    $point->{z} = (long)($point->{z} + 1);
  }

  sub call_sub_value_ref_arg_float : int ($point : TestCase::Point_3f&) {
    $point->{x} = (float)($point->{x} + 1);
    $point->{y} = (float)($point->{y} + 1);
    $point->{z} = (float)($point->{z} + 1);
  }

  sub call_sub_value_ref_arg_double : int ($point : TestCase::Point_3d&) {
    $point->{x} = (double)($point->{x} + 1);
    $point->{y} = (double)($point->{y} + 1);
    $point->{z} = (double)($point->{z} + 1);
  }
  
  sub call_sub_numeric_ref_arg_byte : int ($byte_val : byte&) {
    $$byte_val = (byte)($$byte_val + 1);
  }
  
  sub call_sub_numeric_ref_arg_short : int ($short_val : short&) {
    $$short_val = (short)($$short_val + 1);
  }
  
  sub call_sub_numeric_ref_arg_int : int ($int_val : int&) {
    $$int_val = $$int_val + 1;
  }

  sub call_sub_numeric_ref_arg_long : int ($long_val : long&) {
    $$long_val = $$long_val + 1;
  }

  sub call_sub_numeric_ref_arg_float : int ($float_val : float&) {
    $$float_val = $$float_val + 1;
  }

  sub call_sub_numeric_ref_arg_double : int ($double_val : double&) {
    $$double_val = $$double_val + 1;
  }
  
  sub spvm_object_set_object : int ($obj : TestCase) {
    my $nums = $obj->{x_iarray};
    my $values = ($obj->{x_barray});
    
    
    # [INT32_MAX, INT32_MAX]
    if (@$nums == 2) {
      if ($nums->[0] == 2147483647) {
        if ($nums->[1] == 2147483647) {
          # abc
          if ($values->[0] == 97) {
            if ($values->[1] == 98) {
              if ($values->[2] == 99) {
                if (@$values == 3) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_object_set : int ($obj : TestCase) {
    if ($obj->{x_byte} == 127) {
      if ($obj->{x_short} == 32767) {
        if ($obj->{x_int} == 2147483647) {
          if ($obj->{x_long} == 9223372036854775807L) {
            if ($obj->{x_float} == FLOAT_PRECICE()) {
              if ($obj->{x_double} == DOUBLE_PRECICE()) {
                if ($obj->{minimal}->{x} == 3) {
                  return 1;
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub return_byte_object_only : SPVM::Byte ($values : SPVM::Byte) {
    
    return $values;
  }

  sub return_short_object_only : SPVM::Short ($values : SPVM::Short) {
    
    return $values;
  }

  sub return_int_object_only : SPVM::Int ($values : SPVM::Int) {
    
    return $values;
  }

  sub return_long_object_only : SPVM::Long ($values : SPVM::Long) {
    
    return $values;
  }

  sub return_float_object_only : SPVM::Float ($values : SPVM::Float) {
    
    return $values;
  }

  sub return_double_object_only : SPVM::Double ($values : SPVM::Double) {
    
    return $values;
  }
  
  sub return_any_object_only : object ($values : object) {
    
    return $values;
  }

  sub return_string_array_only : string[] ($values : string[]) {
    
    return $values;
  }
  
  sub return_byte_array_only : byte[] ($values : byte[]) {
    
    return $values;
  }

  sub return_short_array_only : short[] ($values : short[]) {
    
    return $values;
  }

  sub return_int_array_only : int[] ($values : int[]) {
    
    return $values;
  }

  sub return_long_array_only : long[] ($values : long[]) {
    
    return $values;
  }

  sub return_float_array_only : float[] ($values : float[]) {
    
    return $values;
  }

  sub return_double_array_only : double[] ($values : double[]) {
    
    return $values;
  }

  # SPVM Functions
  sub spvm_new_byte_array_from_bin : int ($values : byte[]) {
    
    unless ((string)$values eq "あ") {
      return 0;
    }
    
    return 1;
  }

  sub spvm_new_byte_array_bin : int ($values : byte[]) {
    
    if ($values->[0] == 97) {
      if ($values->[1] == 98) {
        if ($values->[2] == 99) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_byte_array_binary_pack : int ($values : byte[]) {
    
    if ($values->[0] == 97) {
      if ($values->[1] == 98) {
        if ($values->[2] == INT8_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_short_array_binary_pack : int ($values : short[]) {
    
    if ((int)$values->[0] == (int)(short)97) {
      if ((int)$values->[1] == (int)(short)98) {
        if ((int)$values->[2] == (int)(short)INT16_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }
  
  sub spvm_new_int_array_binary_pack : int ($values : int[]) {
    
    if ($values->[0] == (int)97) {
      if ($values->[1] == (int)98) {
        if ($values->[2] == (int)INT32_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_long_array_binary_pack : int ($values : long[]) {
    
    if ($values->[0] == (long)97) {
      if ($values->[1] == (long)98) {
        if ($values->[2] == (long)INT64_MAX()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_float_array_binary_pack : int ($values : float[]) {
    
    if ($values->[0] == (float)97) {
      if ($values->[1] == (float)98) {
        if ($values->[2] == (float)FLOAT_PRECICE()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }
  
  sub spvm_new_double_array_binary_pack : int ($values : double[]) {
    
    if ($values->[0] == (double)97) {
      if ($values->[1] == (double)98) {
        if ($values->[2] == (double)DOUBLE_PRECICE()) {
           if (@$values == 3) {
             return 1;
           }
        }
      }
    }
    
    return 0;
  }
  

  sub spvm_new_object_array_len_element_oarray : int ($nums : TestCase[]) {
    if ($nums->[0]{x_int} == 1) {
      if ($nums->[1]{x_int} == 2) {
        return 1;
      }
    }
    
    return 0;
  }

  sub spvm_new_object_array_len_element_barray : int ($nums : byte[][]) {
    
    if ($nums->[0][0] == 1) {
      if ($nums->[0][1] == 2) {
        if ($nums->[0][2] == 3) {
          if ($nums->[1][0] == 4) {
            if ($nums->[1][1] == 5) {
              if ($nums->[1][2] == 6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_object_array_len_element_sarray : int ($nums : short[][]) {
    if ((int)$nums->[0][0] == (int)(short)1) {
      if ((int)$nums->[0][1] == (int)(short)2) {
        if ((int)$nums->[0][2] == (int)(short)3) {
          if ((int)$nums->[1][0] == (int)(short)4) {
            if ((int)$nums->[1][1] == (int)(short)5) {
              if ((int)$nums->[1][2] == (int)(short)6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_object_array_len_element_iarray : int ($nums : int[][]) {
    if ($nums->[0][0] == 1) {
      if ($nums->[0][1] == 2) {
        if ($nums->[0][2] == 3) {
          if ($nums->[1][0] == 4) {
            if ($nums->[1][1] == 5) {
              if ($nums->[1][2] == 6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_object_array_len_element_larray : int ($nums : long[][]) {
    if ($nums->[0][0] == (long)1) {
      if ($nums->[0][1] == (long)2) {
        if ($nums->[0][2] == (long)3) {
          if ($nums->[1][0] == (long)4) {
            if ($nums->[1][1] == (long)5) {
              if ($nums->[1][2] == (long)6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_object_array_len_element_farray : int ($nums : float[][]) {
    if ($nums->[0][0] == (float)1) {
      if ($nums->[0][1] == (float)2) {
        if ($nums->[0][2] == (float)3) {
          if ($nums->[1][0] == (float)4) {
            if ($nums->[1][1] == (float)5) {
              if ($nums->[1][2] == (float)6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_object_array_len_element_darray : int ($nums : double[][]) {
    if ($nums->[0][0] == (double)1) {
      if ($nums->[0][1] == (double)2) {
        if ($nums->[0][2] == (double)3) {
          if ($nums->[1][0] == (double)4) {
            if ($nums->[1][1] == (double)5) {
              if ($nums->[1][2] == (double)6) {
                return 1;
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  # SPVM set and get
  sub spvm_set_and_get_byte : int ($nums : byte[]) {
    
    if ($nums->[0] == 0) {
      if ($nums->[1] == INT8_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  sub spvm_set_and_get_short : int ($nums : short[]) {
    
    if ($nums->[0] == 0) {
      if ($nums->[1] == INT16_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  sub spvm_set_and_get_int : int ($nums : int[]) {
    
    if ($nums->[0] == 0) {
      if ($nums->[1] == INT32_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  sub spvm_set_and_get_long : int ($nums : long[]) {
    
    if ($nums->[0] == 0L) {
      if ($nums->[1] == INT64_MAX()) {
        return 1;
      }
    }
    
    return 0;
  }
  sub spvm_set_and_get_float : int ($nums : float[]) {
    
    if ($nums->[0] == 0.0f) {
      if ($nums->[1] == FLOAT_PRECICE()) {
        return 1;
      }
    }
    
    return 0;
  }
  sub spvm_set_and_get_double : int ($nums : double[]) {
    
    if ($nums->[0] == 0.0) {
      if ($nums->[1] == DOUBLE_PRECICE()) {
        return 1;
      }
    }
    
    return 0;
  }

  sub spvm_set_and_get_mulnum_t_int : int ($points : TestCase::Point_3i[]) {
    
    if ($points->[1]{x} == INT32_MIN()) {
      if ($points->[1]{y} == 1) {
        if ($points->[1]{z} == 2) {
          return 1;
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_byte : int ($points : TestCase::Point_3b[]) {
    
    if ($points->[0]{x} == INT8_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_short : int ($points : TestCase::Point_3s[]) {
    
    if ($points->[0]{x} == INT16_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_int : int ($points : TestCase::Point_3i[]) {
    
    if ($points->[0]{x} == INT32_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_long : int ($points : TestCase::Point_3l[]) {
    
    if ($points->[0]{x} == INT64_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_float : int ($points : TestCase::Point_3f[]) {
    
    if ($points->[0]{x} == FLT_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_double : int ($points : TestCase::Point_3d[]) {
    
    if ($points->[0]{x} == DBL_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_binary_byte : int ($points : TestCase::Point_3b[]) {
    if ($points->[0]{x} == INT8_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_binary_short : int ($points : TestCase::Point_3s[]) {
    if ($points->[0]{x} == INT16_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_binary_int : int ($points : TestCase::Point_3i[]) {
    if ($points->[0]{x} == INT32_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_binary_long : int ($points : TestCase::Point_3l[]) {
    if ($points->[0]{x} == INT64_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_binary_float : int ($points : TestCase::Point_3f[]) {
    if ($points->[0]{x} == FLT_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }

  sub spvm_new_mulnum_array_binary_double : int ($points : TestCase::Point_3d[]) {
    if ($points->[0]{x} == DBL_MIN()) {
      if ($points->[0]{y} == 1) {
        if ($points->[0]{z} == 2) {
          if ($points->[1]{x} == 3) {
            if ($points->[1]{y} == 4) {
              if ($points->[1]{z} == 5) {
                if ($points->[2]{x} == 6) {
                  if ($points->[2]{y} == 7) {
                    if ($points->[2]{z} == 8) {
                      if (@$points == 3) {
                        return 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    return 0;
  }
}
