// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html#License
/*
*******************************************************************************
*   Copyright (C) 2007-2016, International Business Machines
*   Corporation and others.  All Rights Reserved.
*******************************************************************************
*/
package com.ibm.icu.impl;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.math.BigInteger;
import java.text.FieldPosition;
import java.text.ParsePosition;
import java.util.Arrays;
import java.util.MissingResourceException;

import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.math.BigDecimal;
import com.ibm.icu.text.NumberFormat;
import com.ibm.icu.util.ULocale;
import com.ibm.icu.util.UResourceBundle;

/*
 * NumberFormat implementation dedicated/optimized for DateFormat,
 * used by SimpleDateFormat implementation.
 * This class is not thread-safe.
 */
public final class DateNumberFormat extends NumberFormat {

    private static final long serialVersionUID = -6315692826916346953L;

    private char[] digits;
    private char zeroDigit; // For backwards compatibility
    private char minusSign;
    private boolean positiveOnly = false;

    private static final int DECIMAL_BUF_SIZE = 20; // 20 digits is good enough to store Long.MAX_VALUE
    private transient char[] decimalBuf = new char[DECIMAL_BUF_SIZE];

    private static SimpleCache<ULocale, char[]> CACHE = new SimpleCache<ULocale, char[]>();

    private int maxIntDigits;
    private int minIntDigits;

    public DateNumberFormat(ULocale loc, String digitString, String nsName) {
        if (digitString.length() > 10) {
            throw new UnsupportedOperationException("DateNumberFormat does not support digits out of BMP.");
        }
        initialize(loc,digitString,nsName);
    }

    public DateNumberFormat(ULocale loc, char zeroDigit, String nsName) {
        StringBuffer buf = new StringBuffer();
        for ( int i = 0 ; i < 10 ; i++ ) {
            buf.append((char)(zeroDigit+i));
        }
        initialize(loc,buf.toString(),nsName);
    }

    private void initialize(ULocale loc,String digitString,String nsName) {
        char[] elems = CACHE.get(loc);
        if (elems == null) {
            // Missed cache
            String minusString;
            ICUResourceBundle rb = (ICUResourceBundle)UResourceBundle.getBundleInstance(ICUData.ICU_BASE_NAME, loc);
            try {
                minusString = rb.getStringWithFallback("NumberElements/"+nsName+"/symbols/minusSign");
            } catch (MissingResourceException ex) {
                if ( !nsName.equals("latn") ) {
                    try {
                       minusString = rb.getStringWithFallback("NumberElements/latn/symbols/minusSign");
                    } catch (MissingResourceException ex1) {
                        minusString = "-";
                    }
                } else {
                    minusString = "-";
                }
            }
            elems = new char[11];
            for ( int i = 0 ; i < 10 ; i++ ) {
                 elems[i] = digitString.charAt(i);
            }
            elems[10] = minusString.charAt(0);
            CACHE.put(loc, elems);
        }

        digits = new char[10];
        System.arraycopy(elems, 0, digits, 0, 10);
        zeroDigit = digits[0];

        minusSign = elems[10];
    }

    @Override
    public void setMaximumIntegerDigits(int newValue) {
        maxIntDigits = newValue;
    }

    @Override
    public int getMaximumIntegerDigits() {
        return maxIntDigits;
    }

    @Override
    public void setMinimumIntegerDigits(int newValue) {
        minIntDigits = newValue;
    }

    @Override
    public int getMinimumIntegerDigits() {
        return minIntDigits;
    }

    /* For supporting SimpleDateFormat.parseInt */
    public void setParsePositiveOnly(boolean isPositiveOnly) {
        positiveOnly = isPositiveOnly;
    }

    public char getZeroDigit() {
        return zeroDigit;
    }

    public void setZeroDigit(char zero) {
        zeroDigit = zero;
        if (digits == null) {
            digits = new char[10];
        }
        digits[0] = zero;
        for ( int i = 1 ; i < 10 ; i++ ) {
            digits[i] = (char)(zero+i);
        }
    }

    public char[] getDigits() {
        return digits.clone();
    }

    @Override
    public StringBuffer format(double number, StringBuffer toAppendTo,
            FieldPosition pos) {
        throw new UnsupportedOperationException("StringBuffer format(double, StringBuffer, FieldPostion) is not implemented");
    }

    @Override
    public StringBuffer format(long numberL, StringBuffer toAppendTo,
            FieldPosition pos) {

        if (numberL < 0) {
            // negative
            toAppendTo.append(minusSign);
            numberL = -numberL;
        }

        // Note: NumberFormat used by DateFormat only uses int numbers.
        // Remainder operation on 32bit platform using long is significantly slower
        // than int.  So, this method casts long number into int.
        int number = (int)numberL;

        int limit = decimalBuf.length < maxIntDigits ? decimalBuf.length : maxIntDigits;
        int index = limit - 1;
        while (true) {
            decimalBuf[index] = digits[(number % 10)];
            number /= 10;
            if (index == 0 || number == 0) {
                break;
            }
            index--;
        }
        int padding = minIntDigits - (limit - index);
        for (; padding > 0; padding--) {
            decimalBuf[--index] = digits[0];
        }
        int length = limit - index;
        toAppendTo.append(decimalBuf, index, length);
        pos.setBeginIndex(0);
        if (pos.getField() == NumberFormat.INTEGER_FIELD) {
            pos.setEndIndex(length);
        } else {
            pos.setEndIndex(0);
        }
        return toAppendTo;
    }

    @Override
    public StringBuffer format(BigInteger number, StringBuffer toAppendTo,
            FieldPosition pos) {
        throw new UnsupportedOperationException("StringBuffer format(BigInteger, StringBuffer, FieldPostion) is not implemented");
    }

    @Override
    public StringBuffer format(java.math.BigDecimal number, StringBuffer toAppendTo,
            FieldPosition pos) {
        throw new UnsupportedOperationException("StringBuffer format(BigDecimal, StringBuffer, FieldPostion) is not implemented");
    }

    @Override
    public StringBuffer format(BigDecimal number,
            StringBuffer toAppendTo, FieldPosition pos) {
        throw new UnsupportedOperationException("StringBuffer format(BigDecimal, StringBuffer, FieldPostion) is not implemented");
    }

    /*
     * Note: This method only parse integer numbers which can be represented by long
     */
    private static final long PARSE_THRESHOLD = 922337203685477579L; // (Long.MAX_VALUE / 10) - 1

    @Override
    public Number parse(String text, ParsePosition parsePosition) {
        long num = 0;
        boolean sawNumber = false;
        boolean negative = false;
        int base = parsePosition.getIndex();
        int offset = 0;
        for (; base + offset < text.length(); offset++) {
            char ch = text.charAt(base + offset);
            if (offset == 0 && ch == minusSign) {
                if (positiveOnly) {
                    break;
                }
                negative = true;
            } else {
                int digit = ch - digits[0];
                if (digit < 0 || 9 < digit) {
                    digit = UCharacter.digit(ch);
                }
                if (digit < 0 || 9 < digit) {
                    for ( digit = 0 ; digit < 10 ; digit++ ) {
                        if ( ch == digits[digit]) {
                            break;
                        }
                    }
                }
                if (0 <= digit && digit <= 9 && num < PARSE_THRESHOLD) {
                    sawNumber = true;
                    num = num * 10 + digit;
                } else {
                    break;
                }
            }
        }
        Number result = null;
        if (sawNumber) {
            num = negative ? num * (-1) : num;
            result = Long.valueOf(num);
            parsePosition.setIndex(base + offset);
        }
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null || !super.equals(obj) || !(obj instanceof DateNumberFormat)) {
            return false;
        }
        DateNumberFormat other = (DateNumberFormat)obj;
        return (this.maxIntDigits == other.maxIntDigits
                && this.minIntDigits == other.minIntDigits
                && this.minusSign == other.minusSign
                && this.positiveOnly == other.positiveOnly
                && Arrays.equals(this.digits, other.digits));
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException {
        stream.defaultReadObject();
        if (digits == null) {
            setZeroDigit(zeroDigit);
        }
        // re-allocate the work buffer
        decimalBuf = new char[DECIMAL_BUF_SIZE];
    }

    @Override
    public Object clone() {
        DateNumberFormat dnfmt = (DateNumberFormat)super.clone();
        dnfmt.digits = this.digits.clone();
        dnfmt.decimalBuf = new char[DECIMAL_BUF_SIZE];
        return dnfmt;
    }
}

//eof
