/*******************************************************************************
 * Copyright (c) 2000, 2010 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.draw2d.text;

import java.util.List;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.draw2d.rap.swt.SWT;

/**
 * A <code>FlowFigure</code> represented by a single {@link BlockBox} containing
 * one or more lines. A BlockFlow is a creator of LineBoxes, which its children
 * require during layout. A BlockFlow can be thought of as a foundation for a
 * paragraph.
 * <P>
 * BlockFlows must be parented by a <code>FlowFigure</code>. {@link FlowPage}
 * can be used as a "root" block and can be parented by normal Figures.
 * <P>
 * Only {@link FlowFigure}s can be added to a BlockFlow.
 * <P>
 * WARNING: This class is not intended to be subclassed by clients.
 * 
 * @author hudsonr
 * @since 2.1
 */
public class BlockFlow extends FlowFigure {

	private final BlockBox blockBox;
	private int alignment = PositionConstants.NONE;
	private int orientation = SWT.NONE;
	private boolean bidiValid;

	/**
	 * Constructs a new BlockFlow.
	 */
	public BlockFlow() {
		blockBox = createBlockBox();
	}

	/**
	 * BlockFlows contribute a paragraph separator so as to keep the Bidi state
	 * of the text on either side of this block from affecting each other. Since
	 * each block is like a different paragraph, it does not contribute any
	 * actual text to its containing block.
	 * 
	 * @see org.eclipse.draw2d.text.FlowFigure#contributeBidi(org.eclipse.draw2d.text.BidiProcessor)
	 */
	protected void contributeBidi(BidiProcessor proc) {
		proc.addControlChar(BidiChars.P_SEP);
	}

	BlockBox createBlockBox() {
		return new BlockBox(this);
	}

	/**
	 * @see org.eclipse.draw2d.text.FlowFigure#createDefaultFlowLayout()
	 */
	protected FlowFigureLayout createDefaultFlowLayout() {
		return new BlockFlowLayout(this);
	}

	/**
	 * Returns the BlockBox associated with this.
	 * 
	 * @return This BlockFlow's BlockBox
	 */
	protected BlockBox getBlockBox() {
		return blockBox;
	}

	int getBottomMargin() {
		int margin = 0;
		if (getBorder() instanceof FlowBorder) {
			FlowBorder border = (FlowBorder) getBorder();
			return border.getBottomMargin();
		}
		List children = getChildren();
		int childIndex = children.size() - 1;
		if (childIndex >= 0 && children.get(childIndex) instanceof BlockFlow) {
			margin = Math.max(margin,
					((BlockFlow) children.get(childIndex)).getBottomMargin());
		}
		return margin;
	}

	/**
	 * Returns the effective horizontal alignment. This method will never return
	 * {@link PositionConstants#NONE}. If the value is none, it will return the
	 * inherited alignment. If no alignment was inherited, it will return the
	 * default alignment ({@link PositionConstants#LEFT}).
	 * 
	 * @return the effective alignment
	 */
	public int getHorizontalAligment() {
		if (alignment != PositionConstants.NONE)
			return alignment;
		IFigure parent = getParent();
		while (parent != null && !(parent instanceof BlockFlow))
			parent = parent.getParent();
		if (parent != null)
			return ((BlockFlow) parent).getHorizontalAligment();
		return PositionConstants.LEFT;
	}

	int getLeftMargin() {
		if (getBorder() instanceof FlowBorder)
			return ((FlowBorder) getBorder()).getLeftMargin();
		return 0;
	}

	/**
	 * Returns the orientation set on this block.
	 * 
	 * @return LTR, RTL or NONE
	 * @see #setOrientation(int)
	 * @since 3.1
	 */
	public int getLocalOrientation() {
		return orientation;
	}

	/**
	 * Returns the horizontal alignment set on this block.
	 * 
	 * @return LEFT, RIGHT, ALWAYS_LEFT, ALWAYS_RIGHT, NONE
	 * @see #setHorizontalAligment(int)
	 * @since 3.1
	 */
	public int getLocalHorizontalAlignment() {
		return alignment;
	}

	/**
	 * Returns this block's Bidi orientation. If none was set on this block, it
	 * will inherit the one from its containing block. If there is no containing
	 * block, it will return the default orientation (SWT.RIGHT_TO_LEFT if
	 * mirrored; SWT.LEFT_TO_RIGHT otherwise).
	 * 
	 * @return SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT
	 * @see #setOrientation(int)
	 * @since 3.1
	 */
	public int getOrientation() {
		if (orientation != SWT.NONE)
			return orientation;
		IFigure parent = getParent();
		while (parent != null && !(parent instanceof BlockFlow))
			parent = parent.getParent();
		if (parent != null)
			return ((BlockFlow) parent).getOrientation();
		return isMirrored() ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT;
	}

	int getRightMargin() {
		if (getBorder() instanceof FlowBorder)
			return ((FlowBorder) getBorder()).getRightMargin();
		return 0;
	}

	int getTopMargin() {
		int margin = 0;
		if (getBorder() instanceof FlowBorder) {
			FlowBorder border = (FlowBorder) getBorder();
			return border.getTopMargin();
		}
		List children = getChildren();
		if (children.size() > 0 && children.get(0) instanceof BlockFlow) {
			margin = Math.max(margin,
					((BlockFlow) children.get(0)).getTopMargin());
		}
		return margin;
	}

	/**
	 * @see org.eclipse.draw2d.Figure#paintBorder(org.eclipse.draw2d.Graphics)
	 */
	public void paintBorder(Graphics graphics) {
		if (getBorder() instanceof FlowBorder) {
			Rectangle where = getBlockBox().toRectangle();
			where.crop(new Insets(getTopMargin(), getLeftMargin(),
					getBottomMargin(), getRightMargin()));
			((FlowBorder) getBorder()).paint(this, graphics, where, SWT.LEAD
					| SWT.TRAIL);
		} else
			super.paintBorder(graphics);
		if (selectionStart != -1) {
			graphics.restoreState();
			graphics.setXORMode(true);
			graphics.setBackgroundColor(ColorConstants.white);
			graphics.fillRectangle(getBounds());
		}
	}

	/**
	 * @see org.eclipse.draw2d.text.FlowFigure#postValidate()
	 */
	public void postValidate() {
		Rectangle newBounds = getBlockBox().toRectangle();
		newBounds.crop(new Insets(getTopMargin(), getLeftMargin(),
				getBottomMargin(), getRightMargin()));
		setBounds(newBounds);
	}

	/**
	 * @see FlowFigure#revalidate()
	 */
	public void revalidate() {
		BlockFlowLayout layout = (BlockFlowLayout) getLayoutManager();
		layout.blockContentsChanged();
		super.revalidate();
	}

	/**
	 * A Block will invalidate the Bidi state of all its children, so that it is
	 * re-evaluated when this block is next validated.
	 * 
	 * @see org.eclipse.draw2d.text.FlowFigure#revalidateBidi(org.eclipse.draw2d.IFigure)
	 */
	protected void revalidateBidi(IFigure origin) {
		if (bidiValid) {
			bidiValid = false;
			revalidate();
		}
	}

	/**
	 * Sets the horitontal aligment of the block. Valid values are:
	 * <UL>
	 * <LI>{@link PositionConstants#NONE NONE} - (default) Alignment is
	 * inherited from parent. If a parent is not found then LEFT is used.</LI>
	 * <LI>{@link PositionConstants#LEFT} - Alignment is with leading edge</LI>
	 * <LI>{@link PositionConstants#RIGHT} - Alignment is with trailing edge</LI>
	 * <LI>{@link PositionConstants#CENTER}</LI>
	 * <LI>{@link PositionConstants#ALWAYS_LEFT} - Left, irrespective of
	 * orientation</LI>
	 * <LI>{@link PositionConstants#ALWAYS_RIGHT} - Right, irrespective of
	 * orientation</LI>
	 * </UL>
	 * 
	 * @param value
	 *            the aligment
	 * @see #getHorizontalAligment()
	 */
	public void setHorizontalAligment(int value) {
		value &= PositionConstants.LEFT | PositionConstants.CENTER
				| PositionConstants.RIGHT | PositionConstants.ALWAYS_LEFT
				| PositionConstants.ALWAYS_RIGHT;
		if (value == alignment)
			return;
		alignment = value;
		revalidate();
	}

	/**
	 * Sets the orientation for this block. Orientation can be one of:
	 * <UL>
	 * <LI>{@link SWT#LEFT_TO_RIGHT}
	 * <LI>{@link SWT#RIGHT_TO_LEFT}
	 * <LI>{@link SWT#NONE} (default)
	 * </UL>
	 * <code>NONE</code> is used to indicate that orientation should be
	 * inherited from the encompassing block.
	 * 
	 * @param orientation
	 *            LTR, RTL or NONE
	 * @see #getOrientation()
	 * @since 3.1
	 */
	public void setOrientation(int orientation) {
		orientation &= SWT.LEFT_TO_RIGHT | SWT.RIGHT_TO_LEFT;
		if (this.orientation == orientation)
			return;
		this.orientation = orientation;
		revalidateBidi(this);
	}

	/**
	 * @see org.eclipse.draw2d.Figure#useLocalCoordinates()
	 */
	protected boolean useLocalCoordinates() {
		return true;
	}

	/**
	 * Re-evaluate the Bidi state of all the fragments if it has been
	 * invalidated.
	 * 
	 * @see org.eclipse.draw2d.IFigure#validate()
	 */
	public void validate() {
		if (!bidiValid) {
			BidiProcessor.INSTANCE.setOrientation(getOrientation());
			if (getOrientation() == SWT.LEFT_TO_RIGHT && isMirrored())
				BidiProcessor.INSTANCE.addControlChar(BidiChars.LRE);
			super.contributeBidi(BidiProcessor.INSTANCE);
			BidiProcessor.INSTANCE.process();
			bidiValid = true;
		}
		super.validate();
	}

}