class TestCase::Simple : public {
  version "1.001009000";
  
  allow TestCase::Operator::CopyFields;
  
  use TestCase::Minimal;
  use Hash;
  use Point;
  
  interface Stringable;
  interface Cloneable;
  interface TestCase::Interface::Type;
  
  our $CACHE_POINT : public cache Point;
  our $NOT_CACHE_POINT : public Point;
  
  has x : rw public int;
  has y : rw public int;
  
  has byte_value : rw public byte;
  has short_value : rw public short;
  has int_value : rw public int;
  has long_value : rw public long;
  has float_value : rw public float;
  has double_value : rw public double;
  has object_value : rw public TestCase::Minimal;
  has string_value : rw public string;

  has minimal : rw public TestCase::Minimal;
  
  has parent_child_duplicate : int;
  
  our $FOO : public rw int;
  our $VAR_PRIVATE : private int;

  our $DESTROY_VALUE : public int;
  
  method get_x : int () {
    return $self->{x};
  }

  static method new : TestCase::Simple () {
    
    my $self = new TestCase::Simple;
    
    # Check field access for duplicate fields.
    $self->{parent_child_duplicate};
    
    return $self;
  }

  static method new_xy : TestCase::Simple ($x : int, $y : int) {
    
    my $simple = new TestCase::Simple;
    $simple->{x} = $x;
    $simple->{y} = $y;
    
    return $simple;
  }

  static method import_method1 : int () {
    return 1;
  }

  static method import_method2 : int () {
    return 2;
  }
  
  method to_string : string () {
    my $x = $self->x;
    my $y = $self->y;
    
    my $string = "($x,$y):Simple";
    
    return $string;
  }

  method clone : TestCase::Simple () {
    my $new_simple = TestCase::Simple->new;
    
    my $x = $self->x;
    my $y = $self->y;
    
    $new_simple->set_x($x);
    $new_simple->set_y($y);
    
    return $new_simple;
  }

  method interface_shared1 : string ($num : int) {
    return "interface_shared1 $num";
  }
  
  static method new_options : TestCase::Simple ($options : object[] = undef) {
    my $options_h = Hash->new($options);
    
    my $x = $options_h->get_or_default("x", 0)->(int);
    $options_h->delete("x");
    
    my $y = $options_h->get_or_default("y", 0)->(int);
    $options_h->delete("y");
    
    my $self = new TestCase::Simple;
    
    $self->{x} = $x;
    $self->{y} = $y;
    
    return $self;
  }
  
  # https://github.com/yuki-kimoto/SPVM/issues/369
  method issues_369 : int () {
    
    if (1 || "") {
      
    }
    elsif ("") {
      
    }
    unless ($self) {
      return 0;
    }
    
    return 1;
  }
  
  method clear : void () {
    $self->{x} = 0;
    $self->{y} = 0;
  }
  
  method DESTROY : void () {
    
    $TestCase::Simple::DESTROY_VALUE += 1;
    
  }
  
  static method call_recursive : TestCase::Simple () {
    my $self = TestCase::Simple->call_recursive;
    
    return $self;
  }
  
  method arg_object : object ($object : object) {
    return $object;
  }
  
  method arg_object_option : object () {
    return undef;
  }
  
  method arg_any_object_array : object ($objects : object[]) {
    return $objects;
  }
  
  method arg_inheritance : Point[] ($objects : Point[]) {
    return $objects;
  }
  
  static method args_signature_class_method : void ($args1 : string, $args2 : mutable string, $args3 : string[], $args4 : Point[][], $args5 : int*) {
  
  }
  
  method args_signature_instance_method : void ($args1 : string, $args2 : mutable string, $args3 : string[], $args4 : Point[][], $args5 : int*) {
  
  }
  
}
