/* AttributedFormatBuffer.java -- Implements an attributed FormatBuffer.
   Copyright (C) 2004 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 gnu.java.text;

import gnu.java.lang.CPStringBuilder;

import java.text.AttributedCharacterIterator;
import java.util.ArrayList;
import java.util.HashMap;

/**
 * This class is an implementation of a FormatBuffer with attributes.
 * Note that this class is not thread-safe; external synchronisation
 * should be used if an instance is to be accessed from multiple threads.
 *
 * @author Guilhem Lavaux <guilhem@kaffe.org>
 * @date April 10, 2004
 */
public class AttributedFormatBuffer implements FormatBuffer
{
  private final CPStringBuilder buffer;
  private final ArrayList ranges;
  private final ArrayList attributes;
  private int[] a_ranges;
  private HashMap[] a_attributes;
  private int startingRange;
  AttributedCharacterIterator.Attribute defaultAttr;

  /**
   * This constructor accepts a StringBuffer. If the buffer contains
   * already some characters they will not be attributed.
   */
  public AttributedFormatBuffer(CPStringBuilder buffer)
  {
    this.buffer = new CPStringBuilder(buffer);
    this.ranges = new ArrayList();
    this.attributes = new ArrayList();
    this.defaultAttr = null;
    if (buffer.length() != 0)
      {
        this.startingRange = buffer.length();
        addAttribute(buffer.length(), null);
      }
    else
      this.startingRange = -1;
  }

  public AttributedFormatBuffer(int prebuffer)
  {
    this(new CPStringBuilder(prebuffer));
  }

  public AttributedFormatBuffer()
  {
    this(10);
  }

  /**
   * This method is a helper function for formatters. Given a set of ranges
   * and attributes it adds exactly one attribute for the range of characters
   * comprised between the last entry in 'ranges' and the specified new range.
   *
   * @param new_range A new range to insert in the list.
   * @param attr A new attribute to insert in the list.
   */
  private final void addAttribute(int new_range, AttributedCharacterIterator.Attribute attr)
  {
    HashMap map;

    if (attr != null)
      {
        map = new HashMap();
        map.put(attr, attr);
        attributes.add(map);
      }
    else
      attributes.add(null);

    ranges.add(new Integer(new_range));
  }

  public void append(String s)
  {
    if (startingRange < 0)
      startingRange = 0;
    buffer.append(s);
  }

  public void append(String s, AttributedCharacterIterator.Attribute attr)
  {
    setDefaultAttribute(attr);
    startingRange = buffer.length();
    append(s);
    setDefaultAttribute(null);
  }

  public void append(String s, int[] ranges, HashMap[] attrs)
  {
    int curPos = buffer.length();

    setDefaultAttribute(null);
    if (ranges != null)
      {
        for (int i = 0; i < ranges.length; i++)
          {
            this.ranges.add(new Integer(ranges[i] + curPos));
            this.attributes.add(attrs[i]);
          }
      }
    startingRange = buffer.length();
    buffer.append(s);
  }

  public void append(char c)
  {
    if (startingRange < 0)
      startingRange = buffer.length();
    buffer.append(c);
  }

  public void append(char c, AttributedCharacterIterator.Attribute attr)
  {
    setDefaultAttribute(attr);
    buffer.append(c);
    setDefaultAttribute(null);
  }

  public void setDefaultAttribute(AttributedCharacterIterator.Attribute attr)
  {
    if (attr == defaultAttr)
      return;

    int currentPos = buffer.length();

    if (startingRange != currentPos && startingRange >= 0)
      {
        addAttribute(currentPos, defaultAttr);
      }
    defaultAttr = attr;
    startingRange = currentPos;
  }

  public AttributedCharacterIterator.Attribute getDefaultAttribute()
  {
    return defaultAttr;
  }

  public void cutTail(int length)
  {
    buffer.setLength(buffer.length()-length);
  }

  public int length()
  {
    return buffer.length();
  }

  public void clear()
  {
    buffer.setLength(0);
    ranges.clear();
    attributes.clear();
    defaultAttr = null;
    startingRange = -1;
  }

  /**
   * This method synchronizes the state of the attribute array.
   * After calling it you may call {@link #getDefaultAttribute()}.
   */
  public void sync()
  {
    if (startingRange < 0 || startingRange == buffer.length())
      return;

    addAttribute(buffer.length(), defaultAttr);

    a_ranges = new int[ranges.size()];
    for (int i = 0; i < a_ranges.length; i++)
      a_ranges[i] = ((Integer)(ranges.get (i))).intValue();

    a_attributes = new HashMap[attributes.size()];
    System.arraycopy(attributes.toArray(), 0, a_attributes, 0, a_attributes.length);
  }

  /**
   * This method returns the internal CPStringBuilder describing
   * the attributed string.
   *
   * @return An instance of CPStringBuilder which contains the string.
   */
  public CPStringBuilder getBuffer()
  {
    return buffer;
  }

  /**
   * This method returns the ranges for the attributes.
   *
   * @return An array of int describing the ranges.
   */
  public int[] getRanges()
  {
    return a_ranges;
  }

  /**
   * This method returns the array containing the map on the
   * attributes.
   *
   * @return An array of {@link java.util.Map} containing the attributes.
   */
  public HashMap[] getAttributes()
  {
    return a_attributes;
  }
}
