/* Label.java -- Java label widget
   Copyright (C) 1999, 2000, 2002, 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.awt;

import java.awt.peer.LabelPeer;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;

/**
 * This component is used for displaying simple text strings that cannot
 * be edited by the user.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Tom Tromey (tromey@cygnus.com)
 * @author Andrew John Hughes  (gnu_andrew@member.fsf.org)
 */
public class Label extends Component implements Accessible
{

  /**
   * Alignment constant aligning the text to the left of its window.
   */
  public static final int LEFT = 0;

  /**
   * Alignment constant aligning the text in the center of its window.
   */
  public static final int CENTER = 1;

  /**
   * Alignment constant aligning the text to the right of its window.
   */
  public static final int RIGHT = 2;

  // Serialization version constant:
  private static final long serialVersionUID = 3094126758329070636L;

  /**
   * @serial Indicates the alignment of the text within this label's window.
   * This is one of the constants in this class.  The default value is
   * <code>LEFT</code>.
   */
  private int alignment;

  /**
   * @serial The text displayed in the label
   */
  private String text;

  /**
   * Initializes a new instance of <code>Label</code> with no text.
   *
   * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
   */
  public Label()
  {
    this("", LEFT);
  }

  /**
   * Initializes a new instance of <code>Label</code> with the specified
   * text that is aligned to the left.
   *
   * @param text The text of the label.
   *
   * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
   */
  public Label(String text)
  {
    this(text, LEFT);
  }

  /**
   * Initializes a new instance of <code>Label</code> with the specified
   * text and alignment.
   *
   * @param text The text of the label.
   * @param alignment The desired alignment for the text in this label,
   * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
   * <code>RIGHT</code>.
   *
   * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
   */
  public Label(String text, int alignment)
  {
    setAlignment(alignment);
    setText(text);

    if (GraphicsEnvironment.isHeadless())
      throw new HeadlessException();
  }

  /**
   * Returns the constant indicating the alignment of the text in this
   * label.  The value returned will be one of the alignment constants
   * from this class.
   *
   * @return The alignment of the text in the label.
   */
  public int getAlignment()
  {
    return(alignment);
  }

  /**
   * Sets the text alignment of this label to the specified value.
   *
   * @param alignment The desired alignment for the text in this label,
   * which must be one of <code>LEFT</code>, <code>CENTER</code>, or
   * <code>RIGHT</code>.
   */
  public synchronized void setAlignment(int alignment)
  {
    if (alignment != CENTER && alignment != LEFT && alignment != RIGHT)
      throw new IllegalArgumentException("invalid alignment: " + alignment);
    this.alignment = alignment;
    if (peer != null)
      {
        LabelPeer lp = (LabelPeer) peer;
        lp.setAlignment(alignment);
      }
  }

  /**
   * Returns the text displayed in this label.
   *
   * @return The text for this label.
   */
  public String getText()
  {
    return text;
  }

  /**
   * Sets the text in this label to the specified value.
   *
   * @param text The new text for this label.
   */
  public synchronized void setText(String text)
  {
    if ((this.text == null && text != null)
        || (this.text != null && ! this.text.equals(text)))
      {
        this.text = text;

        if (peer != null)
         {
           LabelPeer lp = (LabelPeer) peer;
           lp.setText(text);
         }
       invalidate();
      }
  }

  /**
   * Notifies this label that it has been added to a container, causing
   * the peer to be created.  This method is called internally by the AWT
   * system.
   */
  public void addNotify()
  {
    if (peer == null)
      peer = getToolkit().createLabel(this);
    super.addNotify();
  }

  /**
   * Returns a parameter string useful for debugging.
   *
   * @return A debugging string.
   */
  protected String paramString()
  {
    return ("text=" + getText() + ",alignment=" +
          getAlignment() + "," + super.paramString());
  }

  /**
   * This class provides accessibility support for the label.
   */
  protected class AccessibleAWTLabel
    extends AccessibleAWTComponent
  {
    /**
     * For compatability with Sun's JDK 1.4.2 rev. 5
     */
    private static final long serialVersionUID = -3568967560160480438L;

    /**
     * Constructor for the accessible label.
     */
    public AccessibleAWTLabel()
    {
    }

    /**
     * Returns the accessible name for the label.  This is
     * the text used in the label.
     *
     * @return a <code>String</code> containing the accessible
     *         name for this label.
     */
    public String getAccessibleName()
    {
      return getText();
    }

    /**
     * Returns the accessible role for the label.
     *
     * @return an instance of <code>AccessibleRole</code>, describing
     *         the role of the label.
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.LABEL;
    }

  }

  /**
   * Gets the AccessibleContext associated with this <code>Label</code>.
   * The context is created, if necessary.
   *
   * @return the associated context
   */
  public AccessibleContext getAccessibleContext()
  {
    /* Create the context if this is the first request */
    if (accessibleContext == null)
      accessibleContext = new AccessibleAWTLabel();
    return accessibleContext;
  }

  /**
   * Generate a unique name for this button.
   *
   * @return A unique name for this button.
   */
  String generateName()
  {
    return "label" + getUniqueLong();
  }

  /**
   * The number used to generate the name returned by getName.
   */
  private static transient long nextLabelNumber;

  private static synchronized long getUniqueLong()
  {
    return nextLabelNumber++;
  }

}
