/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.css2.layout;

import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.geometry.Insets;

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

	BlockBox _blockBox;

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

	/**
	 * @see FlowContainerLayout#cleanup()
	 */
	protected void cleanup() {
		_currentLine = _previousLine = null;
	}

	/**
	 * @see FlowContainerLayout#createNewLine()
	 */
	protected void createNewLine() {
		_currentLine = new LineBox();
		setupLine(_currentLine, Integer.MIN_VALUE);
	}

	protected void createNewLine(int topmargin) {
		_currentLine = new LineBox();
		setupLine(_currentLine, topmargin);
	}

	/**
	 * Override to setup the line's x, remaining, and available width.
	 * 
	 * @param line
	 *            the LineBox to set up
	 */
	protected void setupLine(LineBox line, int topMargin) {
		line.clear();

		// the caller of getCurrentLine() may add leftMargin and leftPadding and
		// leftBorder to line.x
		line._x = 0;

		// FIXME: here should check the floating boxes, and minus the width of
		// them from
		// current line.
		line.setRecommendedWidth(_blockBox.getRecommendedContentWidth());
		if (_previousLine == null) {
			line._y = 0;
			if (topMargin != Integer.MIN_VALUE) {
				line._y += topMargin;
			}
		} else {
			if (topMargin == Integer.MIN_VALUE) {
				line._y = _previousLine._y + _previousLine.getHeight()
						+ getLinePadding() + _previousLine._marginInsets.bottom; // XXX:
				// should
				// add
				// previous
				// margin
				// bottom?
			} else {
				line._y = _previousLine._y
						+ _previousLine.getHeight()
						+ Math.max(topMargin,
								_previousLine._marginInsets.bottom);
			}
		}
		// line.validate();
	}

	/**
	 * Called by flush(), adds the BlockBox associated with this BlockFlowLayout
	 * to the current line and then ends the line.
	 */
	protected void endBlock() {
		getFlowContext().addToCurrentLine(_blockBox);

		// FIXME: here should tell the context the bottom margin.
		getFlowContext().endLine();
	}

	/**
	 * @see FlowContext#endLine()
	 */
	public void endLine() {
		// this is called from child layouts.
		// If there is no current line, state is equivalent to new line
		if (_currentLine == null) {
			return;
		}
		if (_currentLine.isOccupied()) {
			layoutLine(); // finalize the current line layout
		} else {
			_currentLine = null;
			return;
		}
		LineBox box = _currentLine;
		_previousLine = box;
		_currentLine = null;// _previousLine; //XXX: ???? why (yang)

		// setupLine(getCurrentLine());
	}

	/**
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentY()
	 */
	public int getCurrentY() {
		return getCurrentLine()._y; // FIXME: margin of previous block?
	}

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

	/**
	 * Adjust all fragments in the current line to have the same baseline. Do
	 * any additional adjustments, such as horizontal alignment.
	 */
	protected void layoutLine() {
		// currentLine.x = 0; //XXX: comment out, don't understand why set to 0,
		// because it has already
		// been set when setupLine(). And if do need, should
		// set to getBorderPaddingInsets().left
		switch (getBlockFlow().getHorizontalAligment()) {
		case PositionConstants.RIGHT:
			_currentLine._x = _blockBox.getContentWidth()
					- getBorderPaddingInsets().right - _currentLine.getWidth();
			break;
		case PositionConstants.CENTER:
			_currentLine._x = (_blockBox.getContentWidth()
					+ getBorderPaddingInsets().left
					- getBorderPaddingInsets().right - _currentLine.getWidth()) / 2;
			break;
		}
		// FIXME: should check vertical alignment here?
		_currentLine.commit();
		_blockBox.add(_currentLine);
	}

	/**
	 * @see FlowContainerLayout#flush()
	 */
	protected void flush() {
		if (_currentLine != null)
			layoutLine();
		endBlock();
	}

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

	/**
	 * sets up the single block that contains all of the lines.
	 */
	protected void setupBlock() {
		// Ask for a new line, in case we are in the middle of a line

		// FIXME: the endLine() should tell context the top margin of this
		// block.
		getFlowContext().endLine();

		LineBox line = getFlowContext().getCurrentLine();
		// int recommended = line.getAvailableWidth();
		// if (recommended != previousRecommendedWidth)
		// Remove all current Fragments
		_blockBox.clear();

		// Setup the one fragment for this Block with the correct X and
		// available width

		// FIXME: here should check whether the CSS already set recommended
		// width for this
		// block.
		_blockBox.setRecommendedWidth(line.getAvailableWidth());

		_blockBox._y = getFlowContext().getCurrentY();

		// FIXME: blockBox.x should be context.getBorderPaddingInsets().left
		// or just line.x ?
		_blockBox._x = 0;
	}

	Insets getBorderPaddingInsets() {
		// FIXME:
		return new Insets();
	}

	int getLinePadding() {
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#dispose()
	 */
	public void dispose() {
        // TODO: anything to dispose?
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getContainerWidth()
	 */
	public int getContainerWidth() {
		int width = Math.max(0, Math.max(_blockBox.getWidth(), _blockBox
				.getRecommendedWidth()));
		return width;
	}
}
