/* AttributedStringIterator.java -- Class to iterate over AttributedString
   Copyright (C) 1998, 1999, 2004, 2005 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 java.text;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
  * This class implements the AttributedCharacterIterator interface.  It
  * is used by AttributedString.getIterator().
  *
  * @version 0.0
  *
  * @author Aaron M. Renn (arenn@urbanophile.com)
  */
class AttributedStringIterator implements AttributedCharacterIterator
{

  /*************************************************************************/

  /** The character iterator containing the text */
  private CharacterIterator ci;

  /** The list of attributes and ranges */
  private AttributedString.AttributeRange[] attribs;

  /**
   * The list of attributes that the user is interested in.  We may,
   * at our option, not return any other attributes.
   */
  private AttributedCharacterIterator.Attribute[] restricts;

  /*************************************************************************/

  AttributedStringIterator(StringCharacterIterator sci, 
                           AttributedString.AttributeRange[] attribs,
                           int begin_index, int end_index,
                           AttributedCharacterIterator.Attribute[] restricts)
  {
    this.ci = new StringCharacterIterator(sci, begin_index, end_index);
    this.attribs = attribs;
    this.restricts = restricts;
  }

  /*************************************************************************/

  // First we have a bunch of stupid redirects.  If StringCharacterIterator
  // weren't final, I just would have extended that for this class.  Alas, no.

  public Object clone()
  {
    return(ci.clone());
  }

  public char current()
  {
    return(ci.current());
  }

  public char next()
  {
    return(ci.next());
  }

  public char previous()
  {
    return(ci.previous());
  }

  public char first()
  {
    return(ci.first());
  }

  public char last()
  {
    return(ci.last());
  }

  public int getIndex()
  {
    return(ci.getIndex());
  }

  public char setIndex(int index)
  {
    return(ci.setIndex(index));  
  }

  public int getBeginIndex()
  {
    return(ci.getBeginIndex());
  }

  public int getEndIndex()
  {
    return(ci.getEndIndex());
  }

  /*
   * Here is where the AttributedCharacterIterator methods start.
   */ 

  /*************************************************************************/

  /**
   * Returns a list of all the attribute keys that are defined anywhere
   * on this string.
   */
  public Set getAllAttributeKeys()
  {
    HashSet s = new HashSet();
    if (attribs == null)
      return(s);

    for (int i = 0; i < attribs.length; i++)
    {
      if (attribs[i].begin_index > getEndIndex()
	  || attribs[i].end_index <= getBeginIndex())
	continue;

      Set key_set = attribs[i].attribs.keySet();
      Iterator iter = key_set.iterator();
      while (iter.hasNext())
        {
          s.add(iter.next());
        }
    }

    return(s);
  }

  /*************************************************************************/

  /**
   * Various methods that determine how far the run extends for various
   * attribute combinations.
   */

  public int getRunLimit()
  {
    return(getRunLimit(getAttributes().keySet()));
  }

  public int getRunLimit(AttributedCharacterIterator.Attribute attrib)
  {
    HashSet s = new HashSet();
    s.add(attrib);
    return(getRunLimit(s));
  }

  public synchronized int getRunLimit(Set attributeSet)
  {
    if (attributeSet == null)
      return ci.getEndIndex();
    
    int current = ci.getIndex();
    int end = ci.getEndIndex();
    int limit = current;
    if (current == end) 
      return end;
    Map runValues = getAttributes();
    while (limit < end) 
    {
      Iterator iterator = attributeSet.iterator();
      while (iterator.hasNext()) 
      {
	// Qualified name is a workaround for a gcj 4.0 bug.
        AttributedCharacterIterator.Attribute attributeKey
	  = (AttributedCharacterIterator.Attribute) iterator.next();
        Object v1 = runValues.get(attributeKey);
        Object v2 = getAttribute(attributeKey, limit + 1);
        boolean changed = false;
        // check for equal or both null, if NO return start
        if (v1 != null) 
          {
            changed = !v1.equals(v2);
          }
        else 
          {
            changed = (v2 != null);  
          }
        if (changed)
          return limit + 1;
      }
      // no differences, so increment limit and next and loop again
      limit++;
    }
    return end;
  }

  /*************************************************************************/

  /**
   * Various methods that determine where the run begins for various
   * attribute combinations.
   */

  /**
   * Returns the index of the first character in the run containing the current
   * character and defined by all the attributes defined for that character
   * position.
   * 
   * @return The run start index.
   */
  public int getRunStart()
  {
    return(getRunStart(getAttributes().keySet()));
  }

  /**
   * Returns the index of the first character in the run, defined by the 
   * specified attribute, that contains the current character.
   * 
   * @param attrib  the attribute (<code>null</code> permitted).
   * 
   * return The index of the first character in the run.
   */
  public int getRunStart(AttributedCharacterIterator.Attribute attrib)
  {
    if (attrib == null)
      return ci.getBeginIndex();
    HashSet s = new HashSet();
    s.add(attrib);
    return(getRunStart(s));
  }

  /**
   * Returns the index of the first character in the run, defined by the 
   * specified attribute set, that contains the current character.
   * 
   * @param attributeSet  the attribute set (<code>null</code> permitted).
   * 
   * return The index of the first character in the run.
   */
  public int getRunStart(Set attributeSet)
  {
    if (attributeSet == null)
      return ci.getBeginIndex();
    
    int current = ci.getIndex();
    int begin = ci.getBeginIndex();
    int start = current;
    if (start == begin) 
      return begin;
    Map runValues = getAttributes();
    int prev = start - 1;
    while (start > begin) 
    {
      Iterator iterator = attributeSet.iterator();
      while (iterator.hasNext()) 
      {
	// Qualified name is a workaround for a gcj 4.0 bug.
        AttributedCharacterIterator.Attribute attributeKey
	  = (AttributedCharacterIterator.Attribute) iterator.next();
        Object v1 = runValues.get(attributeKey);
        Object v2 = getAttribute(attributeKey, prev);
        boolean changed = false;
        // check for equal or both null, if NO return start
        if (v1 != null) 
          {
            changed = !v1.equals(v2);
          }
        else 
          {
            changed = (v2 != null);  
          }
        if (changed)
          return start;
      }
      // no differences, so decrement start and prev and loop again
      start--;
      prev--;
    }
    return start;
  }

  /*************************************************************************/

  /**
   * Returns the value for an attribute at the specified position.  If the
   * attribute key (<code>key</code>) is <code>null</code>, the method returns
   * <code>null</code>.
   * 
   * @param key  the key (<code>null</code> permitted).
   * @param pos  the character position.
   * 
   * @return The attribute value (possibly <code>null</code>).
   */
  private Object getAttribute(AttributedCharacterIterator.Attribute key, 
          int pos)
  {
    if (attribs == null)
      return null;
    for (int i = attribs.length - 1; i >= 0; i--)
      {
        if (pos >= attribs[i].begin_index && pos < attribs[i].end_index)
          {
            Set keys = attribs[i].attribs.keySet();
            if (keys.contains(key)) 
              {
                return attribs[i].attribs.get(key);
              }
          }
      }
    return null;   
  }
  
  /**
   * Returns the value for an attribute at the current position.  If the
   * attribute key (<code>key</code>) is <code>null</code>, the method returns
   * <code>null</code>.
   * 
   * @param key  the key (<code>null</code> permitted).
   * 
   * @return The attribute value (possibly <code>null</code>).
   */
  public Object getAttribute(AttributedCharacterIterator.Attribute key)
  {
    return getAttribute(key, ci.getIndex());
  }

  /*************************************************************************/

  /**
   * Return a list of all the attributes and values defined for this
   * character
   */
  public Map getAttributes()
  {
    HashMap m = new HashMap();
    if (attribs == null)
      return(m);
  
    for (int i = 0; i < attribs.length; i++)
      {
         if ((ci.getIndex() >= attribs[i].begin_index) &&
             (ci.getIndex() < attribs[i].end_index))
           m.putAll(attribs[i].attribs);
      }

    return(m);
  }

} // class AttributedStringIterator
