/*
 * 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.usermodel;
import java.text.FieldPosition;
import java.text.Format;
import java.text.ParsePosition;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.poi.ss.format.SimpleFraction;
import org.apache.poi.ss.formula.eval.NotImplementedException;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;

/**
 * <p>Format class that handles Excel style fractions, such as "# #/#" and "#/###"</p>
 * 
 * <p>As of this writing, this is still not 100% accurate, but it does a reasonable job
 * of trying to mimic Excel's fraction calculations.  It does not currently
 * maintain Excel's spacing.</p>
 * 
 * <p>This class relies on a method lifted nearly verbatim from org.apache.math.fraction.
 *  If further uses for Commons Math are found, we will consider adding it as a dependency.
 *  For now, we have in-lined the one method to keep things simple.</p>
 */

@SuppressWarnings("serial")
public class FractionFormat extends Format {
    private static final POILogger LOGGER = POILogFactory.getLogger(FractionFormat.class); 
    private static final Pattern DENOM_FORMAT_PATTERN = Pattern.compile("(?:(#+)|(\\d+))");

    //this was chosen to match the earlier limitation of max denom power
    //it can be expanded to get closer to Excel's calculations
    //with custom formats # #/#########
    //but as of this writing, the numerators and denominators
    //with formats of that nature on very small values were quite
    //far from Excel's calculations
    private static final int MAX_DENOM_POW = 4;

    //there are two options:
    //a) an exact denominator is specified in the formatString
    //b) the maximum denominator can be calculated from the formatString
    private final int exactDenom;
    private final int maxDenom;

    private final String wholePartFormatString;
    /**
     * Single parameter ctor
     * @param denomFormatString The format string for the denominator
     */
    public FractionFormat(String wholePartFormatString, String denomFormatString) {
        this.wholePartFormatString = wholePartFormatString;
        //init exactDenom and maxDenom
        Matcher m = DENOM_FORMAT_PATTERN.matcher(denomFormatString);
        int tmpExact = -1;
        int tmpMax = -1;
        if (m.find()){
            if (m.group(2) != null){
                try{
                    tmpExact = Integer.parseInt(m.group(2));
                    //if the denom is 0, fall back to the default: tmpExact=100
                    
                    if (tmpExact == 0){
                        tmpExact = -1;
                    }
                } catch (NumberFormatException e){
                    //should never happen
                }
            } else if (m.group(1) != null) {
                int len = m.group(1).length();
                len = len > MAX_DENOM_POW ? MAX_DENOM_POW : len;
                tmpMax = (int)Math.pow(10, len);
            } else {
                tmpExact = 100;
            }
        }
        if (tmpExact <= 0 && tmpMax <= 0){
            //use 100 as the default denom if something went horribly wrong
            tmpExact = 100;
        }
        exactDenom = tmpExact;
        maxDenom = tmpMax;
    }

    public String format(Number num) {

        final double doubleValue = num.doubleValue();
        
        final boolean isNeg = (doubleValue < 0.0f) ? true : false;
        final double absDoubleValue = Math.abs(doubleValue);
        
        final double wholePart = Math.floor(absDoubleValue);
        final double decPart = absDoubleValue - wholePart;
        if (wholePart + decPart == 0) {
            return "0";
        }
        
        // if the absolute value is smaller than 1 over the exact or maxDenom
        // you can stop here and return "0"
        // reciprocal is result of an int devision ... and so it's nearly always 0
        // double reciprocal = 1/Math.max(exactDenom,  maxDenom);
        // if (absDoubleValue < reciprocal) {
        //    return "0";
        // }
        
        //this is necessary to prevent overflow in the maxDenom calculation
        if (Double.compare(decPart, 0) == 0){
            
            StringBuilder sb = new StringBuilder();
            if (isNeg){
                sb.append("-");
            }
            sb.append((int)wholePart);
            return sb.toString();
        }
        
        SimpleFraction fract = null;
        try{
            //this should be the case because of the constructor
            if (exactDenom > 0){
                fract = SimpleFraction.buildFractionExactDenominator(decPart, exactDenom);
            } else {
                fract = SimpleFraction.buildFractionMaxDenominator(decPart, maxDenom);
            }
        } catch (RuntimeException e){
            LOGGER.log(POILogger.WARN, "Can't format fraction", e);
            return Double.toString(doubleValue);
        }

        StringBuilder sb = new StringBuilder();
        
        //now format the results
        if (isNeg){
            sb.append("-");
        }
        
        //if whole part has to go into the numerator
        if ("".equals(wholePartFormatString)){
            int trueNum = (fract.getDenominator()*(int)wholePart)+fract.getNumerator();
            sb.append(trueNum).append("/").append(fract.getDenominator());
            return sb.toString();
        }
        
        
        //short circuit if fraction is 0 or 1
        if (fract.getNumerator() == 0){
            sb.append(Integer.toString((int)wholePart));
            return sb.toString();
        } else if (fract.getNumerator() == fract.getDenominator()){
            sb.append(Integer.toString((int)wholePart+1));
            return sb.toString();
        }
       //as mentioned above, this ignores the exact space formatting in Excel
        if (wholePart > 0){
            sb.append(Integer.toString((int)wholePart)).append(" ");
        }
        sb.append(fract.getNumerator()).append("/").append(fract.getDenominator());
        return sb.toString();
    }

    public StringBuffer format(Object obj, StringBuffer toAppendTo, FieldPosition pos) {
        return toAppendTo.append(format((Number)obj));
    }

    public Object parseObject(String source, ParsePosition pos) {
        throw new NotImplementedException("Reverse parsing not supported");
    }
   
}
