/*
 * 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;

import jsinterop.annotations.JsPackage;
import jsinterop.annotations.JsType;

/**
 * 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 double acos(double x) {
    return NativeMath.acos(x);
  }

  public static double asin(double x) {
    return NativeMath.asin(x);
  }

  public static int addExact(int x, int y) {
    int r = x + y;
    // "Hacker's Delight" 2-12 Overflow if both arguments have the opposite sign of the result
    throwOverflowIf(((x ^ r) & (y ^ r)) < 0);
    return r;
  }

  public static long addExact(long x, long y) {
    long r = x + y;
    // "Hacker's Delight" 2-12 Overflow if both arguments have the opposite sign of the result
    throwOverflowIf(((x ^ r) & (y ^ r)) < 0);
    return r;
  }

  public static double atan(double x) {
    return NativeMath.atan(x);
  }

  public static double atan2(double y, double x) {
    return NativeMath.atan2(y, x);
  }

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

  public static double ceil(double x) {
    return NativeMath.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 double cos(double x) {
    return NativeMath.cos(x);
  }

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

  public static int decrementExact(int x) {
    throwOverflowIf(x == Integer.MIN_VALUE);
    return x - 1;
  }

  public static long decrementExact(long x) {
    throwOverflowIf(x == Long.MIN_VALUE);
    return x - 1;
  }

  public static double exp(double x) {
    return NativeMath.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 double floor(double x) {
    return NativeMath.floor(x);
  }

  public static int floorDiv(int dividend, int divisor) {
    throwDivByZeroIf(divisor == 0);
    int r = dividend / divisor;
    // if the signs are different and modulo not zero, round down
    if ((dividend ^ divisor) < 0 && (r * divisor != dividend)) {
      r--;
    }
    return r;
  }

  public static long floorDiv(long dividend, long divisor) {
    throwDivByZeroIf(divisor == 0);
    long r = dividend / divisor;
    // if the signs are different and modulo not zero, round down
    if ((dividend ^ divisor) < 0 && (r * divisor != dividend)) {
      r--;
    }
    return r;
  }

  public static int floorMod(int dividend, int divisor) {
    return dividend - floorDiv(dividend, divisor) * divisor;
  }

  public static long floorMod(long dividend, long divisor) {
    return dividend - floorDiv(dividend, divisor) * divisor;
  }

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

  public static int incrementExact(int x) {
    throwOverflowIf(x == Integer.MAX_VALUE);
    return x + 1;
  }

  public static long incrementExact(long x) {
    throwOverflowIf(x == Long.MAX_VALUE);
    return x + 1;
  }

  public static double log(double x) {
    return NativeMath.log(x);
  }

  public static double log10(double x) {
    return NativeMath.log(x) * NativeMath.LOG10E;
  }

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

  public static double max(double x, double y) {
    return NativeMath.max(x, y);
  }

  public static float max(float x, float y) {
    return (float) NativeMath.max(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 NativeMath.min(x, y);
  }

  public static float min(float x, float y) {
    return (float) NativeMath.min(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 int multiplyExact(int x, int y) {
    long r = (long) x * (long) y;
    int ir = (int) r;
    throwOverflowIf(ir != r);
    return ir;
  }

  public static long multiplyExact(long x, long y) {
    long r = x * y;
    throwOverflowIf((x == Long.MIN_VALUE && y == -1) || (y != 0 && (r / y != x)));
    return r;
  }

  public static int negateExact(int x) {
    throwOverflowIf(x == Integer.MIN_VALUE);
    return -x;
  }

  public static long negateExact(long x) {
    throwOverflowIf(x == Long.MIN_VALUE);
    return -x;
  }

  public static double pow(double x, double exp) {
    return NativeMath.pow(x, exp);
  }

  public static double random() {
    return NativeMath.random();
  }

  public static double rint(double x) {
    double mod2 = x % 2;
    if ((mod2 == -1.5) || (mod2 == 0.5)) {
      return NativeMath.floor(x);
    } else {
      return NativeMath.round(x);
    }
  }

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

  public static int round(float x) {
    double roundedValue = NativeMath.round(x);
    return unsafeCastToInt(roundedValue);
  }

  private static native int unsafeCastToInt(double d) /*-{
    return d;
  }-*/;

  public static int subtractExact(int x, int y) {
    int r = x - y;
    // "Hacker's Delight" Overflow if the arguments have different signs and
    // the sign of the result is different than the sign of x
    throwOverflowIf(((x ^ y) & (x ^ r)) < 0);
    return r;
  }

  public static long subtractExact(long x, long y) {
    long r = x - y;
    // "Hacker's Delight" Overflow if the arguments have different signs and
    // the sign of the result is different than the sign of x
    throwOverflowIf(((x ^ y) & (x ^ r)) < 0);
    return r;
  }

  public static double scalb(double d, int scaleFactor) {
    if (scaleFactor >= 31 || scaleFactor <= -31) {
      return d * Math.pow(2, scaleFactor);
    } else 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) {
    return (float) scalb((double) f, 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) {
    return (float) signum((double) f);
  }

  public static double sin(double x) {
    return NativeMath.sin(x);
  }

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

  public static double sqrt(double x) {
    return NativeMath.sqrt(x);
  }

  public static double tan(double x) {
    return NativeMath.tan(x);
  }

  public static double tanh(double x) {
    if (Double.isInfinite(x)) {
      return signum(x);
    }

    double e2x = Math.exp(2.0 * x);
    return (e2x - 1) / (e2x + 1);
  }

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

  public static int toIntExact(long x) {
    int ix = (int) x;
    throwOverflowIf(ix != x);
    return ix;
  }

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

  private static void throwDivByZeroIf(boolean condition) {
    if (condition) {
      throw new ArithmeticException("div by zero");
    }
  }

  private static void throwOverflowIf(boolean condition) {
    if (condition) {
      throw new ArithmeticException("overflow");
    }
  }

  @JsType(isNative = true, name = "Math", namespace = JsPackage.GLOBAL)
  private static class NativeMath {
    public static double LOG10E;
    public static native double acos(double x);
    public static native double asin(double x);
    public static native double atan(double x);
    public static native double atan2(double y, double x);
    public static native double ceil(double x);
    public static native double cos(double x);
    public static native double exp(double x);
    public static native double floor(double x);
    public static native double log(double x);
    public static native double max(double x, double y);
    public static native double min(double x, double y);
    public static native double pow(double x, double exp);
    public static native double random();
    public static native double round(double x);
    public static native double sin(double x);
    public static native double sqrt(double x);
    public static native double tan(double x);
  }
}
