/*******************************************************************************
 * 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.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() ? org.eclipse.draw2d.rap.swt.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 | org.eclipse.draw2d.rap.swt.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();
	}

}