/* 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 gnu.java.lang.CPStringBuilder;

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
    CPStringBuilder buf = new CPStringBuilder();
    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(CPStringBuilder 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)
  {
    CPStringBuilder buf = new CPStringBuilder();
    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)
  {
    CPStringBuilder buf = new CPStringBuilder();
    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()
  {
    CPStringBuilder buf = new CPStringBuilder("number");
    buf.append('[');
    buf.append("format=");
    buf.append(format);
    buf.append(']');
    return buf.toString();
  }

}
