/* ====================================================================
   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.format;

public class SimpleFraction {


    /** The denominator. */
    private final int denominator;

    /** The numerator. */
    private final int numerator;
    /**
     * Create a fraction given a double value and a denominator.
     *
     * @param val double value of fraction
     * @param exactDenom the exact denominator
     * @return a SimpleFraction with the given values set.
     */
    public static SimpleFraction buildFractionExactDenominator(double val, int exactDenom){
        int num =  (int)Math.round(val*exactDenom);
        return new SimpleFraction(num,exactDenom);
    }

    /**
     * Create a fraction given the double value and either the maximum error
     * allowed or the maximum number of denominator digits.
     *
     * @param value the double value to convert to a fraction.
     * @param maxDenominator maximum denominator value allowed.
     *
     * @throws RuntimeException if the continued fraction failed to
     *      converge.
     * @throws IllegalArgumentException if value &gt; Integer.MAX_VALUE
     */
    public static SimpleFraction buildFractionMaxDenominator(double value, int maxDenominator){
        return buildFractionMaxDenominator(value, 0, maxDenominator, 100);
    }
    /**
     * Create a fraction given the double value and either the maximum error
     * allowed or the maximum number of denominator digits.
     * <p>
     * References:
     * <ul>
     * <li><a href="http://mathworld.wolfram.com/ContinuedFraction.html">
     * Continued Fraction</a> equations (11) and (22)-(26)</li>
     * </ul>
     * </p>
     *
     *  Based on org.apache.commons.math.fraction.Fraction from Apache Commons-Math.
     *  YK: The only reason of having this class is to avoid dependency on the Commons-Math jar.
     *
     * @param value the double value to convert to a fraction.
     * @param epsilon maximum error allowed.  The resulting fraction is within
     *        <code>epsilon</code> of <code>value</code>, in absolute terms.
     * @param maxDenominator maximum denominator value allowed.
     * @param maxIterations maximum number of convergents
     * @throws RuntimeException if the continued fraction failed to
     *         converge.
     * @throws IllegalArgumentException if value > Integer.MAX_VALUE
     */
    private static SimpleFraction buildFractionMaxDenominator(double value, double epsilon, int maxDenominator, int maxIterations)
    {
        long overflow = Integer.MAX_VALUE;
        double r0 = value;
        long a0 = (long)Math.floor(r0);
        if (a0 > overflow) {
            throw new IllegalArgumentException("Overflow trying to convert "+value+" to fraction ("+a0+"/"+1l+")");
        }

        // check for (almost) integer arguments, which should not go
        // to iterations.
        if (Math.abs(a0 - value) < epsilon) {
            return new SimpleFraction((int)a0, 1);
        }

        long p0 = 1;
        long q0 = 0;
        long p1 = a0;
        long q1 = 1;

        long p2;
        long q2;

        int n = 0;
        boolean stop = false;
        do {
            ++n;
            double r1 = 1.0 / (r0 - a0);
            long a1 = (long)Math.floor(r1);
            p2 = (a1 * p1) + p0;
            q2 = (a1 * q1) + q0;
            //MATH-996/POI-55419
            if (epsilon == 0.0f && maxDenominator > 0 && Math.abs(q2) > maxDenominator &&
                    Math.abs(q1) < maxDenominator){

                return new SimpleFraction((int)p1, (int)q1);
            }
            if ((p2 > overflow) || (q2 > overflow)) {
                throw new RuntimeException("Overflow trying to convert "+value+" to fraction ("+p2+"/"+q2+")");
            }

            double convergent = (double)p2 / (double)q2;
            if (n < maxIterations && Math.abs(convergent - value) > epsilon && q2 < maxDenominator) {
                p0 = p1;
                p1 = p2;
                q0 = q1;
                q1 = q2;
                a0 = a1;
                r0 = r1;
            } else {
                stop = true;
            }
        } while (!stop);

        if (n >= maxIterations) {
            throw new RuntimeException("Unable to convert "+value+" to fraction after "+maxIterations+" iterations");
        }

        if (q2 < maxDenominator) {
            return new SimpleFraction((int) p2, (int)q2);
        } else {
            return new SimpleFraction((int)p1, (int)q1);
        }

    }

    /**
     * Create a fraction given a numerator and denominator.
     * @param numerator
     * @param denominator maxDenominator The maximum allowed value for denominator
     */
    public SimpleFraction(int numerator, int denominator)
    {
        this.numerator = numerator;
        this.denominator = denominator;
    }

    /**
     * Access the denominator.
     * @return the denominator.
     */
    public int getDenominator() {
        return denominator;
    }

    /**
     * Access the numerator.
     * @return the numerator.
     */
    public int getNumerator() {
        return numerator;
    }

}

