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

import static java.text.AttributedCharacterIterator.Attribute;

/**
 * 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<? extends Attribute, ?> 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<? extends Attribute, ?> 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 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,
                          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<Attribute> allAttribs = aci.getAllAttributeKeys();
    if (attributes != null)
      allAttribs.retainAll(Arrays.asList(attributes));

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

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

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

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

            Attribute attrib = (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<Attribute,Object> newMap = new Hashtable<Attribute,Object>();
            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 = 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(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(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<Attribute,Object> hm = new HashMap<Attribute,Object>();
    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 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(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(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
