/* AttributedString.java -- Models text with attributes
   Copyright (C) 1998, 1999, 2004, 2005, 2006, 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 gnu.java.lang.CPStringBuilder;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * This class models a <code>String</code> with attributes over various
 * subranges of the string.  It allows applications to access this
 * information via the <code>AttributedCharacterIterator</code> interface.
 *
 * @since 1.2
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @since 1.2
 */
public class AttributedString
{

  /**
   * The attributes and ranges of text over which those attributes apply.
   */
  final class AttributeRange
  {

    /** A Map of the attributes */
    Map attribs;

    /** The beginning index of the attributes */
    int beginIndex;

    /** The ending index of the attributes */
    int endIndex;

    /**
     * Creates a new attribute range.
     *
     * @param attribs  the attributes.
     * @param beginIndex  the start index.
     * @param endIndex  the end index.
     */
    AttributeRange(Map attribs, int beginIndex, int endIndex)
    {
      this.attribs = attribs;
      this.beginIndex = beginIndex;
      this.endIndex = endIndex;
    }

  } // Inner class AttributeRange

  /** The string we are representing. */
  private StringCharacterIterator sci;

  /** The attribute information */
  private AttributeRange[] attribs;

  /**
   * Creates a new instance of <code>AttributedString</code>
   * that represents the specified <code>String</code> with no attributes.
   *
   * @param str The <code>String</code> to be attributed (<code>null</code> not
   *            permitted).
   *
   * @throws NullPointerException if <code>str</code> is <code>null</code>.
   */
  public AttributedString(String str)
  {
    sci = new StringCharacterIterator(str);
    attribs = new AttributeRange[0];
  }

  /**
   * Creates a new instance of <code>AttributedString</code>
   * that represents that specified <code>String</code> with the specified
   * attributes over the entire length of the <code>String</code>.
   *
   * @param str The <code>String</code> to be attributed.
   * @param attributes The attribute list.
   */
  public AttributedString(String str,
                          Map<? extends AttributedCharacterIterator.Attribute, ?> attributes)
  {
    this(str);

    attribs = new AttributeRange[1];
    attribs[0] = new AttributeRange(attributes, 0, str.length());
  }

  /**
   * Initializes a new instance of <code>AttributedString</code>
   * that will use the text and attribute information from the specified
   * <code>AttributedCharacterIterator</code>.
   *
   * @param aci The <code>AttributedCharacterIterator</code> containing the
   *            text and attribute information (<code>null</code> not
   *            permitted).
   *
   * @throws NullPointerException if <code>aci</code> is <code>null</code>.
   */
  public AttributedString(AttributedCharacterIterator aci)
  {
    this(aci, aci.getBeginIndex(), aci.getEndIndex(), null);
  }

  /**
   * Initializes a new instance of <code>AttributedString</code>
   * that will use the text and attribute information from the specified
   * subrange of the specified <code>AttributedCharacterIterator</code>.
   *
   * @param aci The <code>AttributedCharacterIterator</code> containing the
   *            text and attribute information.
   * @param beginIndex The beginning index of the text subrange.
   * @param endIndex The ending index of the text subrange.
   */
  public AttributedString(AttributedCharacterIterator aci, int beginIndex,
                          int endIndex)
  {
    this(aci, beginIndex, endIndex, null);
  }

  /**
   * Initializes a new instance of <code>AttributedString</code>
   * that will use the text and attribute information from the specified
   * subrange of the specified <code>AttributedCharacterIterator</code>.
   * Only attributes from the source iterator that are present in the
   * specified array of attributes will be included in the attribute list
   * for this object.
   *
   * @param aci The <code>AttributedCharacterIterator</code> containing the
   *            text and attribute information.
   * @param begin The beginning index of the text subrange.
   * @param end The ending index of the text subrange.
   * @param attributes A list of attributes to include from the iterator, or
   *                   <code>null</code> to include all attributes.
   */
  public AttributedString(AttributedCharacterIterator aci, int begin, int end,
                          AttributedCharacterIterator.Attribute[] attributes)
  {
    // Validate some arguments
    if ((begin < 0) || (end < begin) || end > aci.getEndIndex())
      throw new IllegalArgumentException("Bad index values");

    CPStringBuilder sb = new CPStringBuilder("");

    // Get the valid attribute list
    Set allAttribs = aci.getAllAttributeKeys();
    if (attributes != null)
      allAttribs.retainAll(Arrays.asList(attributes));

    // Loop through and extract the attributes
    char c = aci.setIndex(begin);

    ArrayList accum = new ArrayList();
    do
      {
        sb.append(c);

        Iterator iter = allAttribs.iterator();
        while(iter.hasNext())
          {
            Object obj = iter.next();

            // What should we do if this is not true?
            if (!(obj instanceof AttributedCharacterIterator.Attribute))
              continue;

            AttributedCharacterIterator.Attribute attrib =
              (AttributedCharacterIterator.Attribute)obj;

            // Make sure the attribute is defined.
            Object attribObj = aci.getAttribute(attrib);
            if (attribObj == null)
              continue;
            int rl = aci.getRunLimit(attrib);
            if (rl > end)
              rl = end;
            rl -= begin;

            // Check to see if we already processed this one
            int rs = aci.getRunStart(attrib);
            if ((rs < aci.getIndex()) && (aci.getIndex() != begin))
              continue;

            // If the attribute run starts before the beginning index, we
            // need to junk it if it is an Annotation.
            rs -= begin;
            if (rs < 0)
              {
                if (attribObj instanceof Annotation)
                   continue;

                rs = 0;
              }

            // Create a map object.  Yes this will only contain one attribute
            Map newMap = new Hashtable();
            newMap.put(attrib, attribObj);

            // Add it to the attribute list.
            accum.add(new AttributeRange(newMap, rs, rl));
          }

        c = aci.next();
      }
    while( aci.getIndex() < end );

    attribs = new AttributeRange[accum.size()];
    attribs = (AttributeRange[]) accum.toArray(attribs);

    sci = new StringCharacterIterator(sb.toString());
  }

  /**
   * Adds a new attribute that will cover the entire string.
   *
   * @param attrib The attribute to add.
   * @param value The value of the attribute.
   */
  public void addAttribute(AttributedCharacterIterator.Attribute attrib,
          Object value)
  {
    addAttribute(attrib, value, 0, sci.getEndIndex());
  }

  /**
   * Adds a new attribute that will cover the specified subrange
   * of the string.
   *
   * @param attrib The attribute to add.
   * @param value The value of the attribute, which may be <code>null</code>.
   * @param begin The beginning index of the subrange.
   * @param end The ending index of the subrange.
   *
   * @exception IllegalArgumentException If attribute is <code>null</code> or
   *            the subrange is not valid.
   */
  public void addAttribute(AttributedCharacterIterator.Attribute attrib,
          Object value, int begin, int end)
  {
    if (attrib == null)
      throw new IllegalArgumentException("null attribute");
    if (end <= begin)
      throw new IllegalArgumentException("Requires end > begin");
    HashMap hm = new HashMap();
    hm.put(attrib, value);

    addAttributes(hm, begin, end);
  }

  /**
   * Adds all of the attributes in the specified list to the
   * specified subrange of the string.
   *
   * @param attributes The list of attributes.
   * @param beginIndex The beginning index.
   * @param endIndex The ending index
   *
   * @throws NullPointerException if <code>attributes</code> is
   *         <code>null</code>.
   * @throws IllegalArgumentException if the subrange is not valid.
   */
  public void addAttributes(Map<? extends AttributedCharacterIterator.Attribute, ?> attributes,
                            int beginIndex, int endIndex)
  {
    if (attributes == null)
      throw new NullPointerException("null attribute");

    if ((beginIndex < 0) || (endIndex > sci.getEndIndex()) ||
        (endIndex <= beginIndex))
      throw new IllegalArgumentException("bad range");

    AttributeRange[] new_list = new AttributeRange[attribs.length + 1];
    System.arraycopy(attribs, 0, new_list, 0, attribs.length);
    attribs = new_list;
    attribs[attribs.length - 1] = new AttributeRange(attributes, beginIndex,
                                                     endIndex);
  }

  /**
   * Returns an <code>AttributedCharacterIterator</code> that
   * will iterate over the entire string.
   *
   * @return An <code>AttributedCharacterIterator</code> for the entire string.
   */
  public AttributedCharacterIterator getIterator()
  {
    return(new AttributedStringIterator(sci, attribs, 0, sci.getEndIndex(),
            null));
  }

  /**
   * Returns an <code>AttributedCharacterIterator</code> that
   * will iterate over the entire string.  This iterator will return information
   * about the list of attributes in the specified array.  Attributes not in
   * the array may or may not be returned by the iterator.  If the specified
   * array is <code>null</code>, all attributes will be returned.
   *
   * @param attributes A list of attributes to include in the returned iterator.
   *
   * @return An <code>AttributedCharacterIterator</code> for this string.
   */
  public AttributedCharacterIterator getIterator(
          AttributedCharacterIterator.Attribute[] attributes)
  {
    return(getIterator(attributes, 0, sci.getEndIndex()));
  }

  /**
   * Returns an <code>AttributedCharacterIterator</code> that
   * will iterate over the specified subrange.  This iterator will return
   * information about the list of attributes in the specified array.
   * Attributes not in the array may or may not be returned by the iterator.
   * If the specified array is <code>null</code>, all attributes will be
   * returned.
   *
   * @param attributes A list of attributes to include in the returned iterator.
   * @param beginIndex The beginning index of the subrange.
   * @param endIndex The ending index of the subrange.
   *
   * @return An <code>AttributedCharacterIterator</code> for this string.
   */
  public AttributedCharacterIterator getIterator(
          AttributedCharacterIterator.Attribute[] attributes,
          int beginIndex, int endIndex)
  {
    if ((beginIndex < 0) || (endIndex > sci.getEndIndex()) ||
        (endIndex < beginIndex))
      throw new IllegalArgumentException("bad range");

    return(new AttributedStringIterator(sci, attribs, beginIndex, endIndex,
                                        attributes));
  }

} // class AttributedString
