/*
 * Java-Gnome Bindings Library
 *
 * Copyright 1998-2004 the Java-Gnome Team, all rights reserved.
 *
 * The Java-Gnome bindings library is free software distributed under
 * the terms of the GNU Library General Public License version 2.
 */

package org.gnu.gtk;

import org.gnu.glib.GObject;
import org.gnu.glib.Handle;
import org.gnu.glib.Type;
import org.gnu.pango.EllipsizeMode;

/**
 * The Label widget displays a small amount of text. As the name implies, most 
 * labels are used to label another widget such as a Button, a MenuItem, or a 
 * OptionMenu.
 *
 * <h3>Mnemonics</h3>
 * <p>Labels may contain mnemonics. Mnemonics are underlined characters in the 
 * label, used for keyboard navigation. Mnemonics are created by providing a 
 * string with an underscore before the mnemonic character, such as "_File", 
 * to the constructor or setText method, with the hadMnemonic parameter true.
 * <p>Mnemonics automatically activate any activatable widget the label is 
 * inside, such as a Button; if the label is not inside the mnemonic's target 
 * widget, you have to tell the label about the target using setMnemonicWidget.
 * 
 * <h3>Markup (Styled Text)</h3>
 * <p>To make it easy to format text in a label (changing colors, fonts, etc.),
 * label text can be provided in a simple markup format. Here's how to create a
 * label with a small font:
 * <pre>
 * label = new Label("");
 * label.setMarkup("<small>Small text</small>");
 * </pre>
 * (See complete documentation of available tags in the Pango manual.)
 * <p>The markup passed to setMarkup must be valid; for example, literal 
 * &lt;/&gt;/&amp; characters must be escaped as &amp;lt;, &amp;gt;, and 
 * &amp;amp;. If you pass text obtained from the user, file, or a network to 
 * setMarkup, you'll want to escape it with g_markup_escape_text().
 * <p>Markup strings are just a convenient way to set the PangoAttrList on a 
 * label; setAttributes may be a simpler way to set attributes in some cases. 
 * Be careful though; PangoAttrList tends to cause internationalization 
 * problems, unless you're applying attributes to the entire string . The 
 * reason is that specifying the startIndex and endIndex for a PangoAttribute 
 * requires knowledge of the exact string being displayed, so translations 
 * will cause problems.
 *
 * <h3>Selectable labels</h3>
 * <p>Labels can be made selectable with setSelectable. Selectable labels 
 * allow the user to copy the label contents to the clipboard. Only labels 
 * that contain useful-to-copy information - such as error messages - should 
 * be made selectable.
 * 
 * <h3>Text Layout</h3>
 * <p>A label can contain any number of paragraphs, but will have performance 
 * problems if it contains more than a small number. Paragraphs are separated 
 * by newlines or other paragraph separators understood by Pango.
 * <p>Labels can automatically wrap text if you call setLineWrap.
 * <p>setJustify sets how the lines in a label align with one another. If you 
 * want to set how the label as a whole aligns in its available space, see 
 * gtk.Misc.setAlignment.
 */
public class Label extends Misc {

	/**
	 * Creates a new label widget displaying the given caption. Mnemonic
	 * characters are not interpreted if this constructor is used.
	 * @param caption The default text to be displayed on the label
	 */
	public Label(String caption) {
		super(gtk_label_new(caption));
	}

	/**
	 * Creates a new label widget displaying the given caption. 
	 * @param caption The default text to be displayed on the label
	 * @param hasMnemonic If true, the caption is interpreted to have mnemonic
	 * characters. See the description for this class for more details.
	 */
	public Label(String caption, boolean hasMnemonic) {
		super(init(caption, hasMnemonic));
	}
	
	private static Handle init(String caption, boolean hasMnemonic) {
		if (hasMnemonic)
			return gtk_label_new_with_mnemonic(caption);
		else
			return gtk_label_new(caption);
	}

	/**
	 * Construct a label using a handle to a native resource.
	 */
	public Label(Handle handle) {
	    super(handle);
	}

	/**
	 * Changes the text to be displayed in the label widget.
	 * @param caption the new text to be displayed.
	 */
	public void setText(String caption) {
		gtk_label_set_text(getHandle(), caption);
	}

	/**
	 * Returns the text which is being displayed on this label.
	 * @return the text which is being displayed.
	 */
	public String getText() {
		return gtk_label_get_text(getHandle());
	}

	/**
	 * Sets a PangoAttrList; the attributes in the list are applied to the 
	 * label text. The attributes set with this function will be ignored if 
	 * Mnemonics or markup are being used.
	 * @param attributes Pange attrlist attributes to use
	 * @see org.gnu.pango.AttrList
	 */
	public void setAttributes(org.gnu.pango.AttrList attributes) {
		gtk_label_set_attributes(getHandle(), attributes.getHandle());
	}

	/**
	 * Gets the attribute list that was set on the label using setAttributes, 
	 * if any. This function does not reflect attributes that come from the 
	 * labels markup (see setMarkup). If you want to get the effective 
	 * attributes for the label, use pango.layout.getAttribute
	 * @return the Pango Attributes list
	 */
	public org.gnu.pango.AttrList getAttributes() {
		return (org.gnu.pango.AttrList) new org.gnu.glib.GObject(gtk_label_get_attributes(getHandle()));
	}

	/**
	 * Sets the text of the label.
	 * @param label The new text to set for the label
	 */
	public void setLabel(String label) {
		gtk_label_set_label(getHandle(), label);
	}

	/**
	 * Fetches the text from a label widget including any embedded underlines 
	 * indicating mnemonics and Pango markup.
	 * @return The entrie text of the label.
	 */
	public String getLabel() {
		return gtk_label_get_label(getHandle());
	}

	/**
	 * Parses <code>markup</code> which is marked up with the Pango text markup
	 * language, setting the label's text and attribute list based on the 
	 * parse results. The markup should not contain mnemonic characters if this
	 * method is used.
	 * @param markup String containg pango markup
	 */
	public void setMarkup(String markup) {
		gtk_label_set_markup(getHandle(), markup);
	}

	/**
	 * Parses <code>markup</code> which is marked up with the Pango text markup
	 * language, setting the label's text and attribute list based on the 
	 * parse results. 
	 * @param markup String containg pango markup
	 * @param hasMnemonic If True, the markup string will be interpreted to
	 * contain mnemonic characters, for use as keyboard accelerators
	 */
	public void setMarkup(String markup, boolean hasMnemonic) {
		if (hasMnemonic) {
			gtk_label_set_markup_with_mnemonic(getHandle(), markup);
		} else {
			gtk_label_set_markup(getHandle(), markup);
		}
	}

	/**
	 * Sets whether the text of the label contains markup in Pango's text 
	 * markup language.
	 * @see #setMarkup(String, boolean)
	 * @param setting TRUE if the label's text should be parsed for markup.
	 */
	public void setUseMarkup(boolean setting) {
		gtk_label_set_use_markup(getHandle(), setting);
	}

	/**
	 * Returns whether the label's text is interpreted as marked up with the
	 * Pango text markup language.
	 * @see #setUseMarkup(boolean)
	 * @return TRUE if the label's text will be parsed for markup.
	 */
	public boolean getUseMarkup() {
		return gtk_label_get_use_markup(getHandle());
	}

	/**
	 * Returns whether an embedded underline in the label indicates a mnemonic.
	 * @see #setUseMnemonic(boolean)
	 * @return Whether an embedded underline in the label indicates the 
	 * mnemonic accelerator keys.
	 */
	public boolean getUseMnemonic() {
		return gtk_label_get_use_underline(getHandle());
	}

	/**
	 * If true, an underline in the text indicates the next character should 
	 * be used for the mnemonic accelerator key.
	 * @param setting TRUE if underlines in the text indicate mnemonics
	 */
	public void setUseMnemonic(boolean setting) {
		gtk_label_set_use_underline(getHandle(), setting);
	}

	/**
	 * If the label has been set so that it has an mnemonic key,  the label can be 
	 * associated with a widget that is the target of the mnemonic. When the label 
	 * is inside a widget (like a Button or a Notebook tab) it is automatically 
	 * associated with the correct widget, but sometimes (i.e. when the target is 
	 * an Entry next to the label) you need to set it explicitly using this 
	 * function.
	 * <p>The target widget will be accelerated by emitting "mnemonic_activate"
	 * on it. The default handler for this signal will activate the widget if 
	 * there are no mnemonic collisions and toggle focus between the colliding 
	 * widgets otherwise.
	 * @param widget The target widget
	 */
	public void setMnemonicWidget(Widget widget) {
		gtk_label_set_mnemonic_widget(getHandle(), widget.getHandle());
	}

	/**
	 * Retrieves the target of the mnemonic (keyboard shortcut) of this label
	 * @return Target Widget
	 */
	public Widget getMnemonicWidget() {
	    Handle hndl = gtk_label_get_mnemonic_widget(getHandle());
		GObject obj = getGObjectFromHandle(hndl);
		if (null != obj)
			return (Widget)obj;
		return new Widget(hndl);
	}

	/**
	 * Sets the alignment of the lines in the text of the label relative to
	 * each other. Justification.LEFT is the default value when the widget 
	 * is first created. If you instead want to set the alignment of the 
	 * label as a whole, use Misc.setAlignment instead. setJustify has no 
	 * effect on labels containing only a single line.
	 */
	public void setJustification(Justification justification) {
		gtk_label_set_justify(getHandle(), justification.getValue());
	}

	/**
	 * Returns the justification of the label.
	 * @return the justification of the label
	 * @see #setJustification(Justification)
	 */
	public Justification getJustification() {
		return Justification.intern(gtk_label_get_justify(getHandle()));
	}

	/**
	 * The pattern of underlines you want under the existing text within the 
	 * Label widget. For example if the current text of the label says 
	 * "FooBarBaz" passing a pattern of "___ ___" will underline "Foo" and 
	 * "Baz" but not "Bar".
	 * @param pattern The pattern as described above.
	 */
	public void setUnderlinePattern(String pattern) {
		gtk_label_set_pattern(getHandle(), pattern);
	}

	/**
	 * Toggles line wrapping within the Label widget. TRUE makes it break 
	 * lines if text exceeds the widget's size. FALSE lets the text get cut 
	 * off by the edge of the widget if it exceeds the widget size.
	 * @param wrap New line wrap setting.
	 */
	public void setLineWrap(boolean wrap) {
		gtk_label_set_line_wrap(getHandle(), wrap);
	}

	/**
	 * Returns whether lines in the label are automatically wrapped.
	 * @return True if lines are automatically wrapped
	 */
	public boolean getLineWrap() {
		return gtk_label_get_line_wrap(getHandle());
	}

	/**
	 * Selectable labels allow the user to select text from the label, for copy-and-paste.
	 * @param setting TRUE to allow selecting text in the label
	 */
	public void setSelectable(boolean setting) {
		gtk_label_set_selectable(getHandle(), setting);
	}

	/**
	 * Gets the value set by setSelectable.
	 * @return TRUE if the user can copy text from the label.
	 */
	public boolean getSelectable() {
		return gtk_label_get_selectable(getHandle());
	}

	/**
	 * Selects a range of characters in the label, if the label is selectable. 
	 * If the label is not selectable, this function has no effect. If 
	 * startOffset or endOffset are -1, then the end of the label will be 
	 * substituted.
	 * @param startOffset The start offset in characters
	 * @param endOffset The end offset in characters
	 * @see #setSelectable(boolean)
	 */
	public void select(int startOffset, int endOffset) {
		gtk_label_select_region(getHandle(), startOffset, endOffset);
	}

	/**
	 * Returns true if any part of the label is selected
	 */
	public boolean getSelected() {
		int[] start = new int[1];
		int[] end = new int[1];
		return gtk_label_get_selection_bounds(getHandle(), start, end);
	}

	/**
	 * Returns the index of the start of the selected text. If the text is not
	 * selected, this returns -1; 
	 */
	public int getSelectionStart() {
		int[] start = new int[1];
		int[] end = new int[1];
		if (gtk_label_get_selection_bounds(getHandle(), start, end)) {
			return start[0];
		} else {
			return -1;
		}
	}
	/**
	 * Returns the index of the end of the selected test. If no text is
	 * selected, this returns -1.
	 */
	public int getSelectionEnd() {
		int[] start = new int[1];
		int[] end = new int[1];
		if (gtk_label_get_selection_bounds(getHandle(), start, end)) {
			return end[0];
		} else {
			return -1;
		}
	}

	/**
	 * Sets the desired width in characters of label to chars.
	 *
	 * @param chars the new desired width, in characters.
	 * @since 2.6 
	 */
	public void setWidthChars(int chars){
		gtk_label_set_width_chars(getHandle(), chars);
	}

	/**
	 * Retrieves the desired width of label, in characters. 
	 *
	 * @see #setWidthChars(int)
	 * @return the width of the label in characters.
	 * @since 2.6 
	 */
	public int getWidthChars(){
		return gtk_label_get_width_chars(getHandle());
	}

	/**
	 * Sets the desired maximum width in characters to chars.
	 *
	 * @param chars the new desired maximum width, in characters.
	 * @since 2.6 
	 */
	public void setMaxWidthChars(int chars){
		 gtk_label_set_max_width_chars(getHandle(), chars);
	}

	/** 
	 * Retrieves the desired maximum width of label, in characters. 
	 *
	 * @see #setMaxWidthChars(int)
	 * @return the maximum width of the label in characters.
	 * @since 2.6
	 */
	public int getMaxWidthChars(){
		return gtk_label_get_max_width_chars(getHandle());
	}

	/**
	 * Sets the angle of rotation for the label. An angle of 90 reads from from
	 * bottom to top, an angle of 270, from top to bottom. The angle setting for
	 * the label is ignored if the label is selectable, wrapped, or ellipsized.
	 *
	 * @param angle	the angle that the baseline of the label makes with the
	 * horizontal, in degrees, measured counterclockwise
	 *
	 * @since 2.6 
	 */
	public void setAngle(double angle){
		gtk_label_set_angle(getHandle(), angle);
	}

	/** 
	 * Gets the angle of rotation for the label. 
	 *
	 * @see #setAngle(double)
	 * @return	the angle of rotation for the label
	 * @since 2.6 
	 */
	public double getAngle(){
		return gtk_label_get_angle(getHandle());
	}
	
	/**
	 * Sets whether the label is in single line mode.
	 * @param singleLineMode true if the label should be in single line mode
	 * @since 2.6 
	 */
	public void setSingleLineMode(boolean singleLineMode){
		gtk_label_set_single_line_mode(getHandle(), singleLineMode);
	}

	/**
	 * Returns whether the label is in single line mode.
	 * @return true when the label is in single line mode.
	 * @since 2.6 
	 */
	public boolean getSingleLineMode(){
		return gtk_label_get_single_line_mode(getHandle());
	}

    /**
     * Sets the mode used to ellipsize (add an ellipsis: "...") the
     * text if there is not enough space to render the entire string.
     * @since 2.6 
     */
    public void setEllipsize( EllipsizeMode mode ) {
        gtk_label_set_ellipsize( getHandle(), mode.getValue() );
    }
    /**
     * Returns the ellipsizing position.
     * @since 2.6 
     */
    public EllipsizeMode getEllipsize() {
        return EllipsizeMode.intern( gtk_label_get_ellipsize( getHandle() ) );
    }
    
	/**
	 * Retrieve the runtime type used by the GLib library.
	 */
	public static Type getType() {
		return new Type(gtk_label_get_type());
	}


	native static final protected int gtk_label_get_type();
	native static final protected Handle gtk_label_new(String str);
	native static final protected Handle gtk_label_new_with_mnemonic(String str);
	native static final protected void gtk_label_set_text(Handle label, String str);
	native static final protected String gtk_label_get_text(Handle label);
	native static final protected void gtk_label_set_attributes(Handle label, Handle attrs);
	native static final protected Handle gtk_label_get_attributes(Handle label);
	native static final protected void gtk_label_set_label(Handle label, String str);
	native static final protected String gtk_label_get_label(Handle label);
	native static final protected void gtk_label_set_markup(Handle label, String str);
	native static final protected void gtk_label_set_use_markup(Handle label, boolean setting);
	native static final protected boolean gtk_label_get_use_markup(Handle label);
	native static final protected void gtk_label_set_use_underline(Handle label, boolean setting);
	native static final protected boolean gtk_label_get_use_underline(Handle label);
	native static final protected void gtk_label_set_markup_with_mnemonic(Handle label, String str);
	native static final protected int gtk_label_get_mnemonic_keyval(Handle label);
	native static final protected void gtk_label_set_mnemonic_widget(Handle label, Handle widget);
	native static final protected Handle gtk_label_get_mnemonic_widget(Handle label);
	native static final protected void gtk_label_set_text_with_mnemonic(Handle label, String str);
	native static final protected void gtk_label_set_justify(Handle label, int jtype);
	native static final protected int gtk_label_get_justify(Handle label);
	native static final protected void gtk_label_set_pattern(Handle label, String pattern);
	native static final protected void gtk_label_set_line_wrap(Handle label, boolean wrap);
	native static final protected boolean gtk_label_get_line_wrap(Handle label);
	native static final protected void gtk_label_set_selectable(Handle label, boolean setting);
	native static final protected boolean gtk_label_get_selectable(Handle label);
	native static final protected void gtk_label_select_region(Handle label, int startOffset, int endOffset);
	native static final protected boolean gtk_label_get_selection_bounds(Handle label, int[] start, int[] end);
	native static final protected Handle gtk_label_get_layout(Handle label);
	native static final protected void gtk_label_get_layout_offsets(int label, int[] x, int[] y);
	native static final private void gtk_label_set_width_chars(Handle label, int n_chars);
    native static final private int gtk_label_get_width_chars(Handle label);
    native static final private void gtk_label_set_max_width_chars(Handle label, int n_chars);
    native static final private int gtk_label_get_max_width_chars(Handle label);
    native static final private void gtk_label_set_angle(Handle label, double angle);
    native static final private double gtk_label_get_angle(Handle label);
    native static final private void gtk_label_set_single_line_mode(Handle label, boolean single_line_mode);
    native static final private boolean gtk_label_get_single_line_mode(Handle label);
    native static final private void gtk_label_set_ellipsize(Handle label, int mode);
    native static final private int gtk_label_get_ellipsize(Handle label);

    /* Deprecated functions.
    native static final private void gtk_label_get(Handle label, char** str);
    native static final private int gtk_label_parse_uline(Handle label, String string);
    */
}
