/*******************************************************************************
 * 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 {
	private 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;

	/**
	 * @param flowFigure 
	 * @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 the css style
	 */
	public ICSSStyle getCSSStyle() {
		return getCSSFigure().getCSSStyle();
	}

	/**
	 * @return the absolute context
	 */
	protected final BlockFlowContext getAbsoluteContext() {
        return _absoluteContext;
    }

    /**
	 * @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();
	}

	/**
	 * @return true if is absolute position
	 */
	protected final 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 true if supports absolute position  
	 */
	protected boolean supportAbsolutePosition() {
		if (findContainingPositionedFigure() == null) {
			return false;
		}
		return true;
	}

	/**
	 * Perform a 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();
	}

	/**
	 * @return the flow context
	 */
	private FlowContext getParentFigureContext() {
		return super.getFlowContext();
	}

	final 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.getMarginInsets().right;
		}
        return 0;
	}

	/**
	 * @param c
	 */
	public void setCalculatingMaxWidth(boolean c) {
		_calculatingMaxWidth = c;
	}

	/**
	 * @return the calculated maximum width
	 */
	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();

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

	/**
	 * @return the css figure
	 */
	protected final CSSFigure getCSSFigure() {
		return (CSSFigure) getFlowFigure();
	}

	/**
	 * 
	 * @return the fragments for read
	 */
	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 true if should use local coordinates
	 */
	protected 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 true if handling border block
	 */
	protected boolean handlingBorderForBlock() {
		return true;
	}

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