/*
 * 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.pango;
import org.gnu.glib.GObject;
import org.gnu.glib.Handle;
/** 
 * While complete access to the layout capabilities of Pango is provided using
 * the detailed interfaces for itemization and shaping, using that functionality
 * directly involves writing a fairly large amount of code. The objects and
 * functions in this structure provide a high-level driver for formatting entire
 * paragraphs of text at once.
 *
 * <p>The PangoLayout structure represents and entire paragraph of text. It is
 * initialized with a PangoContext, UTF-8 string and set of attributes for that
 * string. Once that is done, the set of formatted lines can be extracted from
 * the object, the layout can be rendered, and conversion between logical
 * character positions within the layout's text, and the physical position of
 * the resulting glyphs can be made.
 */
public class Layout extends GObject 
{
	
	/**
	 * Construct a new Layout with the given Context.
	 * 
	 * @param context The context to use for the Layout construction.
	 */
	public Layout(Context context) {
		super(Layout.pango_layout_new(context.getHandle()));
	}
	
	/**
	 * Construct a new Layout that is a copy of the provided Layout.
	 * @param layout
	 */
	public Layout(Layout layout) {
	    super(pango_layout_copy(layout.getHandle()));
	}
	
	/**
	 * Construct a new Layout with a handle that has been returned
	 * from a native call.
	 * 
	 * @param handle The handle to the native resource.
	 */
	public Layout(Handle handle) {
		super(handle);
	}
	
	/**
	 * Retrieve the Context used for this Layout.
	 */
	public Context getContext() {
	    return new Context(pango_layout_get_context(getHandle()));
	}
	
	/**
	 * Forces recomputation of any state in the Layout that might 
	 * depend on the layout's context. This method should be called 
	 * if you make changes to the context subsequent to creating 
	 * the layout
	 *
	 */
	public void contextChanged() {
	    pango_layout_context_changed(getHandle());
	}

	/**
	 * Set the text of the layout.
	 */
	public void setText(String text){
		pango_layout_set_text(getHandle(), text, text.length());
	}

	/**
	 * Gets the text in the layout.
	 */
	public String getText(){
		return pango_layout_get_text(getHandle());
	}

	/**
	 * Sets the layout text and attribute list from marked-up text (see markup
	 * format). Replaces the current text and attribute list.
	 *
	 * <p>If accelMarker is nonzero, the given character will mark the character
	 * following it as an accelerator. For example, the accel marker might be an
	 * ampersand or underscore. All characters marked as an accelerator will
	 * receive a {@link Underline#LOW} attribute. Two accelMarker characters
	 * following each other produce a single literal accelMarker character.
	 *
	 * @param markup some marked-up text
	 * @param accelMarker : marker for accelerators in the text
	 */
	public void setMarkup(String markup, char accelMarker){
		pango_layout_set_markup_with_accel(getHandle(), markup, markup.length(), (byte) accelMarker, (byte) '0');
	}

	/**
	 * Same as {@link #setMarkup(String, char)}, but the markup text isn't
	 * scanned for accelerators.
	 */
	public void setMarkup(String markup){
		pango_layout_set_markup(getHandle(), markup, markup.length());
	}


	/**
	 * Sets the text attributes for a layout object
	 */
	public void setAttributes(AttrList attributes){
		pango_layout_set_attributes(getHandle(), attributes.getHandle());
	}

	/**
	 * Gets the attribute list for the layout, if any
	 */
	public AttrList getAttributes(){
		return new AttrList( pango_layout_get_attributes (getHandle()) );
	}

	/**
	 * Set the default font description for the layout. If no font description
	 * is set on the layout, the font description from the layout's context is
	 * used.
	 */
	public void setFontDescription(FontDescription desc){
		pango_layout_set_font_description(getHandle(), desc.getHandle());
	}

	/**
	 * Sets the width to which the lines of the PangoLayout should be wrapped.
	 */
	public void setWidth(int width){
		pango_layout_set_width(getHandle(), width);
	}

	/**
	 * Gets the width to which the lines of the PangoLayout should be wrapped.
	 */
	public int getWidth(){
		return pango_layout_get_width(getHandle());
	}

	/**
	 * Sets the wrap style; the wrap style only has an effect if a width is set
	 * on the layout with {@link #setWidth(int)}To turn off wrapping, set
	 * the width to -1.
	 */
	public void setWrapStyle(WrapMode wrap){
		pango_layout_set_wrap(getHandle(), wrap.getValue());
	}

	/**
	 * Get the wrap mode for the layout.
	 */
	public WrapMode getWrapMode(){
		return WrapMode.intern( pango_layout_get_wrap(getHandle()) );
	}

	/**
	 * Sets the amount by which the first line should be shorter than the rest
	 * of the lines. This may be negative, in which case the subsequent lines
	 * will be shorter than the first line. (However, in either case, the entire
	 * width of the layout will be given by the value
	 */
	public void setIndent(int indent){
		pango_layout_set_indent(getHandle(), indent);
	}

	/**
	 * Gets the amount by which the first line should be shorter than the rest
	 * of the lines.
	 */
	public int getIndent(){
		return pango_layout_get_indent(getHandle());
	}

	/**
	 * Gets the amount of spacing between the lines of the layout.
	 * @return  the spacing (in thousandths of a device unit)
	 */
	public int getSpacing(){
		return pango_layout_get_spacing(getHandle());
	}

	/**
	 * Sets the amount of spacing between the lines of the layout.
	 */
	public void setSpacing(int spacing){
		pango_layout_set_spacing(getHandle(), spacing);
	}

	/**
	 * Sets whether or not each complete line should be stretched to fill the
	 * entire width of the layout. This stretching is typically done by adding
	 * whitespace, but for some scripts (such as Arabic), the justification is
	 * done by extending the characters.
	 */
	public void setJustification(boolean justify){
		pango_layout_set_justify(getHandle(), justify);
	}

	/**
	 * Gets whether or not each complete line should be stretched to fill the
	 * entire width of the layout.
	 */
	public boolean getJustified(){
		return pango_layout_get_justify(getHandle());
	}

	/**
	 * Sets the alignment for the layout (how partial lines are positioned
	 * within the horizontal space available.)
	 */
	public void setAlignment(Alignment alignment){
		pango_layout_set_alignment(getHandle(), alignment.getValue());
	}

	/**
	 * Gets the alignment for the layout (how partial lines are positioned
	 * within the horizontal space available.)
	 */
	public Alignment getAlignment(){
		return Alignment.intern( pango_layout_get_alignment(getHandle()) );
	}

	/**
	 * Sets the tabs to use for layout, overriding the default tabs (by default,
	 * tabs are every 8 spaces).
	 */
	public void setTabs(TabArray tabs){
		pango_layout_set_tabs(getHandle(), tabs.getHandle());
	}
	
	/**
	 * Retrieve the tabs used for this layout.
	 */
	public TabArray getTabs() {
	    return new TabArray(pango_layout_get_tabs(getHandle()));
	}

	/**
	 * If setting is TRUE, do not treat newlines and similar characters as
	 * paragraph separators; instead, keep all text in a single paragraph, and
	 * display a glyph for paragraph separator characters. Used when you want to
	 * allow editing of newlines on a single text line.
	 */
	public void setSingleParagraphMode(boolean setting){
		pango_layout_set_single_paragraph_mode(getHandle(), setting);
	}

	/**
	 * Obtains the value set by {@link #setSingleParagraphMode}.
	 */
	public boolean getSingleParagraphMode(){
		return pango_layout_get_single_paragraph_mode(getHandle());
	}

	/**
	 * Retrieve the count of lines for the layout
	 */
	public int getLineCount(){
		return pango_layout_get_line_count(getHandle());
	}

	/**
	 * Retrieves a particular line from a PangoLayout.
	 * @param line  the index of a line, which must be between 0 and
	 * pango_layout_get_line_count(layout) - 1, inclusive.
	 * @return  the requested PangoLayoutLine.
	 */
	public LayoutLine getLine(int line){
		return new LayoutLine(pango_layout_get_line(getHandle(), line));
	}
	
	/**
	 * Converts from an index within a Layout to the onscreen position 
	 * corresponding to the grapheme at that index, which is represented 
	 * as rectangle. Note that pos->x is always the leading edge of the 
	 * grapheme and pos->x + pos->width the trailing edge of the grapheme. 
	 * If the directionality of the grapheme is right-to-left, then 
	 * pos->width will be negative.
	 * @param index
	 */
	public Rectangle indexToPos(int index) {
	    Handle hndl = GObject.getNullHandle();
	    pango_layout_index_to_pos(getHandle(), index, hndl);
	    return new Rectangle(hndl);
	}
	
	/**
	 * Given an index within a layout, determines the positions that of the 
	 * strong cursor if the insertion point is at that index. The 
	 * position of each cursor is stored as a zero-width rectangle. The strong 
	 * cursor location is the location where characters of the directionality 
	 * equal to the base direction of the layout are inserted. 
	 * @param index
	 */
	public Rectangle getStrongCursorPosition(int index) {
	    Handle strong = GObject.getNullHandle();
	    Handle weak = GObject.getNullHandle();
	    pango_layout_get_cursor_pos(getHandle(), index, strong, weak);
	    if (strong.isNull())
	        return null;
	    return new Rectangle(strong);
	}
	
	/**
	 * Given an index within a layout, determines the positions that of the 
	 * weak cursor if the insertion point is at that index. The position 
	 * of each cursor is stored as a zero-width rectangle. The weak cursor 
	 * location is the location where characters of the directionality opposite 
	 * to the base direction of the layout are inserted.
	 * @param index
	 */
	public Rectangle getWeakCursorPosition(int index) {
	    Handle strong = GObject.getNullHandle();
	    Handle weak = GObject.getNullHandle();
	    pango_layout_get_cursor_pos(getHandle(), index, strong, weak);
	    if (weak.isNull())
	        return null;
	    return new Rectangle(weak);
	}
	
	/**
	 * Return the logical height of the Layout in Pango units.
	 */
	public int getHeight() {
	    int[] width = new int[1];
	    int[] height = new int[1];
	    pango_layout_get_size(getHandle(), width, height);
	    return height[0];
	}
	
	/**
	 * Return the logical width of the Layout in device units.
	 */
	public int getPixelWidth() {
	    int[] width = new int[1];
	    int[] height = new int[1];
	    pango_layout_get_pixel_size(getHandle(), width, height);
	    return width[0];
	}

	/**
	 * Return the logical height of the Layout in device units.
	 */
	public int getPixelHeight() {
	    int[] width = new int[1];
	    int[] height = new int[1];
	    pango_layout_get_pixel_size(getHandle(), width, height);
	    return height[0];
	}

	 
    native static final protected int pango_layout_get_type ();
    native static final protected Handle pango_layout_new (Handle context);
    native static final protected Handle pango_layout_copy (Handle src);
    native static final protected Handle pango_layout_get_context (Handle layout);
    native static final protected void pango_layout_set_attributes (Handle layout, Handle attrs);
    native static final protected Handle pango_layout_get_attributes (Handle layout);
    native static final protected void pango_layout_set_text (Handle layout, String text, int length);
    native static final protected String pango_layout_get_text (Handle layout);
    native static final protected void pango_layout_set_markup (Handle layout, String markup, int length);
    native static final protected void pango_layout_set_markup_with_accel (Handle layout, String 
        markup, int length, byte accelMarker, byte accelChar);
    native static final protected void pango_layout_set_font_description (Handle layout, Handle desc);
    native static final protected void pango_layout_set_width (Handle layout, int width);
    native static final protected int pango_layout_get_width (Handle layout);
    native static final protected void pango_layout_set_wrap (Handle layout, int wrap);
    native static final protected int pango_layout_get_wrap (Handle layout);
    native static final protected void pango_layout_set_indent (Handle layout, int indent);
    native static final protected int pango_layout_get_indent (Handle layout);
    native static final protected void pango_layout_set_spacing (Handle layout, int spacing);
    native static final protected int pango_layout_get_spacing (Handle layout);
    native static final protected void pango_layout_set_justify (Handle layout, boolean justify);
    native static final protected boolean pango_layout_get_justify (Handle layout);
    native static final protected void pango_layout_set_alignment (Handle layout, int alignment);
    native static final protected int pango_layout_get_alignment (Handle layout);
    native static final protected void pango_layout_set_tabs (Handle layout, Handle tabs);
    native static final protected Handle pango_layout_get_tabs (Handle layout);
    native static final protected void pango_layout_set_single_paragraph_mode (Handle layout, boolean setting);
    native static final protected boolean pango_layout_get_single_paragraph_mode (Handle layout);
    native static final protected void pango_layout_context_changed (Handle layout);
    native static final protected void pango_layout_index_to_pos (Handle layout, int index, Handle pos);
    native static final protected void pango_layout_get_cursor_pos (Handle layout, int index, Handle 
        strongPos, Handle weakPos);
    native static final protected void pango_layout_move_cursor_visually (Handle layout, boolean 
        strong, int oldIndex, int oldTrailing, int direction, int [] newIndex, int [] newTrailing);
    native static final protected boolean pango_layout_xy_to_index (Handle layout, int x, int y, int []
        index, int [] trailing);
    native static final protected void pango_layout_get_extents (Handle layout, Handle inkRect, Handle logicalRect);
    native static final protected void pango_layout_get_pixel_extents (Handle layout, Handle inkRect, Handle logicalRect);
    native static final protected void pango_layout_get_size (Handle layout, int [] width, int [] height);
    native static final protected void pango_layout_get_pixel_size (Handle layout, int [] width, int [] height);
    native static final protected int pango_layout_get_line_count (Handle layout);
    native static final protected Handle pango_layout_get_line (Handle layout, int line);

}

