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

import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.regex.Matcher;

import org.apache.poi.ss.format.CellFormatPart.PartHandler;
import org.apache.poi.ss.format.CellNumberFormatter.Special;
import org.apache.poi.util.Internal;

/**
 * Internal helper class for CellNumberFormatter
 */
@Internal
public class CellNumberPartHandler implements PartHandler {
    private char insertSignForExponent;
    private double scale = 1;
    private Special decimalPoint;
    private Special slash;
    private Special exponent;
    private Special numerator;
    private final List<Special> specials = new LinkedList<Special>();
    private boolean improperFraction;

    public String handlePart(Matcher m, String part, CellFormatType type, StringBuffer descBuf) {
        int pos = descBuf.length();
        char firstCh = part.charAt(0);
        switch (firstCh) {
        case 'e':
        case 'E':
            // See comment in writeScientific -- exponent handling is complex.
            // (1) When parsing the format, remove the sign from after the 'e' and
            // put it before the first digit of the exponent.
            if (exponent == null && specials.size() > 0) {
                exponent = new Special('.', pos);
                specials.add(exponent);
                insertSignForExponent = part.charAt(1);
                return part.substring(0, 1);
            }
            break;

        case '0':
        case '?':
        case '#':
            if (insertSignForExponent != '\0') {
                specials.add(new Special(insertSignForExponent, pos));
                descBuf.append(insertSignForExponent);
                insertSignForExponent = '\0';
                pos++;
            }
            for (int i = 0; i < part.length(); i++) {
                char ch = part.charAt(i);
                specials.add(new Special(ch, pos + i));
            }
            break;

        case '.':
            if (decimalPoint == null && specials.size() > 0) {
                decimalPoint = new Special('.', pos);
                specials.add(decimalPoint);
            }
            break;

        case '/':
            //!! This assumes there is a numerator and a denominator, but these are actually optional
            if (slash == null && specials.size() > 0) {
                numerator = previousNumber();
                // If the first number in the whole format is the numerator, the
                // entire number should be printed as an improper fraction
                improperFraction |= (numerator == firstDigit(specials));
                slash = new Special('.', pos);
                specials.add(slash);
            }
            break;

        case '%':
            // don't need to remember because we don't need to do anything with these
            scale *= 100;
            break;

        default:
            return null;
        }
        return part;
    }

    public double getScale() {
        return scale;
    }

    public Special getDecimalPoint() {
        return decimalPoint;
    }

    public Special getSlash() {
        return slash;
    }

    public Special getExponent() {
        return exponent;
    }

    public Special getNumerator() {
        return numerator;
    }

    public List<Special> getSpecials() {
        return specials;
    }

    public boolean isImproperFraction() {
        return improperFraction;
    }

    private Special previousNumber() {
        ListIterator<Special> it = specials.listIterator(specials.size());
        while (it.hasPrevious()) {
            Special s = it.previous();
            if (isDigitFmt(s)) {
                Special last = s;
                while (it.hasPrevious()) {
                    s = it.previous();
                    // it has to be continuous digits
                    if (last.pos - s.pos > 1 || !isDigitFmt(s)) {
                        break;
                    }
                    last = s;
                }
                return last;
            }
        }
        return null;
    }
    
    private static boolean isDigitFmt(Special s) {
        return s.ch == '0' || s.ch == '?' || s.ch == '#';
    }

    private static Special firstDigit(List<Special> specials) {
        for (Special s : specials) {
            if (isDigitFmt(s)) {
                return s;
            }
        }
        return null;
    }
}
