/* ====================================================================
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You 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 org.apache.poi.ss.formula.functions;

import org.apache.poi.ss.util.NumberToTextConverter;

/**
 * @author Amol S. Deshmukh &lt; amolweb at ya hoo dot com &gt;
 * This class is an extension to the standard math library
 * provided by java.lang.Math class. It follows the Math class
 * in that it has a private constructor and all static methods.
 */
final class MathX {

    private MathX() {
        // no instances of this class
    }


    /**
     * Returns a value rounded to p digits after decimal.
     * If p is negative, then the number is rounded to
     * places to the left of the decimal point. eg.
     * 10.23 rounded to -1 will give: 10. If p is zero,
     * the returned value is rounded to the nearest integral
     * value.
     * <p>If n is negative, the resulting value is obtained
     * as the round value of absolute value of n multiplied
     * by the sign value of n (@see MathX.sign(double d)).
     * Thus, -0.6666666 rounded to p=0 will give -1 not 0.
     * <p>If n is NaN, returned value is NaN.
     * @param n
     * @param p
     */
    public static double round(double n, int p) {
        return round(n, p, java.math.RoundingMode.HALF_UP);
    }

    public static double round(double n, double p) {
        return round(n, (int)p);
    }



    /**
     * Returns a value rounded-up to p digits after decimal.
     * If p is negative, then the number is rounded to
     * places to the left of the decimal point. eg.
     * 10.23 rounded to -1 will give: 20. If p is zero,
     * the returned value is rounded to the nearest integral
     * value.
     * <p>If n is negative, the resulting value is obtained
     * as the round-up value of absolute value of n multiplied
     * by the sign value of n (@see MathX.sign(double d)).
     * Thus, -0.2 rounded-up to p=0 will give -1 not 0.
     * <p>If n is NaN, returned value is NaN.
     * @param n
     * @param p
     */
    public static double roundUp(double n, int p) {
        return round(n, p, java.math.RoundingMode.UP);
    }

    public static double roundUp(double n, double p) {
        return roundUp(n, (int)p);
    }


    /**
     * Returns a value rounded to p digits after decimal.
     * If p is negative, then the number is rounded to
     * places to the left of the decimal point. eg.
     * 10.23 rounded to -1 will give: 10. If p is zero,
     * the returned value is rounded to the nearest integral
     * value.
     * <p>If n is negative, the resulting value is obtained
     * as the round-up value of absolute value of n multiplied
     * by the sign value of n (@see MathX.sign(double d)).
     * Thus, -0.8 rounded-down to p=0 will give 0 not -1.
     * <p>If n is NaN, returned value is NaN.
     * @param n
     * @param p
     */
    public static double roundDown(double n, int p) {
        return round(n, p, java.math.RoundingMode.DOWN);
    }

    public static double roundDown(double n, double p) {
        return roundDown(n, (int)p);
    }

    private static double round(double n, int p, java.math.RoundingMode rounding) {
        if (Double.isNaN(n) || Double.isInfinite(n)) {
            return Double.NaN;
        }
        else {
            final String excelNumber = NumberToTextConverter.toText(n);
            return new java.math.BigDecimal(excelNumber).setScale(p, rounding).doubleValue();
        }
    }


    /**
     * If d < 0, returns short -1
     * <br>
     * If d > 0, returns short 1
     * <br>
     * If d == 0, returns short 0
     * <p> If d is NaN, then 1 will be returned. It is the responsibility
     * of caller to check for d isNaN if some other value is desired.
     * @param d
     */
    public static short sign(double d) {
        return (short) ((d == 0)
                ? 0
                : (d < 0)
                        ? -1
                        : 1);
    }

    /**
     * average of all values
     * @param values
     */
    public static double average(double[] values) {
        double ave = 0;
        double sum = 0;
        for (double value : values) {
            sum += value;
        }
        ave = sum / values.length;
        return ave;
    }

    /**
     * sum of all values
     * @param values
     */
    public static double sum(double[] values) {
        double sum = 0;
        for (double value : values) {
            sum += value;
        }
        return sum;
    }

    /**
     * sum of squares of all values
     * @param values
     */
    public static double sumsq(double[] values) {
        double sumsq = 0;
        for (double value : values) {
            sumsq += value * value;
        }
        return sumsq;
    }


    /**
     * product of all values
     * @param values
     */
    public static double product(double[] values) {
        double product = 0;
        if (values!=null && values.length > 0) {
            product = 1;
            for (double value : values) {
                product *= value;
            }
        }
        return product;
    }

    /**
     * min of all values. If supplied array is zero length,
     * Double.POSITIVE_INFINITY is returned.
     * @param values
     */
    public static double min(double[] values) {
        double min = Double.POSITIVE_INFINITY;
        for (double value : values) {
            min = Math.min(min, value);
        }
        return min;
    }

    /**
     * min of all values. If supplied array is zero length,
     * Double.NEGATIVE_INFINITY is returned.
     * @param values
     */
    public static double max(double[] values) {
        double max = Double.NEGATIVE_INFINITY;
        for (double value : values) {
            max = Math.max(max, value);
        }
        return max;
    }

    /**
     * Note: this function is different from java.lang.Math.floor(..).
     * <p>
     * When n and s are "valid" arguments, the returned value is: Math.floor(n/s) * s;
     * <br>
     * n and s are invalid if any of following conditions are true:
     * <ul>
     * <li>s is zero</li>
     * <li>n is negative and s is positive</li>
     * <li>n is positive and s is negative</li>
     * </ul>
     * In all such cases, Double.NaN is returned.
     * @param n
     * @param s
     */
    public static double floor(double n, double s) {
        if (s==0 && n!=0) {
            return Double.NaN;
        } else {
            return (n==0 || s==0) ? 0 : Math.floor(n/s) * s;
        }
    }

    /**
     * Note: this function is different from java.lang.Math.ceil(..).
     * <p>
     * When n and s are "valid" arguments, the returned value is: Math.ceiling(n/s) * s;
     * <br>
     * n and s are invalid if any of following conditions are true:
     * <ul>
     * <li>s is zero</li>
     * <li>n is negative and s is positive</li>
     * <li>n is positive and s is negative</li>
     * </ul>
     * In all such cases, Double.NaN is returned.
     * @param n
     * @param s
     */
    public static double ceiling(double n, double s) {
        if (n>0 && s<0) {
            return Double.NaN;
        } else {
            return (n == 0 || s == 0) ? 0 : Math.ceil(n/s) * s;
        }
    }

    /**
     * <br> for all n >= 1; factorial n = n * (n-1) * (n-2) * ... * 1
     * <br> else if n == 0; factorial n = 1
     * <br> else if n < 0; factorial n = Double.NaN
     * <br> Loss of precision can occur if n is large enough.
     * If n is large so that the resulting value would be greater
     * than Double.MAX_VALUE; Double.POSITIVE_INFINITY is returned.
     * If n < 0, Double.NaN is returned.
     * @param n
     */
    public static double factorial(int n) {
        double d = 1;

        if (n >= 0) {
            if (n <= 170) {
                for (int i=1; i<=n; i++) {
                    d *= i;
                }
            }
            else {
                d = Double.POSITIVE_INFINITY;
            }
        }
        else {
            d = Double.NaN;
        }
        return d;
    }

    public static double factorial(double d) {
        return factorial((int)d);
    }


    /**
     * returns the remainder resulting from operation:
     * n / d.
     * <br> The result has the sign of the divisor.
     * <br> Examples:
     * <ul>
     * <li>mod(3.4, 2) = 1.4</li>
     * <li>mod(-3.4, 2) = 0.6</li>
     * <li>mod(-3.4, -2) = -1.4</li>
     * <li>mod(3.4, -2) = -0.6</li>
     * </ul>
     * If d == 0, result is NaN
     * @param n
     * @param d
     */
    public static double mod(double n, double d) {
        if (d == 0) {
            return Double.NaN;
        }
        else if (sign(n) == sign(d)) {
            return n % d;
        }
        else {
            return ((n % d) + d) % d;
        }
    }

    /**
     * inverse hyperbolic cosine
     * @param d
     */
    public static double acosh(double d) {
        return Math.log(Math.sqrt(Math.pow(d, 2) - 1) + d);
    }

    /**
     * inverse hyperbolic sine
     * @param d
     */
    public static double asinh(double d) {
        return Math.log(Math.sqrt(d*d + 1) + d);
    }

    /**
     * inverse hyperbolic tangent
     * @param d
     */
    public static double atanh(double d) {
        return Math.log((1 + d)/(1 - d)) / 2;
    }

    /**
     * hyperbolic cosine
     * @param d
     */
    public static double cosh(double d) {
        double ePowX = Math.pow(Math.E, d);
        double ePowNegX = Math.pow(Math.E, -d);
        return (ePowX + ePowNegX) / 2;
    }

    /**
     * hyperbolic sine
     * @param d
     */
    public static double sinh(double d) {
        double ePowX = Math.pow(Math.E, d);
        double ePowNegX = Math.pow(Math.E, -d);
        return (ePowX - ePowNegX) / 2;
    }

    /**
     * hyperbolic tangent
     * @param d
     */
    public static double tanh(double d) {
        double ePowX = Math.pow(Math.E, d);
        double ePowNegX = Math.pow(Math.E, -d);
        return (ePowX - ePowNegX) / (ePowX + ePowNegX);
    }


    /**
     * returns the total number of combinations possible when
     * k items are chosen out of total of n items. If the number
     * is too large, loss of precision may occur (since returned
     * value is double). If the returned value is larger than
     * Double.MAX_VALUE, Double.POSITIVE_INFINITY is returned.
     * If either of the parameters is negative, Double.NaN is returned.
     * @param n
     * @param k
     */
    public static double nChooseK(int n, int k) {
        double d = 1;
        if (n<0 || k<0 || n<k) {
            d= Double.NaN;
        }
        else {
            int minnk = Math.min(n-k, k);
            int maxnk = Math.max(n-k, k);
            for (int i=maxnk; i<n; i++) {
                d *= i+1;
            }
            d /= factorial(minnk);
        }

        return d;
    }
}
