/*
 * reserved comment block
 * DO NOT REMOVE OR ALTER!
 */
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 *
 * Licensed 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.
 */
/*
 * $Id: NodeCounter.java,v 1.2.4.1 2005/09/12 11:52:36 pvedula Exp $
 */

package com.sun.org.apache.xalan.internal.xsltc.dom;

import java.util.Vector;

import com.sun.org.apache.xalan.internal.xsltc.DOM;
import com.sun.org.apache.xalan.internal.xsltc.Translet;
import com.sun.org.apache.xml.internal.dtm.DTM;
import com.sun.org.apache.xml.internal.dtm.DTMAxisIterator;

/**
 * @author Jacek Ambroziak
 * @author Santiago Pericas-Geertsen
 * @author Morten Jorgensen
 */
public abstract class NodeCounter {
    public static final int END = DTM.NULL;

    protected int _node = END;
    protected int _nodeType = DOM.FIRST_TYPE - 1;
    protected double _value = Integer.MIN_VALUE;

    public final DOM          _document;
    public final DTMAxisIterator _iterator;
    public final Translet     _translet;

    protected String _format;
    protected String _lang;
    protected String _letterValue;
    protected String _groupSep;
    protected int    _groupSize;

    private boolean _separFirst = true;
    private boolean _separLast = false;
    private Vector _separToks = new Vector();
    private Vector _formatToks = new Vector();
    private int _nSepars  = 0;
    private int _nFormats = 0;

    private final static String[] Thousands =
        {"", "m", "mm", "mmm" };
    private final static String[] Hundreds =
    {"", "c", "cc", "ccc", "cd", "d", "dc", "dcc", "dccc", "cm"};
    private final static String[] Tens =
    {"", "x", "xx", "xxx", "xl", "l", "lx", "lxx", "lxxx", "xc"};
    private final static String[] Ones =
    {"", "i", "ii", "iii", "iv", "v", "vi", "vii", "viii", "ix"};

    private StringBuilder _tempBuffer = new StringBuilder();

    /**
     * Indicates if this instance of xsl:number has a from pattern.
     */
    protected boolean _hasFrom;

    protected NodeCounter(Translet translet,
              DOM document, DTMAxisIterator iterator) {
    _translet = translet;
    _document = document;
    _iterator = iterator;
    }

    protected NodeCounter(Translet translet,
              DOM document, DTMAxisIterator iterator, boolean hasFrom) {
        _translet = translet;
        _document = document;
        _iterator = iterator;
        _hasFrom = hasFrom;
    }

    /**
     * Set the start node for this counter. The same <tt>NodeCounter</tt>
     * object can be used multiple times by resetting the starting node.
     */
    abstract public NodeCounter setStartNode(int node);

    /**
     * If the user specified a value attribute, use this instead of
     * counting nodes.
     */
    public NodeCounter setValue(double value) {
    _value = value;
    return this;
    }

    /**
     * Sets formatting fields before calling formatNumbers().
     */
    protected void setFormatting(String format, String lang, String letterValue,
                 String groupSep, String groupSize) {
    _lang = lang;
    _groupSep = groupSep;
    _letterValue = letterValue;
    _groupSize = parseStringToAnInt(groupSize);
    setTokens(format);

 }

    /**
     * Effectively does the same thing as Integer.parseInt(String s) except
     * instead of throwing a NumberFormatException, it returns 0.  This method
     * is used instead of Integer.parseInt() since it does not incur the
     * overhead of throwing an Exception which is expensive.
     *
     * @param s  A String to be parsed into an int.
     * @return  Either an int represented by the incoming String s, or 0 if
     *          the parsing is not successful.
     */
    private int parseStringToAnInt(String s) {
        if (s == null)
            return 0;

        int result = 0;
        boolean negative = false;
        int radix = 10, i = 0, max = s.length();
        int limit, multmin, digit;

        if (max > 0) {
            if (s.charAt(0) == '-') {
                negative = true;
                limit = Integer.MIN_VALUE;
                i++;
            } else {
                limit = -Integer.MAX_VALUE;
            }
            multmin = limit / radix;
            if (i < max) {
                digit = Character.digit(s.charAt(i++), radix);
                if (digit < 0)
                    return 0;
                else
                    result = -digit;
            }
            while (i < max) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                digit = Character.digit(s.charAt(i++), radix);
                if (digit < 0)
                    return 0;
                if (result < multmin)
                    return 0;
                result *= radix;
                if (result < limit + digit)
                    return 0;
                result -= digit;
            }
        } else {
            return 0;
        }
        if (negative) {
            if (i > 1)
                return result;
            else /* Only got "-" */
                return 0;
        } else {
            return -result;
        }
    }

  // format == null assumed here
 private final void setTokens(final String format){
     if( (_format!=null) &&(format.equals(_format)) ){// has already been set
        return;
     }
     _format = format;
     // reset
     final int length = _format.length();
     boolean isFirst = true;
     _separFirst = true;
     _separLast = false;
     _nSepars  = 0;
     _nFormats = 0;
     _separToks.clear() ;
     _formatToks.clear();

         /*
          * Tokenize the format string into alphanumeric and non-alphanumeric
          * tokens as described in M. Kay page 241.
          */
         for (int j = 0, i = 0; i < length;) {
                 char c = format.charAt(i);
                 for (j = i; Character.isLetterOrDigit(c);) {
                     if (++i == length) break;
             c = format.charAt(i);
                 }
                 if (i > j) {
                     if (isFirst) {
                         _separToks.addElement(".");
                         isFirst = _separFirst = false;
                     }
                     _formatToks.addElement(format.substring(j, i));
                 }

                 if (i == length) break;

                 c = format.charAt(i);
                 for (j = i; !Character.isLetterOrDigit(c);) {
                     if (++i == length) break;
                     c = format.charAt(i);
                     isFirst = false;
                 }
                 if (i > j) {
                     _separToks.addElement(format.substring(j, i));
                 }
             }

         _nSepars = _separToks.size();
         _nFormats = _formatToks.size();
         if (_nSepars > _nFormats) _separLast = true;

         if (_separFirst) _nSepars--;
         if (_separLast) _nSepars--;
         if (_nSepars == 0) {
             _separToks.insertElementAt(".", 1);
             _nSepars++;
         }
         if (_separFirst) _nSepars ++;

 }
    /**
     * Sets formatting fields to their default values.
     */
    public NodeCounter setDefaultFormatting() {
    setFormatting("1", "en", "alphabetic", null, null);
    return this;
    }

    /**
     * Returns the position of <tt>node</tt> according to the level and
     * the from and count patterns.
     */
    abstract public String getCounter();

    /**
     * Returns the position of <tt>node</tt> according to the level and
     * the from and count patterns. This position is converted into a
     * string based on the arguments passed.
     */
    public String getCounter(String format, String lang, String letterValue,
                String groupSep, String groupSize) {
    setFormatting(format, lang, letterValue, groupSep, groupSize);
    return getCounter();
    }

    /**
     * Returns true if <tt>node</tt> matches the count pattern. By
     * default a node matches the count patterns if it is of the
     * same type as the starting node.
     */
    public boolean matchesCount(int node) {
    return _nodeType == _document.getExpandedTypeID(node);
    }

    /**
     * Returns true if <tt>node</tt> matches the from pattern. By default,
     * no node matches the from pattern.
     */
    public boolean matchesFrom(int node) {
    return false;
    }

    /**
     * Format a single value according to the format parameters.
     */
    protected String formatNumbers(int value) {
    return formatNumbers(new int[] { value });
    }

    /**
     * Format a sequence of values according to the format paramaters
     * set by calling setFormatting().
     */
    protected String formatNumbers(int[] values) {
    final int nValues = values.length;

    boolean isEmpty = true;
    for (int i = 0; i < nValues; i++)
        if (values[i] != Integer.MIN_VALUE)
        isEmpty = false;
    if (isEmpty) return("");

    // Format the output string using the values array and the fmt. tokens
    boolean isFirst = true;
    int t = 0, n = 0, s = 1;
  _tempBuffer.setLength(0);
    final StringBuilder buffer = _tempBuffer;

    // Append separation token before first digit/letter/numeral
    if (_separFirst) buffer.append((String)_separToks.elementAt(0));

    // Append next digit/letter/numeral and separation token
    while (n < nValues) {
        final int value = values[n];
        if (value != Integer.MIN_VALUE) {
        if (!isFirst) buffer.append((String) _separToks.elementAt(s++));
        formatValue(value, (String)_formatToks.elementAt(t++), buffer);
        if (t == _nFormats) t--;
        if (s >= _nSepars) s--;
        isFirst = false;
        }
        n++;
    }

    // Append separation token after last digit/letter/numeral
    if (_separLast) buffer.append((String)_separToks.lastElement());
    return buffer.toString();
    }

    /**
     * Format a single value based on the appropriate formatting token.
     * This method is based on saxon (Michael Kay) and only implements
     * lang="en".
     */
    private void formatValue(int value, String format, StringBuilder buffer) {
        char c = format.charAt(0);

        if (Character.isDigit(c)) {
            char zero = (char)(c - Character.getNumericValue(c));

            StringBuilder temp = buffer;
            if (_groupSize > 0) {
                temp = new StringBuilder();
            }
            String s = "";
            int n = value;
            while (n > 0) {
                s = (char) ((int) zero + (n % 10)) + s;
                n = n / 10;
            }

            for (int i = 0; i < format.length() - s.length(); i++) {
                temp.append(zero);
            }
            temp.append(s);

            if (_groupSize > 0) {
                for (int i = 0; i < temp.length(); i++) {
                    if (i != 0 && ((temp.length() - i) % _groupSize) == 0) {
                        buffer.append(_groupSep);
                    }
                    buffer.append(temp.charAt(i));
                }
            }
        }
    else if (c == 'i' && !_letterValue.equals("alphabetic")) {
            buffer.append(romanValue(value));
        }
    else if (c == 'I' && !_letterValue.equals("alphabetic")) {
            buffer.append(romanValue(value).toUpperCase());
        }
    else {
        int min = (int) c;
        int max = (int) c;

        // Special case for Greek alphabet
        if (c >= 0x3b1 && c <= 0x3c9) {
        max = 0x3c9;    // omega
        }
        else {
        // General case: search for end of group
        while (Character.isLetterOrDigit((char) (max + 1))) {
            max++;
        }
        }
            buffer.append(alphaValue(value, min, max));
        }
    }

    private String alphaValue(int value, int min, int max) {
        if (value <= 0) {
        return "" + value;
    }

        int range = max - min + 1;
        char last = (char)(((value-1) % range) + min);
        if (value > range) {
            return alphaValue((value-1) / range, min, max) + last;
        }
    else {
            return "" + last;
        }
    }

    private String romanValue(int n) {
        if (n <= 0 || n > 4000) {
        return "" + n;
    }
        return
        Thousands[n / 1000] +
        Hundreds[(n / 100) % 10] +
        Tens[(n/10) % 10] +
        Ones[n % 10];
    }

}
