package jazz.lang;

///////////////////////////////////////////////////////////////////////////////
//
//                          Mathematical functions
//
///////////////////////////////////////////////////////////////////////////////

public abstract final class Math {

  public static E: float = native("double java.lang.Math.E");

  public static PI: float = native("double java.lang.Math.PI");

  public native static acos(x: float): float =
    "double java.lang.Math.acos(double)";
  
  public native static asin(x: float): float =
    "double java.lang.Math.asin(double)";
  
  public native static atan(x: float): float =
    "double java.lang.Math.atan(double)";
  
  public native static ceil(x:float): float =
    "double java.lang.Math.ceil(double)";
  
  public native static cos(x:float): float =
    "double java.lang.Math.cos(double)";
  
  public native static exp(x:float): float =
    "double java.lang.Math.exp(double)";
  
  public native static floor(x:float): float =
    "double java.lang.Math.floor(double)";
  
  public native static log(x:float): float =
    "double java.lang.Math.log(double)";
  
  public native static pow(x:float, e: float): float =
    "double java.lang.Math.pow(double, double)";
  
  public native static random(): int =
    "double java.lang.Math.random()";
  
  public native static round(x:float): int =
    "long java.lang.Math.round(double)";
  
  public native static sin(x: float): float =
    "double java.lang.Math.sin(double)";
  
  public native static sqrt(x: float): float =
    "double java.lang.Math.sqrt(double)";
  
  public native static tan(x: float): float =
    "double java.lang.Math.tan(double)";

  public static abs<T: float>(x: T): T;
  public static max<T: float>(x: T, y: T): T;
  public static min<T: float>(x: T, y: T): T;
  public static trunc(x: float): int;
}

///////////////////////////////////////////////////////////////////////////////
//
//                               Implementation
//
///////////////////////////////////////////////////////////////////////////////

Math.abs(x) = (x < 0 ? -x : x);
Math.min(x, y) = (x < y ? x : y);
Math.max(x, y) = (x > y ? x : y);
Math.trunc(x) = Math.round(Math.floor(x));