/* CollationElementIterator.java -- Walks through collation elements
   Copyright (C) 1998, 1999, 2001, 2002, 2003, 2004  Free Software Foundation

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 java.text;

import gnu.java.lang.CPStringBuilder;

import java.util.ArrayList;

/* Written using "Java Class Libraries", 2nd edition, plus online
 * API docs for JDK 1.2 from http://www.javasoft.com.
 * Status: Believed complete and correct to JDK 1.1.
 */

/**
 * This class walks through the character collation elements of a
 * <code>String</code> as defined by the collation rules in an instance of
 * <code>RuleBasedCollator</code>.  There is no public constructor for
 * this class.  An instance is created by calling the
 * <code>getCollationElementIterator</code> method on
 * <code>RuleBasedCollator</code>.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Tom Tromey (tromey@cygnus.com)
 * @author Guilhem Lavaux (guilhem.lavaux@free.fr)
 */
public final class CollationElementIterator
{
  /**
   * This is a constant value that is returned to indicate that the end of
   * the string was encountered.
   */
  public static final int NULLORDER = -1;

  /**
   * This is the RuleBasedCollator this object was created from.
   */
  RuleBasedCollator collator;

  /**
   * This is the String that is being iterated over.
   */
  CharacterIterator text;

  /**
   * This is the index into the collation decomposition where we are currently scanning.
   */
  int index;

  /**
   * This is the index into the String where we are currently scanning.
   */
  int textIndex;

  /**
   * Array containing the collation decomposition of the
   * text given to the constructor.
   */
  private RuleBasedCollator.CollationElement[] text_decomposition;

  /**
   * Array containing the index of the specified block.
   */
  private int[] text_indexes;

  /**
   * This method initializes a new instance of <code>CollationElementIterator</code>
   * to iterate over the specified <code>String</code> using the rules in the
   * specified <code>RuleBasedCollator</code>.
   *
   * @param collator The <code>RuleBasedCollation</code> used for calculating collation values
   * @param text The <code>String</code> to iterate over.
   */
  CollationElementIterator(RuleBasedCollator collator, String text)
  {
    this.collator = collator;

    setText (text);
  }

  /**
   * This method initializes a new instance of <code>CollationElementIterator</code>
   * to iterate over the specified <code>String</code> using the rules in the
   * specified <code>RuleBasedCollator</code>.
   *
   * @param collator The <code>RuleBasedCollation</code> used for calculating collation values
   * @param text The character iterator to iterate over.
   */
  CollationElementIterator(RuleBasedCollator collator, CharacterIterator text)
  {
    this.collator = collator;

    setText (text);
  }

  RuleBasedCollator.CollationElement nextBlock()
  {
    if (index >= text_decomposition.length)
      return null;

    RuleBasedCollator.CollationElement e = text_decomposition[index];

    textIndex = text_indexes[index+1];

    index++;

    return e;
  }

  RuleBasedCollator.CollationElement previousBlock()
  {
    if (index == 0)
      return null;

    index--;
    RuleBasedCollator.CollationElement e = text_decomposition[index];

    textIndex = text_indexes[index+1];

    return e;
  }

  /**
   * This method returns the collation ordering value of the next character sequence
   * in the string (it may be an extended character following collation rules).
   * This method will return <code>NULLORDER</code> if the
   * end of the string was reached.
   *
   * @return The collation ordering value.
   */
  public int next()
  {
    RuleBasedCollator.CollationElement e = nextBlock();

    if (e == null)
      return NULLORDER;

    return e.getValue();
  }

  /**
   * This method returns the collation ordering value of the previous character
   * in the string.  This method will return <code>NULLORDER</code> if the
   * beginning of the string was reached.
   *
   * @return The collation ordering value.
   */
  public int previous()
  {
    RuleBasedCollator.CollationElement e = previousBlock();

    if (e == null)
      return NULLORDER;

    return e.getValue();
  }

  /**
   * This method returns the primary order value for the given collation
   * value.
   *
   * @param order The collation value returned from <code>next()</code> or
   *              <code>previous()</code>.
   *
   * @return The primary order value of the specified collation value.  This is
   *         the high 16 bits.
   */
  public static int primaryOrder(int order)
  {
    // From the JDK 1.2 spec.
    return order >>> 16;
  }

  /**
   * This method resets the internal position pointer to read from the
   * beginning of the <code>String</code> again.
   */
  public void reset()
  {
    index = 0;
    textIndex = 0;
  }

  /**
   * This method returns the secondary order value for the given collation
   * value.
   *
   * @param order The collation value returned from <code>next()</code> or
   *              <code>previous()</code>.
   *
   * @return The secondary order value of the specified collation value.  This
   *         is the bits 8-15.
   */
  public static short secondaryOrder(int order)
  {
    // From the JDK 1.2 spec.
    return (short) ((order >>> 8) & 255);
  }

  /**
   * This method returns the tertiary order value for the given collation
   * value.
   *
   * @param order The collation value returned from <code>next()</code> or
   *              <code>previous()</code>.
   *
   * @return The tertiary order value of the specified collation value.  This
   *         is the low eight bits.
   */
  public static short tertiaryOrder(int order)
  {
    // From the JDK 1.2 spec.
    return (short) (order & 255);
  }

  /**
   * This method sets the <code>String</code> that it is iterating over
   * to the specified <code>String</code>.
   *
   * @param text The new <code>String</code> to iterate over.
   *
   * @since 1.2
   */
  public void setText(String text)
  {
    int idx = 0;
    int idx_idx = 0;
    int alreadyExpanded = 0;
    int idxToMove = 0;

    this.text = new StringCharacterIterator(text);
    this.index = 0;

    String work_text = text.intern();

    ArrayList a_element = new ArrayList();
    ArrayList a_idx = new ArrayList();

    // Build element collection ordered as they come in "text".
    while (idx < work_text.length())
      {
        String key, key_old;

        Object object = null;
        int p = 1;

        // IMPROVE: use a TreeMap with a prefix-ordering rule.
        key_old = key = null;
        do
          {
            if (object != null)
              key_old = key;
            key = work_text.substring (idx, idx+p);
            object = collator.prefix_tree.get (key);
            if (object != null && idx < alreadyExpanded)
              {
                RuleBasedCollator.CollationElement prefix = (RuleBasedCollator.CollationElement)object;
                if (prefix.expansion != null &&
                    prefix.expansion.startsWith(work_text.substring(0, idx)))
                {
                  object = null;
                  key = key_old;
                }
              }
            p++;
          }
        while (idx+p <= work_text.length());

        if (object == null)
          key = key_old;

        RuleBasedCollator.CollationElement prefix =
          (RuleBasedCollator.CollationElement) collator.prefix_tree.get (key);

        /*
         * First case: There is no such sequence in the database.
         * We will have to build one from the context.
         */
        if (prefix == null)
          {
            /*
             * We are dealing with sequences in an expansion. They
             * are treated as accented characters (tertiary order).
             */
            if (alreadyExpanded > 0)
              {
                RuleBasedCollator.CollationElement e =
                  collator.getDefaultAccentedElement (work_text.charAt (idx));

                a_element.add (e);
                a_idx.add (new Integer(idx_idx));
                idx++;
                alreadyExpanded--;
                if (alreadyExpanded == 0)
                  {
                    /* There is not any characters left in the expansion set.
                     * We can increase the pointer in the source string.
                     */
                    idx_idx += idxToMove;
                    idxToMove = 0;
                  }
                else
                  idx_idx++;
              }
            else
              {
                /* This is a normal character. */
                RuleBasedCollator.CollationElement e =
                  collator.getDefaultElement (work_text.charAt (idx));
                Integer i_ref = new Integer(idx_idx);

                /* Don't forget to mark it as a special sequence so the
                 * string can be ordered.
                 */
                a_element.add (RuleBasedCollator.SPECIAL_UNKNOWN_SEQ);
                a_idx.add (i_ref);
                a_element.add (e);
                a_idx.add (i_ref);
                idx_idx++;
                idx++;
              }
            continue;
          }

        /*
         * Second case: Here we have found a matching sequence.
         * Here we have an expansion string prepend it to the "work text" and
         * add the corresponding sorting element. We must also mark
         */
        if (prefix.expansion != null)
          {
            work_text = prefix.expansion
              + work_text.substring (idx+prefix.key.length());
            idx = 0;
            a_element.add (prefix);
            a_idx.add (new Integer(idx_idx));
            if (alreadyExpanded == 0)
              idxToMove = prefix.key.length();
            alreadyExpanded += prefix.expansion.length()-prefix.key.length();
          }
        else
          {
            /* Third case: the simplest. We have got the prefix and it
             * has not to be expanded.
             */
            a_element.add (prefix);
            a_idx.add (new Integer(idx_idx));
            idx += prefix.key.length();
            /* If the sequence is in an expansion, we must decrease the
             * counter.
             */
            if (alreadyExpanded > 0)
              {
                alreadyExpanded -= prefix.key.length();
                if (alreadyExpanded == 0)
                  {
                    idx_idx += idxToMove;
                    idxToMove = 0;
                  }
              }
            else
              idx_idx += prefix.key.length();
          }
      }

    text_decomposition = (RuleBasedCollator.CollationElement[])
           a_element.toArray(new RuleBasedCollator.CollationElement[a_element.size()]);
    text_indexes = new int[a_idx.size()+1];
    for (int i = 0; i < a_idx.size(); i++)
      {
        text_indexes[i] = ((Integer)a_idx.get(i)).intValue();
      }
    text_indexes[a_idx.size()] = text.length();
  }

  /**
   * This method sets the <code>String</code> that it is iterating over
   * to the <code>String</code> represented by the specified
   * <code>CharacterIterator</code>.
   *
   * @param source The <code>CharacterIterator</code> containing the new
   * <code>String</code> to iterate over.
   */
  public void setText(CharacterIterator source)
  {
    CPStringBuilder expand = new CPStringBuilder();

    // For now assume we read from the beginning of the string.
    for (char c = source.first();
         c != CharacterIterator.DONE;
         c = source.next())
      expand.append(c);

    setText(expand.toString());
  }

  /**
   * This method returns the current offset into the <code>String</code>
   * that is being iterated over.
   *
   * @return The iteration index position.
   *
   * @since 1.2
   */
  public int getOffset()
  {
    return textIndex;
  }

  /**
   * This method sets the iteration index position into the current
   * <code>String</code> to the specified value.  This value must not
   * be negative and must not be greater than the last index position
   * in the <code>String</code>.
   *
   * @param offset The new iteration index position.
   *
   * @exception IllegalArgumentException If the new offset is not valid.
   */
  public void setOffset(int offset)
  {
    if (offset < 0)
      throw new IllegalArgumentException("Negative offset: " + offset);

    if (offset > (text.getEndIndex() - 1))
      throw new IllegalArgumentException("Offset too large: " + offset);

    for (index = 0; index < text_decomposition.length; index++)
      {
        if (offset <= text_indexes[index])
          break;
      }
    /*
     * As text_indexes[0] == 0, we should not have to take care whether index is
     * greater than 0. It is always.
     */
    if (text_indexes[index] == offset)
      textIndex = offset;
    else
      textIndex = text_indexes[index-1];
  }

  /**
   * This method returns the maximum length of any expansion sequence that
   * ends with the specified collation order value.  (Whatever that means).
   *
   * @param value The collation order value
   *
   * @return The maximum length of an expansion sequence.
   */
  public int getMaxExpansion(int value)
  {
    return 1;
  }
}
