package MyComplex {
  use SPVM::Complex_2f;
  use SPVM::Complex_2d;
  use SPVM::Math (complexf);
  use SPVM::Math (complex);
  use SPVM::Math (caddf, csubf, cmulf, cscamulf, cdivf);
  use SPVM::Math (cadd, csub, cmul, cscamul, cdiv);
  
  sub new_float_complex : void () {
    
    my $z : SPVM::Complex_2f;
    $z->{re} = 1.5f;
    $z->{im} = 1.7f;
  }

  sub new_float_complex_func : void () {
    my $z = complexf(1.5f, 1.7f);
  }
  
  sub new_double_complex : void () {
    my $z : SPVM::Complex_2d;
    $z->{re} = 1.5;
    $z->{im} = 1.7;
  }

  sub new_double_complex_func : void () {
    my $z = complex(1.5, 1.7);
  }

  sub complex_float_operations : void () {

    my $z1 = complexf(1.5f, 1.7f);
    my $z2 = complexf(2.5f, 2.7f);

    # Addition
    my $z_add = caddf($z1, $z2);

    # Subtract
    my $z_method = csubf($z1, $z2);

    # Multiply
    my $z_mul = cmulf($z1, $z2);

    # Scalar Multiply
    my $z_scamul = cscamulf(3, $z2);

    # Division
    my $z_div = cdivf($z1, $z2);
  }

  sub complex_double_operations : void () {

    my $z1 = complex(1.5, 1.7);
    my $z2 = complex(2.5, 2.7);

    # Addition
    my $z_add = cadd($z1, $z2);

    # Subtract
    my $z_method = csub($z1, $z2);

    # Multiply
    my $z_mul = cmul($z1, $z2);

    # Scalar Multiply
    my $z_scamul = cscamul(3, $z2);

    # Division
    my $z_div = cdiv($z1, $z2);
  }

  sub complex_float_array : void () {
    my $zs = new SPVM::Complex_2f[100];

    for (my $i = 0; $i < @$zs; $i++) {
      my $z = $zs->[$i];
      $z->{re} = 1.5f;
      $z->{im} = 1.7f;
    }
  }
  
  sub complex_double_array : void () {
    my $zs = new SPVM::Complex_2d[100];

    for (my $i = 0; $i < @$zs; $i++) {
      my $z = $zs->[$i];
      $z->{re} = 1.5;
      $z->{im} = 1.7;
    }
  }

  sub complex_call_from_perl : SPVM::Complex_2d ($z1 : SPVM::Complex_2d, $z2 : SPVM::Complex_2d) {
    
    my $z_ret = cadd($z1, $z2);
    
    return $z_ret;
  }
}