package org.avmdti.josast.util;

/**
 * utility class for mathematic function.
 *
 * @author Xtophe
 * @version 1.0
 */
public final class MathTools {
    //~ Constructors ------------------------------------------------------

    /**
     * Creates a new MathTools object.
     */
    private MathTools() {
    }

    //~ Methods -----------------------------------------------------------

    /**
     * set an agle between O and 2 PI.
     *
     * @param x angle in radian
     *
     * @return angle in radian between 0 and 2 PI
     */
    public static double rev(final double x) {
        return x - (Math.floor(x / (2 * Math.PI)) * 2 * Math.PI);
    }

    /**
     * Method absolute value of input value.
     *
     * @param value input value
     *
     * @return double absolute value of input value.
     */
    public static double abs(final double value) {
        if (value < 0) {
            return (-value);
        } else {
            return value;
        }
    }

    /**
     * double remainder function Equivalent to the C fmod function . The
     * fmod() ) function return the value x-iy, for some integer i such
     * that, if y is non-zero, the result has the same sign as x and
     * magnitude less than the magnitude of y.    TODO : unit test
     *
     * @param x input value
     * @param y input value
     *
     * @return the double remainder of x/ y.
     */
    public static double fmod(final double x, final double y) {
        double tmp = x / y;
        double rval = x - (Math.rint(tmp) * y);

        return (rval);
    }

    /**
     * cacul the remainder of x/ 2 PI.
     *
     * @param x angle in radian
     *
     * @return remainder of x/ 2 PI
     */
    public static double fmod2p(final double x) {
        double x2 = modulus(x, 2.0 * Math.PI);

        return x2;
    }

    /**
     * DOCUMENT ME!
     *
     * @param x DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static double cube(final double x) {
        double x2 = Math.pow(x, 3.0);

        return x2;
    }

    /**
     * DOCUMENT ME!
     *
     * @param x DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static double sqr(double x) {
        x *= x;

        return x;
    }

    /**
     * DOCUMENT ME!
     *
     * @param arg1 DOCUMENT ME!
     * @param arg2 DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static double modulus(final double arg1, final double arg2) {
        double modu;
        modu = arg1 - (Math.floor(arg1 / arg2) * arg2);

        if (modu >= 0) {
            return modu;
        } else {
            modu += arg2;

            return modu;
        }
    }

    /**
     * DOCUMENT ME!
     *
     * @param x DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static double radians(double x) {
        x *= (Math.PI / 180.0);

        return x;
    }

    /**
     * DOCUMENT ME!
     *
     * @param v DOCUMENT ME!
     */
    public static void Magnitude(VectorFourDim v) {
        v.v[3] = Math.sqrt(sqr(v.v[0]) + sqr(v.v[1]) + sqr(v.v[2]));
    }

    /**
     * DOCUMENT ME!
     *
     * @param altitude DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public static double arc(double altitude) {
        double altitude2 = altitude * altitude;
        double t = altitude + 6367.4000;

        return (Math.sqrt((altitude2 - ((altitude2 * altitude2) / (t * t)))));
    }
}
