/* FieldPosition.java -- Keeps track of field positions while formatting
   Copyright (C) 1998, 1999, 2001 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;

/**
 * This class is used by the java.text formatting classes to track
 * field positions.  A field position is defined by an identifier value
 * and begin and end index positions.  The formatting classes in java.text
 * typically define constant values for the field identifiers.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Per Bothner <bothner@cygnus.com>
 */
public class FieldPosition
{
  /**
   * This is the field identifier value.
   */
  private int field_id;

  /**
   * This is the beginning index of the field.
   */
  private int begin;

  /**
   * This is the ending index of the field.
   */
  private int end;

  /**
   * This is the field attribute value.
   */
  private Format.Field field_attribute;

  /**
   * This method initializes a new instance of <code>FieldPosition</code>
   * to have the specified field attribute. The attribute will be used as
   * an id.
   *
   * @param field The field format attribute.
   */
  public FieldPosition (Format.Field field)
  {
    this.field_attribute = field;
  }

  /**
   * This method initializes a new instance of <code>FieldPosition</code>
   * to have the specified field attribute. The attribute will be used as
   * an id is non null. The integer field id is only used if the Format.Field
   * attribute is not used by the formatter.
   *
   * @param field The field format attribute.
   * @param field_id The field identifier value.
   */
  public FieldPosition (Format.Field field, int field_id)
  {
    this.field_attribute = field;
    this.field_id = field_id;
  }

  /**
   * This method initializes a new instance of <code>FieldPosition</code> to
   * have the specified field id.
   *
   * @param field_id The field identifier value.
   */
  public FieldPosition (int field_id)
  {
    this.field_id = field_id;
  }

  /**
   * This method returns the field identifier value for this object.
   *
   * @return The field identifier.
   */
  public int getField ()
  {
    return field_id;
  }

  public Format.Field getFieldAttribute ()
  {
    return field_attribute;
  }

  /**
   * This method returns the beginning index for this field.
   *
   * @return The beginning index.
   */
  public int getBeginIndex ()
  {
    return begin;
  }

  /**
   * This method sets the beginning index of this field to the specified value.
   *
   * @param begin The new beginning index.
   */
  public void setBeginIndex (int begin)
  {
    this.begin = begin;
  }

  /**
   * This method returns the ending index for the field.
   *
   * @return The ending index.
   */
  public int getEndIndex ()
  {
    return end;
  }

  /**
   * This method sets the ending index of this field to the specified value.
   *
   * @param end The new ending index.
   */
  public void setEndIndex (int end)
  {
    this.end = end;
  }

  /**
   * This method tests this object for equality against the specified object.
   * The objects will be considered equal if and only if:
   * <p>
   * <ul>
   * <li>The specified object is not <code>null</code>.
   * <li>The specified object has the same class as this object.
   * <li>The specified object has the same field identifier, field attribute 
   * and beginning and ending index as this object.
   * </ul>
   *
   * @param obj The object to test for equality to this object.
   *
   * @return <code>true</code> if the specified object is equal to
   * this object, <code>false</code> otherwise. 
   */
  public boolean equals (Object obj)
  {
    if (this == obj)
      return true;

    if (obj == null || obj.getClass() != this.getClass())
      return false;

    FieldPosition fp = (FieldPosition) obj;
    return (field_id == fp.field_id
	    && (field_attribute == fp.field_attribute 
		|| (field_attribute != null 
		    && field_attribute.equals(fp.field_attribute)))
	    && begin == fp.begin
	    && end == fp.end);
  }


  /**
   * This method returns a hash value for this object
   * 
   * @return A hash value for this object.
   */
  public int hashCode ()
  {
    int hash = 5;

    hash = 31 * hash + field_id;
    hash = 31 * hash + begin;
    hash = 31 * hash + end;
    hash = 31 * hash + 
      (null == field_attribute ? 0 : field_attribute.hashCode());

    return hash;
  }

  /**
   * This method returns a <code>String</code> representation of this
   * object.
   *
   * @return A <code>String</code> representation of this object.
   */
  public String toString ()
  {
    return (getClass ().getName ()
	    + "[field=" + getField ()
	    + ",attribute=" + getFieldAttribute ()
	    + ",beginIndex=" + getBeginIndex () 
	    + ",endIndex=" + getEndIndex () 
	    + "]");
  }
}
