/* AttributedString.java -- Models text with attributes
   Copyright (C) 1998, 1999 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.Iterator;
import java.util.Hashtable;
import java.util.HashSet;
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>AttributedCharcterIterator</code> interface.
  *
  * @version 0.0
  *
  * @author Aaron M. Renn (arenn@urbanophile.com)
  */
public class AttributedString
{

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

/*
 * Inner Classes
 */

/**
  * This class contains the attributes and ranges of text over which
  * that attributes apply.
  */
final class AttributeRange
{

/*
 * Instance Variables
 */

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

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

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

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

/*
 * Constructors
 */

AttributeRange(Map attribs, int begin_index, int end_index)
{
  this.attribs = attribs;
  this.begin_index = begin_index;
  this.end_index = end_index;
}

} // Inner class AttributeRange

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

/*
 * Instance Variables
 */

/**
  * This object holds the string we are representing.
  */
private StringCharacterIterator sci;

/**
  * This is the attribute information 
  */
private AttributeRange[] attribs;

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

/*
 * Constructors
 */

/**
  * This method initializes 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.
  */
public
AttributedString(String str)
{
  sci = new StringCharacterIterator(str);
  attribs = new AttributeRange[0];
}

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

/**
  * This method initializes 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 attributes)
{
  this(str);

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

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

/**
  * This method 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.
  */
public
AttributedString(AttributedCharacterIterator aci)
{
  this(aci, aci.getBeginIndex(), aci.getEndIndex(), null);
}

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

/**
  * This method 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 begin_index The beginning index of the text subrange.
  * @param end_index The ending index of the text subrange.
  */
public
AttributedString(AttributedCharacterIterator aci, int begin_index,
                 int end_index)
{
  this(aci, begin_index, end_index, null);
}

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

/**
  * This method 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_index The beginning index of the text subrange.
  * @param end_index 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_index, 
                 int end_index, AttributedCharacterIterator.Attribute[] attributes)
{
  // Validate some arguments
  if ((begin_index < 0) || (end_index < begin_index))
    throw new IllegalArgumentException("Bad index values");

  StringBuffer sb = new StringBuffer("");

  // Get the valid attribute list
  Set all_attribs = aci.getAllAttributeKeys();
  if (attributes != null)
    {
      Set valid_attribs = new HashSet();
      Iterator iter = all_attribs.iterator();
      while (iter.hasNext())
        {
          Object obj = iter.next();

          int i;
          for (i = 0; i < attributes.length; i++)
            if (obj.equals(attributes[0]))
              break;

          if (i == attributes.length)
            continue;

          valid_attribs.add(obj);
        }

      all_attribs = valid_attribs;
    } 

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

  do
    { 
      sb.append(c);

      Iterator iter = all_attribs.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.
          int rl = aci.getRunLimit(attrib);
          if (rl == -1)
            continue;
          if (rl > end_index)
            rl = end_index;
          rl -= begin_index;

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

          // If the attribute run starts before the beginning index, we
          // need to junk it if it is an Annotation.
          Object attrib_obj = aci.getAttribute(attrib);
          if (rs < begin_index)
            {
              if (attrib_obj instanceof Annotation)
                 continue;

              rs = begin_index;
            }
          else
            {
              rs -= begin_index;
            }

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

          // Add it to the attribute list.  Yes this is a bad way to do things.
          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(new_map, rs, rl);
        }

      c = aci.next();
    }
  while(c != CharacterIterator.DONE);

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

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

/*
 * Instance Methods
 */

/**
  * This method 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() - 1);
}

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

/**
  * This method 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.
  * @param begin_index The beginning index of the subrange.
  * @param end_index 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_index, int end_index)
{
  if (attrib == null)
    throw new IllegalArgumentException("null attribute");

  Hashtable ht = new Hashtable();
  ht.put(attrib, value);

  addAttributes(ht, begin_index, end_index);
}

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

/**
  * This method adds all of the attributes in the specified list to the
  * specified subrange of the string.
  *
  * @param attributes The list of attributes.
  * @param begin_index The beginning index.
  * @param end_index The ending index
  *
  * @param IllegalArgumentException If the list is <code>null</code> or the subrange is not valid.
  */
public void
addAttributes(Map attributes, int begin_index, int end_index)
{
  if (attributes == null)
    throw new IllegalArgumentException("null attribute");

  if ((begin_index < 0) || (end_index > sci.getEndIndex()) ||
      (end_index < begin_index))
    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, begin_index, 
                                                   end_index);
} 

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

/**
  * This method 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() - 1,
                                      null));
}

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

/**
  * This method 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() - 1));
}

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

/**
  * This method 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 begin_index The beginning index of the subrange.
  * @param end_index The ending index of the subrange.
  *
  * @return An <code>AttributedCharacterIterator</code> for this string.
  */
public AttributedCharacterIterator
getIterator(AttributedCharacterIterator.Attribute[] attributes, 
            int begin_index, int end_index)
{
  if ((begin_index < 0) || (end_index > sci.getEndIndex()) ||
      (end_index < begin_index))
    throw new IllegalArgumentException("bad range");

  return(new AttributedStringIterator(sci, attribs, begin_index, end_index,
                                      attributes));
}

} // class AttributedString

