package TestCase::List {
  use SPVM::Int;
  
  has values : object[];
  has length : int;
  has capacity : int;
  
  sub test_list : int () {
    my $list = TestCase::List->new(5);
    $list->add(SPVM::Int->new(1));
    $list->add(SPVM::Int->new(2));
    
    my $onum1 = (SPVM::Int)$list->get(1);
    my $objects = new object[] {SPVM::Int->new(4), SPVM::Int->new(5)};
    $list->add_all($objects);
    
    my $onum2 = (SPVM::Int)$list->get(2);

    my $onums = $list->sub_list(2, 3);
    my $onum3 = (SPVM::Int)$onums->[1];
    
    my $ok = 0;
    if ($onum1->val == 2) {
      if ($onum2->val == 4) {
        if ($onum3->val == 5) {
          $ok = 1;
        }
      }
    }
    
    return $ok;
  }
  
  sub new : TestCase::List ($capacity : int) {
    my $self = new TestCase::List;
    
    $self->{capacity} = $capacity;
    
    $self->{values} = new object[$capacity];
    
    return $self;
  }
  
  sub add : void ($self : self, $object : object) {
    my $length = $self->{length};
    my $capacity = $self->{capacity};
    
    if ($length >= $capacity) {
      my $new_capacity = $capacity * 2;
      $self->{values} = new object[$new_capacity];
      $self->{capacity} = $new_capacity;
    }
    
    $self->{values}[$length] = $object;
    
    $self->{length} = $self->{length} + 1;
  }
  
  sub add_all : void ($self : self, $objects : object[]) {
    for (my $i = 0; $i < @$objects; $i++) {
      if ($objects->[$i]) {
        $self->add($objects->[$i]);
      }
      else {
        croak "Error";
      }
    }
  }
  
  sub get : object ($self : self, $index : int) {
    return $self->{values}[$index];
  }
  
  sub sub_list : object[] ($self : self, $from : int, $to : int) {
    my $length = $to - $from + 1;
    
    my $new_values = new object[$length];
    for (my $i = $from; $i <= $to; $i++) {
      $new_values->[$i - $from] = $self->{values}[$i];
    }
    
    return $new_values;
  }
}
