/*
 * Copyright 2008 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package java.lang;

/**
 * Math utility methods and constants.
 */
public final class Math {
  // The following methods are not implemented because JS doesn't provide the
  // necessary pieces:
  //   public static double ulp (double x)
  //   public static float ulp (float x)
  //   public static int getExponent (double d)
  //   public static int getExponent (float f)
  //   public static double IEEEremainder(double f1, double f2)
  //   public static double nextAfter(double start, double direction)
  //   public static float nextAfter(float start, float direction)
  //   public static double nextUp(double start) {
  //     return nextAfter(start, 1.0d);
  //   }
  //   public static float nextUp(float start) {
  //     return nextAfter(start,1.0f);
  //   }

  public static final double E = 2.7182818284590452354;
  public static final double PI = 3.14159265358979323846;

  private static final double PI_OVER_180 = PI / 180.0;
  private static final double PI_UNDER_180 = 180.0 / PI;

  public static double abs(double x) {
    // This is implemented this way so that either positive or negative zeroes
    // get converted to positive zeros.
    // See http://www.concentric.net/~Ttwang/tech/javafloat.htm for details.
    return x <= 0 ? 0.0 - x : x;
  }

  public static float abs(float x) {
    return (float) abs((double) x);
  }

  public static int abs(int x) {
    return x < 0 ? -x : x;
  }

  public static long abs(long x) {
    return x < 0 ? -x : x;
  }

  public static native double acos(double x) /*-{
    return Math.acos(x);
  }-*/;

  public static native double asin(double x) /*-{
    return Math.asin(x);
  }-*/;

  public static native double atan(double x) /*-{
    return Math.atan(x);
  }-*/;

  public static native double atan2(double y, double x) /*-{
    return Math.atan2(y,x);
  }-*/;

  public static double cbrt(double x) {
    return Math.pow(x, 1.0 / 3.0);
  }

  public static native double ceil(double x) /*-{
    return Math.ceil(x);
  }-*/;

  public static double copySign(double magnitude, double sign) {
    if (sign < 0) {
      return (magnitude < 0) ? magnitude : -magnitude;
    } else {
      return (magnitude > 0) ? magnitude : -magnitude;
    }
  }

  public static float copySign(float magnitude, float sign) {
    return (float) (copySign((double) magnitude, (double) sign));
  }

  public static native double cos(double x) /*-{
    return Math.cos(x);
  }-*/;

  public static native double cosh(double x) /*-{
    return (Math.exp(x) + Math.exp(-x)) / 2.0;
  }-*/;

  public static native double exp(double x) /*-{
    return Math.exp(x);
  }-*/;

  public static double expm1(double d) {
    if (d == 0.0 || Double.isNaN(d)) {
      return d; // "a zero with same sign as argument", arg is zero, so...
    } else if (!Double.isInfinite(d)) {
      if (d < 0.0d) {
        return -1.0d;
      } else {
        return Double.POSITIVE_INFINITY;
      }
    }
    return exp(d) + 1.0d;
  }

  public static native double floor(double x) /*-{
    return Math.floor(x);
  }-*/;

  public static double hypot(double x, double y) {
    return sqrt(x * x + y * y);
  }

  public static native double log(double x) /*-{
    return Math.log(x);
  }-*/;

  public static native double log10(double x) /*-{
    return Math.log(x) * Math.LOG10E;
  }-*/;

  public static double log1p(double x) {
    return Math.log(x + 1.0d);
  }

  public static double max(double x, double y) {
    return x > y ? x : y;
  }

  public static float max(float x, float y) {
    return x > y ? x : y;
  }

  public static int max(int x, int y) {
    return x > y ? x : y;
  }

  public static long max(long x, long y) {
    return x > y ? x : y;
  }

  public static double min(double x, double y) {
    return x < y ? x : y;
  }

  public static float min(float x, float y) {
    return x < y ? x : y;
  }

  public static int min(int x, int y) {
    return x < y ? x : y;
  }

  public static long min(long x, long y) {
    return x < y ? x : y;
  }

  public static native double pow(double x, double exp) /*-{
    return Math.pow(x, exp);
  }-*/;

  public static native double random() /*-{
    return Math.random();
  }-*/;

  public static double rint(double d) {
    if (Double.isNaN(d)) {
      return d;
    } else if (Double.isInfinite(d)) {
      return d;
    } else if (d == 0.0d) {
      return d;
    } else {
      return round(d);
    }
  }

  public static long round(double x) {
    return (long) round0(x);
  }

  public static native int round(float x) /*-{
    return Math.round(x);
  }-*/;

  public static double scalb(double d, int scaleFactor) {
    if (scaleFactor > 0) {
      return d * (1 << scaleFactor);
    } else if (scaleFactor == 0) {
      return d;
    } else {
      return d * 1.0d / (1 << -scaleFactor);
    }
  }

  public static float scalb(float f, int scaleFactor) {
    if (scaleFactor > 0) {
      return f * (1 << scaleFactor);
    } else if (scaleFactor == 0) {
      return f;
    } else {
      return f * 1.0f / (1 << -scaleFactor);
    }
  }

  public static double signum(double d) {
    if (d > 0.0d) {
      return 1.0d;
    } else if (d < 0.0d) {
      return -1.0d;
    } else {
      return 0.0d;
    }
  }

  public static float signum(float f) {
    if (f > 0.0f) {
      return 1.0f;
    } else if (f < 0.0f) {
      return -1.0f;
    } else {
      return 0.0f;
    }
  }

  public static native double sin(double x) /*-{
    return Math.sin(x);
  }-*/;

  public static native double sinh(double x) /*-{
    return (Math.exp(x) - Math.exp(-x)) / 2.0;
  }-*/;

  public static native double sqrt(double x) /*-{
    return Math.sqrt(x);
  }-*/;

  public static native double tan(double x) /*-{
    return Math.tan(x);
  }-*/;

  public static native double tanh(double x) /*-{
    if (x == Infinity) {
      return 1.0;
    }
    var e2x = Math.exp(2.0 * x);
    return (e2x - 1) / (e2x + 1);
  }-*/;

  public static double toDegrees(double x) {
    return x * PI_UNDER_180;
  }

  public static double toRadians(double x) {
    return x * PI_OVER_180;
  }

  private static native double round0(double x) /*-{
    return Math.round(x);
  }-*/;
}
