/*******************************************************************************
 * 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 java.util.List;

import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
import org.eclipse.jst.pagedesigner.css2.property.ICSSPropertyID;
import org.eclipse.jst.pagedesigner.css2.property.PositionMeta;
import org.eclipse.jst.pagedesigner.css2.property.VerticalAlignMeta;
import org.eclipse.jst.pagedesigner.css2.value.Length;

/**
 * CSSLayout is the base layout manager for different CSS layouts, such as block
 * layout, inline layout (possible in the future table layout, etc)
 * 
 * @author mengbo
 */
public abstract class CSSLayout extends FlowFigureLayout implements FlowContext {
	protected BlockFlowContext _absoluteContext;

	// when doing absolute layout, and if top/left are both "auto", it will be
	// relating to the normaly flow position. The following two fields try to
	// catch normal flow layout position.
	// int _xForAbsolute;
	// int _yForAbsolute;
	private FlowBox _boxForAbsolute;

	/**
	 * the current line
	 */
	protected LineBox _currentLine;

	private boolean _calculatingMaxWidth = false;

	/**
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#FlowFigureLayout(FlowFigure)
	 */
	protected CSSLayout(CSSFigure flowFigure) {
		super(flowFigure);
	}

	/**
	 * a shortcut method to get the style associated with the figure.
	 * 
	 * @return
	 */
	public ICSSStyle getCSSStyle() {
		return getCSSFigure().getCSSStyle();
	}

	/**
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#addToCurrentLine(FlowBox)
	 */
	public void addToCurrentLine(FlowBox block) {
		getCurrentLine().add(block);
	}

	/**
	 * Used by getCurrentLine().
	 */
	protected abstract void createNewLine();

	/**
	 * Used by getCurrentLine(int topmargin)
	 * 
	 * @param topMargin
	 */
	protected void createNewLine(int topMargin) {
		createNewLine();
	}

	/**
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentLine()
	 */
	public LineBox getCurrentLine() {
		if (_currentLine == null) {
			createNewLine();
		}
		return _currentLine;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getCurrentLine(int)
	 */
	public LineBox getCurrentLine(int topMargin) {
		if (_currentLine == null) {
			createNewLine(topMargin);
		}
		// if the current line only contains an empty string, reset the current
		// line using the given margin.
		else if (_currentLine.isEmptyStringLine()) {
			List list = _currentLine.getFragments();
			createNewLine(topMargin);
			_currentLine._fragments.addAll(list);
		}
		return _currentLine;
	}

	/**
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#isCurrentLineOccupied
	 */
	public boolean isCurrentLineOccupied() {
		return _currentLine != null && _currentLine.isOccupied();
	}

	/**
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#layout()
	 */
	protected void layout() {
		preLayout();
		layoutChildren();
		flush();
		cleanup();
	}

	protected boolean isAbsolutePosition() {
		ICSSStyle style = getCSSStyle();

		// FIXME: Some layout don't support absolute, need check here
		if (style != null) {
			Object obj = style.getStyleProperty(ICSSPropertyID.ATTR_POSITION);
			if (PositionMeta.ABSOLUTE.equals(obj)
					|| PositionMeta.FIXED.equals(obj)) {
				return supportAbsolutePosition();
			}
		}
		return false;
	}

	/**
	 * Child class could override this method.
	 * 
	 * @return
	 */
	protected boolean supportAbsolutePosition() {
		if (findContainingPositionedFigure() == null) {
			return false;
		}
		return true;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContainerLayout#preLayout()
	 */
	protected void preLayout() {
		ICSSStyle style = this.getCSSStyle();
		if (style != null) {
			style.processCounters();
		}

		if (isAbsolutePosition()) {
			FlowContext parentFigureContext = getParentFigureContext();
			_absoluteContext = new BlockFlowContext(parentFigureContext, style);
			_boxForAbsolute = new FlowBox();// size is 0. Just as a flag, so
			// later we
			// could figure out where will this figure be
			// be put in case of not absolute
			_boxForAbsolute.setVerticalAlignData(VerticalAlignMeta.TOP);
			parentFigureContext.addToCurrentLine(_boxForAbsolute);
		} else {
			_absoluteContext = null;
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowFigureLayout#getFlowContext()
	 */
	public FlowContext getFlowContext() {
		if (_absoluteContext != null) {
			return _absoluteContext;
		}
        return getOriginalFlowContext();
	}

	public FlowContext getParentFigureContext() {
		return super.getFlowContext();
	}

	public void postValidateForAbsolute() {
		if (_absoluteContext != null) {
			ICSSStyle style = this.getCSSStyle();

			_absoluteContext.endBlock();

			int xOffset;
			int yOffset;

			ICSSFigure containingPositionedFigure = findContainingPositionedFigure();
			IFigure parentFigure = this.getCSSFigure().getParent();

			xOffset = calculatePositionRelativeToParent(style,
					containingPositionedFigure, parentFigure, true);
			yOffset = calculatePositionRelativeToParent(style,
					containingPositionedFigure, parentFigure, false);
			move(_absoluteContext._blockBox, xOffset, yOffset);
		}
	}

	/**
	 * @param style
	 * @param containingPositionedFigure
	 * @param parentFigure
	 * @return
	 */
	private int calculatePositionRelativeToParent(ICSSStyle style,
			ICSSFigure containingPositionedFigure, IFigure parentFigure,
			boolean horizontal) {
		int xOffset;
		Object left = horizontal ? style
				.getStyleProperty(ICSSPropertyID.ATTR_LEFT) : style
				.getStyleProperty(ICSSPropertyID.ATTR_TOP);
		Object right = horizontal ? style
				.getStyleProperty(ICSSPropertyID.ATTR_RIGHT) : style
				.getStyleProperty(ICSSPropertyID.ATTR_BOTTOM);

		if (!(left instanceof Length) && !(right instanceof Length)) {
			// _boxForAbsolute partipated the layout of the parent figure, and
			// is already relative to parent.
			return horizontal ? _boxForAbsolute._x : _boxForAbsolute._y;
		}

		// ok, user specified left or right. let's calculate the left
		int leftValue;
		if (left instanceof Length) {
			Length leftLength = (Length) left;
			leftValue = leftLength.getValue();
			if (leftLength.isPercentage()) {
				leftValue = (horizontal ? containingPositionedFigure
						.getBounds().width : containingPositionedFigure
						.getBounds().height)
						* leftValue / 100;
			}
		} else {
			Length rightLength = (Length) right;
			int lengthValue = rightLength.getValue();
			if (rightLength.isPercentage()) {
				lengthValue = (horizontal ? containingPositionedFigure
						.getBounds().width : containingPositionedFigure
						.getBounds().height)
						* lengthValue / 100;
			}

			if (horizontal) {
				leftValue = containingPositionedFigure.getBounds().width
						- _absoluteContext._blockBox.getWidth() - lengthValue;
			} else {
				leftValue = containingPositionedFigure.getBounds().height
						- _absoluteContext._blockBox.getHeight() - lengthValue;
			}

		}

		// xOffset is relative to the first box of the containing figure
		List fragments = containingPositionedFigure
				.getFragmentsForRead();
		if (fragments.size() > 0) {
			FlowBox box = (FlowBox) fragments.get(0);
			// box._x is the x location relative to containingPositionedFigure's
			// parent.
			// so now xOffset is relative to containingPositionedFigure's
			// parent.
			xOffset = (horizontal ? box._x : box._y) + leftValue;
		} else {
			xOffset = leftValue; // should not happen.
		}
		Point p;
		if (horizontal) {
			p = new Point(xOffset, 0);
		} else {
			p = new Point(0, xOffset);
		}
		containingPositionedFigure.translateFromParent(p);
		containingPositionedFigure.translateToAbsolute(p);
		parentFigure.translateToRelative(p);
		return horizontal ? p.x : p.y;
	}

	/**
	 * @return
	 */
	private ICSSFigure findContainingPositionedFigure() {
		IFigure figure = this.getCSSFigure().getParent();
		while (figure instanceof ICSSFigure) {
			return (ICSSFigure) figure;
			// ICSSStyle style = ((ICSSFigure) figure).getCSSStyle();
			// if (DisplayToLayout.isPositioned(style))
			// {
			// return (ICSSFigure) figure;
			// }
			// figure = figure.getParent();
		}
		return null;

	}

	/**
	 * @param resultBox
	 * @param x
	 * @param y
	 */
	private void move(CompositeBox compBox, int x, int y) {
		compBox._x += x;
		compBox._y += y;
		List list = compBox.getFragments();
		for (int i = 0; i < list.size(); i++) {
			FlowBox box = (FlowBox) list.get(i);

			if (box instanceof CompositeBox && !(box instanceof BlockBox)) {
				move((CompositeBox) box, x, y);
			} else {
				box._x += x;
				box._y += y;
			}
		}
	}

	/**
	 * Layout all children.
	 */
	protected void layoutChildren() {
		List children = getFlowFigure().getChildren();
		for (int i = 0; i < children.size(); i++) {
			Figure f = (Figure) children.get(i);
			f.invalidate();
			f.validate();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#getLastMarginRight()
	 */
	public int getLastMarginRight() {
		if (_currentLine == null || !_currentLine.isOccupied()) {
			return 0;
		}
		FlowBox box = (FlowBox) _currentLine.getFragments().get(
				_currentLine.getFragments().size() - 1);
		if (box != null) {
			return box._marginInsets.right;
		}
        return 0;
	}

	public void setCalculatingMaxWidth(boolean c) {
		_calculatingMaxWidth = c;
	}

	public boolean getCalcuatingMaxWidth() {
		return _calculatingMaxWidth;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowContext#isCalculatingMaxWidth()
	 */
	public boolean isCalculatingMaxWidth() {
		if (_calculatingMaxWidth) {
			return true;
		} else if (this.getFlowContext() == null) {
			return false;
		} else {
			return this.getFlowContext().isCalculatingMaxWidth();
		}
	}

	/**
	 * Called after {@link #layoutChildren()}when all children have been laid
	 * out. This method exists to flush the last line.
	 */
	protected abstract void flush();

	/**
	 * Flush anything pending and free all temporary data used during layout.
	 */
	protected abstract void cleanup();

	// ------------------------------------------------------------------------------------

	public CSSFigure getCSSFigure() {
		return (CSSFigure) getFlowFigure();
	}

	/**
	 * 
	 * @return
	 */
	public abstract List getFragmentsForRead();

	/**
	 * postValidate the child figures of this CSSFigure. Normally layout fall
	 * into the first category need implement this method.
	 */
	public abstract void postValidate();

	/**
	 * setBounds is called on the CSSFigure. Normally layout fall into the
	 * second category need implement this method.
	 * 
	 * @param rect
	 * @param invalidate
	 */
	public void setBoundsCalled(Rectangle rect, boolean invalidate) {
        // TODO: dead?
	}

	/**
	 * Child class can override this. Normally block figure will return true.
	 * 
	 * @return
	 */
	public boolean useLocalCoordinates() {
		return false;
	}

	/**
	 * If CSSLayout will call paint rountine to draw Border for its box, this
	 * method will return true, else return false, for example,the input file
	 * will return false.
	 * 
	 * @return
	 */
	public boolean handlingBorderForBlock() {
		return true;
	}

	/**
	 * This method is called when the corresponding figure is revalidated.
	 * 
	 */
	public void figureRevalidate() {
		// child class can override.
	}
}
