/*******************************************************************************
 * 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.Figure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.rap.swt.SWT;

/**
 * The layout for {@link BlockFlow} figures.
 * 
 * <P>
 * WARNING: This class is not intended to be subclassed by clients.
 * 
 * @author hudsonr
 * @since 2.1
 */
public class BlockFlowLayout extends FlowContainerLayout {

	BlockBox blockBox;
	boolean blockInvalid = false;
	private boolean continueOnSameLine = false;
	private CompositeBox previousLine = null;

	/**
	 * Creates a new BlockFlowLayout with the given BlockFlow.
	 * 
	 * @param blockFlow
	 *            the BlockFlow
	 */
	public BlockFlowLayout(BlockFlow blockFlow) {
		super(blockFlow);
	}

	private void addBelowPreviousLine(CompositeBox line) {
		if (previousLine == null)
			line.setLineTop(line.getTopMargin());
		else
			line.setLineTop(previousLine.getBaseline()
					+ previousLine.getDescent()
					+ Math.max(previousLine.getBottomMargin(),
							line.getTopMargin()));

		int alignment = getBlockFlow().getHorizontalAligment();
		if (alignment == PositionConstants.LEFT
				|| alignment == PositionConstants.RIGHT) {
			int orientation = getBlockFlow().getOrientation();
			if (alignment == PositionConstants.LEFT)
				alignment = orientation == SWT.LEFT_TO_RIGHT ? PositionConstants.ALWAYS_LEFT
						: PositionConstants.ALWAYS_RIGHT;
			else
				alignment = orientation == SWT.LEFT_TO_RIGHT ? PositionConstants.ALWAYS_RIGHT
						: PositionConstants.ALWAYS_LEFT;
		}
		if (alignment != PositionConstants.CENTER
				&& getBlockFlow().isMirrored())
			alignment = (PositionConstants.ALWAYS_LEFT | PositionConstants.ALWAYS_RIGHT)
					& ~alignment;

		switch (alignment) {
		case PositionConstants.ALWAYS_RIGHT:
			line.setX(blockBox.getRecommendedWidth() - line.getWidth());
			break;
		case PositionConstants.CENTER:
			line.setX((blockBox.getRecommendedWidth() - line.getWidth()) / 2);
			break;
		case PositionConstants.ALWAYS_LEFT:
			line.setX(0);
			break;
		default:
			throw new RuntimeException("Unexpected state"); //$NON-NLS-1$
		}
		blockBox.add(line);
		previousLine = line;
	}

	/**
	 * Align the line horizontally and then commit it.
	 */
	protected void addCurrentLine() {
		addBelowPreviousLine(currentLine);
		((LineRoot) currentLine).commit();
	}

	/**
	 * @see FlowContext#addLine(CompositeBox)
	 */
	public void addLine(CompositeBox box) {
		endLine();
		addBelowPreviousLine(box);
	}

	/**
	 * Marks the blocks contents as changed. This means that children will be
	 * invalidated during validation.
	 * 
	 * @since 3.1
	 */
	public void blockContentsChanged() {
		blockInvalid = true;
	}

	/**
	 * @see FlowContainerLayout#cleanup()
	 */
	protected void cleanup() {
		super.cleanup();
		previousLine = null;
	}

	/**
	 * @see FlowContainerLayout#createNewLine()
	 */
	protected void createNewLine() {
		currentLine = new LineRoot(getBlockFlow().isMirrored());
		currentLine.setRecommendedWidth(blockBox.getRecommendedWidth());
	}

	/**
	 * Called by flush(), adds the BlockBox associated with this BlockFlowLayout
	 * to the current line and then ends the line.
	 */
	protected void endBlock() {
		if (blockInvalid) {
			Insets insets = getBlockFlow().getInsets();
			blockBox.height += insets.getHeight();
			blockBox.width += insets.getWidth();
		}

		if (getContext() != null)
			getContext().addLine(blockBox);

		if (blockInvalid) {
			blockInvalid = false;
			List v = getFlowFigure().getChildren();
			for (int i = 0; i < v.size(); i++)
				((FlowFigure) v.get(i)).postValidate();
		}
	}

	/**
	 * @see FlowContext#endLine()
	 */
	public void endLine() {
		if (currentLine == null || !currentLine.isOccupied())
			return;
		addCurrentLine();
		currentLine = null;
	}

	/**
	 * @see FlowContainerLayout#flush()
	 */
	protected void flush() {
		endLine();
		endBlock();
	}

	boolean forceChildInvalidation(Figure f) {
		return blockInvalid;
	}

	/**
	 * Returns the BlockFlow associated with this BlockFlowLayout
	 * 
	 * @return the BlockFlow
	 */
	protected final BlockFlow getBlockFlow() {
		return (BlockFlow) getFlowFigure();
	}

	int getContextWidth() {
		return getContext().getRemainingLineWidth();
	}

	/**
	 * @see FlowContext#getContinueOnSameLine()
	 */
	public boolean getContinueOnSameLine() {
		return continueOnSameLine;
	}

	/**
	 * @see FlowContext#getWidthLookahead(FlowFigure, int[])
	 */
	public void getWidthLookahead(FlowFigure child, int result[]) {
		List children = getFlowFigure().getChildren();
		int index = -1;
		if (child != null)
			index = children.indexOf(child);

		for (int i = index + 1; i < children.size(); i++)
			if (((FlowFigure) children.get(i))
					.addLeadingWordRequirements(result))
				return;
	}

	/**
	 * @see FlowContainerLayout#preLayout()
	 */
	protected void preLayout() {
		setContinueOnSameLine(false);
		blockBox = getBlockFlow().getBlockBox();
		setupBlock();
		// Probably could setup current and previous line here, or just previous
	}

	/**
	 * @see org.eclipse.draw2d.text.FlowContext#setContinueOnSameLine(boolean)
	 */
	public void setContinueOnSameLine(boolean value) {
		continueOnSameLine = value;
	}

	/**
	 * sets up the single block that contains all of the lines.
	 */
	protected void setupBlock() {
		int recommended = getContextWidth();
		if (recommended == Integer.MAX_VALUE)
			recommended = -1;
		BlockFlow bf = getBlockFlow();
		if (recommended > 0) {
			int borderCorrection = bf.getInsets().getWidth()
					+ bf.getLeftMargin() + bf.getRightMargin();
			recommended = Math.max(0, recommended - borderCorrection);
		}

		if (recommended != blockBox.recommendedWidth) {
			blockInvalid = true;
			blockBox.setRecommendedWidth(recommended);
		}

		if (blockInvalid) {
			blockBox.height = 0;
			blockBox.setWidth(Math.max(0, recommended));
		}
	}

}