/* AbstractNumberNode.java -- 
   Copyright (C) 2004 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */

package gnu.xml.transform;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.xml.namespace.QName;
import javax.xml.transform.TransformerException;
import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
import org.w3c.dom.Node;
import org.w3c.dom.Text;
import gnu.xml.xpath.Expr;

/**
 * A template node representing the XSL <code>number</code> instruction.
 *
 * @author <a href='mailto:dog@gnu.org'>Chris Burdess</a>
 */
abstract class AbstractNumberNode
  extends TemplateNode
{

  static final int ALPHABETIC = 0;
  static final int TRADITIONAL = 1;

  final TemplateNode format;
  final String lang;
  final int letterValue;
  final String groupingSeparator;
  final int groupingSize;

  AbstractNumberNode(TemplateNode format, String lang,
                     int letterValue, String groupingSeparator,
                     int groupingSize)
  {
    this.format = format;
    this.lang = lang;
    this.letterValue = letterValue;
    this.groupingSeparator = groupingSeparator;
    this.groupingSize = groupingSize;
  }

  void doApply(Stylesheet stylesheet, QName mode,
               Node context, int pos, int len,
               Node parent, Node nextSibling)
    throws TransformerException
  {
    Document doc = (parent instanceof Document) ? (Document) parent :
      parent.getOwnerDocument();
    DocumentFragment fragment = doc.createDocumentFragment();
    format.apply(stylesheet, mode, context, pos, len, fragment, null);
    String f = Expr._string(context, Collections.singleton(fragment));
    String value = format(f, compute(stylesheet, context, pos, len));
    Text text = doc.createTextNode(value);
    if (nextSibling != null)
      {
        parent.insertBefore(text, nextSibling);
      }
    else
      {
        parent.appendChild(text);
      }
    // xsl:number doesn't process children
    if (next != null)
      {
        next.apply(stylesheet, mode, 
                   context, pos, len,
                   parent, nextSibling);
      }
  }

  String format(String format, int[] number)
  {
    if (number.length == 0)
      {
        return "";
      }
    int start = 0, end = 0, len = format.length(); // region of format
    // Tokenize
    List tokens = new ArrayList((number.length * 2) + 1);
    List types = new ArrayList(tokens.size());
    while (end < len)
      {
        while (end < len && !isAlphanumeric(format.charAt(end)))
          {
            end++;
          }
        if (end > start)
          {
            tokens.add(format.substring(start, end));
            types.add(Boolean.FALSE);
          }
        start = end;
        while (end < len && isAlphanumeric(format.charAt(end)))
          {
            end++;
          }
        if (end > start)
          {
            tokens.add(format.substring(start, end));
            types.add(Boolean.TRUE);
          }
        start = end;
      }
    // Process tokens
    StringBuffer buf = new StringBuffer();
    len = tokens.size();
    int pos = 0;
    for (int i = 0; i < len; i++)
      {
        String token = (i < 0) ? "." : (String) tokens.get(i);
        boolean alpha = (i < 0) ? true : 
          ((Boolean) types.get(i)).booleanValue();
        if (!alpha)
          {
            buf.append(token);
          }
        else
          {
            if (pos < number.length)
              {
                format(buf, number[pos++], token);
                if (((i + 1 == len) || (i + 2 == len)) &&
                    (pos < number.length))
                  {
                    // More numbers than tokens, reuse last token
                    i -= 2;
                  }
              }
            if (pos == number.length && i < (len - 2))
              {
                // No more numbers. Skip to the end...
                i = len - 2;
                if (((Boolean) types.get(i + 1)).booleanValue())
                  {
                    // number formatting token, ignore
                    i++;
                  }
              }
          }
      }
    //System.err.println("format: '"+format+"' "+asList(number)+" = '"+buf.toString()+"'");
    return buf.toString();
  }

  /*List asList(int[] number)
    {
      List l = new ArrayList();
      for (int i = 0; i < number.length; i++)
        l.add(new Integer(number[i]));
      return l;
    }*/

  void format(StringBuffer buf, int number, String formatToken)
  {
    int len = formatToken.length();
    char c = formatToken.charAt(len - 1);
    if (Character.digit(c, 10) == 1)
      {
        // Check preceding characters
        for (int i = len - 2; i >= 0; i--)
          {
            if (formatToken.charAt(i) != (c - 1))
              {
                format(buf, number, "1");
                return;
              }
          }
        // Decimal representation
        String val = Integer.toString(number);
        for (int d = len - val.length(); d > 0; d--)
          {
            buf.append('0');
          }
        buf.append(val);
      }
    else if ("A".equals(formatToken))
      {
        buf.append(alphabetic('@', number));
      }
    else if ("a".equals(formatToken))
      {
        buf.append(alphabetic('`', number));
      }
    else if ("i".equals(formatToken))
      {
        buf.append(roman(false, number));
      }
    else if ("I".equals(formatToken))
      {
        buf.append(roman(true, number));
      }
    else
      {
        // Unknown numbering sequence
        format(buf, number, "1");
      }
  }

  static final boolean isAlphanumeric(char c)
  {
    switch (Character.getType(c))
      {
      case Character.DECIMAL_DIGIT_NUMBER: // Nd
      case Character.LETTER_NUMBER: // Nl
      case Character.OTHER_NUMBER: // No
      case Character.UPPERCASE_LETTER: // Lu
      case Character.LOWERCASE_LETTER: // Ll
      case Character.TITLECASE_LETTER: // Lt
      case Character.MODIFIER_LETTER: // Lm
      case Character.OTHER_LETTER: // Lo
        return true;
      default:
        return false;
      }
  }

  static final String alphabetic(char offset, int number)
  {
    StringBuffer buf = new StringBuffer();
    while (number > 0)
      {
        int r = number % 26;
        number = number / 26;
        buf.insert(0, (char) (offset + r));
      }
    return buf.toString();
  }

  static final int[] roman_numbers = {1, 5, 10, 50, 100, 500, 1000};
  static final char[] roman_chars = {'i', 'v', 'x', 'l', 'c', 'd', 'm'};

  static final String roman(boolean upper, int number)
  {
    StringBuffer buf = new StringBuffer();
    for (int pos = roman_numbers.length - 1; pos >= 0; pos -= 2)
      {
        int f = number / roman_numbers[pos];
        if (f != 0)
          {
            number = number % (f * roman_numbers[pos]);
          }
        if (f > 4 && f < 9)
          {
            buf.append(roman_chars[pos + 1]);
            f -= 5;
          }
        if (f == 4)
          {
            buf.append(roman_chars[pos]);
            buf.append(roman_chars[pos + 1]);
          }
        else if (f == 9)
          {
            buf.append(roman_chars[pos]);
            buf.append(roman_chars[pos + 2]);
          }
        else
          {
            for (; f > 0; f--)
              {
                buf.append(roman_chars[pos]);
              }
          }
      }
    return upper ? buf.toString().toUpperCase() : buf.toString();
  }
  
  abstract int[] compute(Stylesheet stylesheet, Node context, int pos, int len)
    throws TransformerException;

  public boolean references(QName var)
  {
    if (format.references(var))
      {
        return true;
      }
    return super.references(var);
  }

  public String toString()
  {
    StringBuffer buf = new StringBuffer("number");
    buf.append('[');
    buf.append("format=");
    buf.append(format);
    buf.append(']');
    return buf.toString();
  }

}
