class TestCase::Operator::Divide {
  use Fn;
  use Array;
  
  #
  # Spec tests
  #
  static method divide_byte_byte : int () {
    my $total = (byte)7 / (byte)3;
    
    unless ($total == 2) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  static method divide_short_short : int () {
    my $total = (short)10 / (short)2;
    
    unless ($total == 5) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  static method divide_int_byte : int () {
    my $total = 12 / (byte)5;
    
    unless ($total == 2) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  static method divide_int_short : int () {
    my $total = 7 / (short)3;
    
    unless ($total == 2) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  static method divide_byte_int : int () {
    my $total = (byte)10 / -2;
    
    unless ($total == -5) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  static method divide_short_int : int () {
    my $total = (short)-7 / 3;
    
    unless ($total == -2) {
      return 0;
    }
    
    unless ($total isa int) {
      return 0;
    }
    
    return 1;
  }

  static method divide_int_int : int () {
    my $total1 = -1000000000 / -2;
    
    unless ($total1 == 500000000) {
      return 0;
    }
    
    unless ($total1 isa int) {
      return 0;
    }
    
    return 1;
  }

  static method divide_long_long : int () {
    my $total1 = -100000000000L / -2L;
    
    unless ($total1 == 50000000000L) {
      return 0;
    }
    
    unless ($total1 isa long) {
      return 0;
    }
    
    return 1;
  }

  static method divide_int_float : int () {
    my $total = 5 / 2.5f;
    
    unless ($total == 2.0f) {
      return 0;
    }
    
    unless ($total isa float) {
      return 0;
    }
    
    return 1;
  }

  static method divide_int_double : int () {
    my $total = 10 / 2.5;
    
    unless ($total == 4.0) {
      return 0;
    }
    
    unless ($total isa double) {
      return 0;
    }
    
    return 1;
  }

  static method divide_float_float : int () {
    my $total = 20.0f / -2.5f;
    
    unless ($total == -8.0f) {
      return 0;
    }
    
    unless ($total isa float) {
      return 0;
    }
    
    return 1;
  }
  static method divide_double_double : int () {
    my $total = 1.25 / 2.5;
    
    unless ($total == 0.5) {
      return 0;
    }
    
    unless ($total isa double) {
      return 0;
    }
    
    return 1;
  }

  static method divide_double_double_big : int () {
    my $total = 1000000000.5 / 2.0;
    
    unless ($total == 500000000.25) {
      return 0;
    }
    
    unless ($total isa double) {
      return 0;
    }
    
    return 1;
  }

  static method divide_unsigned_int : int () {
    {
      my $x = Fn->UINT32_MAX;

      # 0 = -1 / 3
      my $ret_div = $x / 3;
      
      # 1431655765 = 4,294,967,295 div_uint 3
      my $ret_divui = $x div_uint 3;
      
      unless ($ret_divui isa int) {
        return 0;
      }
      
      unless ($ret_div == 0) {
        return 0;
      }
      
      unless ($ret_divui == 1431655765) {
        return 0;
      }
    }
    
    return 1;
  }

  static method divide_unsigned_long : int () {
    {
      my $x = Fn->UINT64_MAX;

      # 0 = -1 / 3
      my $ret_div = $x / 3L;
      
      # 6,148,914,691,236,517,205 = 18,446,744,073,709,551,615 div_ulong 3
      my $ret_divul = $x div_ulong 3L;

      unless ($ret_divul isa long) {
        return 0;
      }
      
      unless ($ret_div == 0) {
        return 0;
      }
      
      unless ($ret_divul == 6148914691236517205L) {
        return 0;
      }
    }
    
    return 1;
  }

  #
  # Optional tests
  #
  static method divide : int () {
    # int
    my $int_success = 0;
    {
      my $value1 : int = 8 / 4;
      my $value2 : int = (byte)8 / 4;
      my $value3 : int = 8 / (byte)4;
      my $value4 : int = (short)8 / 4;
      my $value5 : int = 8 / (short)4;
      my $value6 : int = (byte)8 / (byte)4;
      my $value7 : int = (short)8 / (short)4;
      my $value8 : int = (byte)8 / (short)4;
      my $value9 : int = 8 / 3;
      if ($value1 == 2) {
        if ($value2 == 2) {
          if ($value3 == 2) {
            if ($value4 == 2) {
              if ($value5 == 2) {
                if ($value6 == 2) {
                  if ($value7 == 2) {
                    if ($value8 == 2) {
                      if ($value9 == 2) {
                        $int_success = 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    # float
    my $float_success = 0;
    {
      my $value1 : float = 1.0f / 2.0f;
      my $value2 : float = (byte)1 / 2.0f;
      my $value3 : float = 1.0f / (byte)2;
      my $value4 : float = (short)1 / 2.0f;
      my $value5 : float = 1.0f / (short)2;
      my $value6 : float = 1 / 2.0f;
      my $value7 : float = 1.0f / 2;
      if ($value1 == 0.5f) {
        if ($value2 == 0.5f) {
          if ($value3 == 0.5f) {
            if ($value4 == 0.5f) {
              if ($value5 == 0.5f) {
                if ($value6 == 0.5f) {
                  if ($value7 == 0.5f) {
                    $float_success = 1;
                  }
                }
              }
            }
          }
        }
      }
    }
    
    # double
    my $double_success = 0;
    {
      my $value1 : double = 1.0 / 2.0;
      my $value2 : double = (byte)1 / 2.0;
      my $value3 : double = 1.0 / (byte)2;
      my $value4 : double = (short)1 / 2.0;
      my $value5 : double = 1.0 / (short)2;
      my $value6 : double = 1 / 2.0;
      my $value7 : double = 1.0 / 2;
      my $value8 : double = 1.0 / 2.0f;
      my $value9 : double = 1.0f / 2.0;
      if ($value1 == 0.5f) {
        if ($value2 == 0.5f) {
          if ($value3 == 0.5f) {
            if ($value4 == 0.5f) {
              if ($value5 == 0.5f) {
                if ($value6 == 0.5f) {
                  if ($value7 == 0.5f) {
                    if ($value8 == 0.5f) {
                      if ($value9 == 0.5f) {
                        $double_success = 1;
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    
    if ($int_success && $float_success && $double_success) {
      return 1;
    }

    return 0;
  }
}
