/*******************************************************************************
 * 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.jst.pagedesigner.css2.property.VerticalAlignMeta;
import org.eclipse.jst.pagedesigner.css2.value.Length;
import org.eclipse.swt.graphics.FontMetrics;

/**
 * A composite box representing a single line. LineBox calculates its ascent and
 * descent from the child boxes it contains. Clients can call
 * {@link #getAscent()}or {@link#getHeight()}at any time and expect valid
 * values. The child boxes that are added to a line have unspecied locations
 * until {@link #commit()}is called, at which time the child boxes are layed
 * out in left-to-right order, and their baselines are all aligned vertically.
 * 
 */
public class LineBox extends CompositeBox {
	private final static int BASELINE = 0;

	private final static int MIDDLE = 1;

	private final static int SUB = 2;

	private final static int SUPER = 3;

	private final static int TEXT_TOP = 4;

	private final static int TEXT_BOTTOM = 5;

	private final static int TOP = 6;

	private final static int BOTTOM = 7;

	private final static int LENGTH = 8;

	private int _ascent = 0;

	private int _descent = 0;

	private int _fontAscent = 0;

	private int _fontDescent = 0;

	private int _fontLeading = 0;

	private Object _horizonalData = null;

	private Object _htmlInitData = null;

	private int _accumlatedWidth = 0;

	/**
	 * Removes all owned fragments and invalidates this CompositeBox.
	 */
	public void clear() {
		super.clear();
		_horizonalData = null;
		_htmlInitData = null;
	}

	/**
	 * Committing a LineBox will position its children correctly. All children
	 * boxes are made to have the same baseline, and are layed out from
	 * left-to-right.
	 */
	public void commit() {
		int baseline = getBaseline();
		int xLocation = _x;
		for (int i = 0; i < _fragments.size(); i++) {
			FlowBox block = (FlowBox) _fragments.get(i);
			block._x = xLocation + block._marginInsets.left;
			xLocation = block._x + block._width + block._marginInsets.right;

			if (_fragments.size() > 1 && block instanceof TextFragmentBox) {
				TextFragmentBox textBox = (TextFragmentBox) block;
				if (textBox.getTextData().length() == 0) {
					textBox._height = _fontAscent + _fontDescent + _fontLeading;
					textBox.setAscent(_fontAscent + _fontLeading);
					block._y = this._y;
					continue;
				}
			}

			switch (getVerticalAlignType(block)) {
			case TOP:
				block._y = this._y;
				break;
			case BOTTOM:
				block._y = this.getBaseline() - (block.getHeight() - _descent);
				break;
			case MIDDLE:
				int halfXHeight = getHalfXHeight();
				block._y = this.getBaseline() - halfXHeight
						- (block.getHeight() + 1) / 2;
				break;
			case TEXT_TOP:
				block._y = this.getBaseline() - _fontAscent - _fontLeading;
				break;
			case TEXT_BOTTOM:
				block._y = this.getBaseline() - (block._height - _fontDescent);
				break;
			case LENGTH:
				block._y = this.getBaseline() + getIncrement(block);
				break;
			case SUPER:
				block._y = this.getBaseline() - getHalfXHeight() * 2
						- block._height;
				break;
			case SUB:
				block._y = this.getBaseline() - block._height * _fontLeading
						/ getFontHeight();
				break;
			case BASELINE:
			default:
				block.makeBaseline(baseline);
				break;
			}
			if (block instanceof LineBox) {
				((LineBox) block).commit();
			}
		}
	}

	protected int getVerticalAlignType(FlowBox box) {
		Object data = box.getVerticalAlignData();

		if (data != null) {
			if (data instanceof Length) {
				return LENGTH;
			} else if (VerticalAlignMeta.BASELINE.equals(data)) {
				return BASELINE;
			} else if (VerticalAlignMeta.MIDDLE.equals(data)) {
				return MIDDLE;
			} else if (VerticalAlignMeta.SUB.equals(data)) {
				return SUB;
			} else if (VerticalAlignMeta.SUPER.equals(data)) {
				return SUPER;
			} else if (VerticalAlignMeta.TEXT_TOP.equals(data)) {
				return TEXT_TOP;
			} else if (VerticalAlignMeta.TEXT_BOTTOM.equals(data)) {
				return TEXT_BOTTOM;
			} else if (VerticalAlignMeta.TOP.equals(data)) {
				return TOP;
			} else if (VerticalAlignMeta.BOTTOM.equals(data)) {
				return BOTTOM;
			}
			return BASELINE;
		}
		return BASELINE;
	}

	/**
	 * @see org.eclipse.jst.pagedesigner.css2.layout.FlowBox#getAscent()
	 */
	public int getAscent() {
		// because at initial, ascent is 0. And the linebox
		// could have some size setting without children. In
		// that case, we need handle differently.
		if (_ascent == 0 && _fragments.isEmpty()) {
			return getHeight();
		}
		return _ascent;
	}

	/**
	 * Returns the width available to child fragments.
	 * 
	 * @return the width in pixels
	 */
	public int getAvailableWidth() {
		if (_recommendedWidth < 0) {
			return Integer.MAX_VALUE;
		}
		int availableWidth = _recommendedWidth - _accumlatedWidth;
		if (availableWidth < 0) {
			availableWidth = 0;
		}
		return availableWidth;
	}

	/**
	 * Returns the baseline of this LineBox, which is the y value plus the
	 * ascent.
	 * 
	 * @return the baseline value.
	 */
	public int getBaseline() {
		return _y + getAscent();
	}

	/**
	 * @see CompositeBox#resetInfo()
	 */
	protected void resetInfo() {
		super.resetInfo();
		_accumlatedWidth = 0;
		_ascent = 0;
	}

	/**
	 * @see CompositeBox#unionInfo(FlowBox)
	 */
	protected void unionInfo(FlowBox blockInfo) {
		if (blockInfo instanceof TextFragmentBox) {
			if (((TextFragmentBox) blockInfo).getTextData().length() == 0) {
				return;
			}
		}

		if (_fragments == null || _fragments.isEmpty()) {
			this._ascent = 0;
			this._descent = 0;
			this._height = 0;
		}

		int valign = getVerticalAlignType(blockInfo);

		if (valign == BASELINE) {
			_ascent = Math.max(_ascent, blockInfo.getAscent());
			if (blockInfo instanceof WidgetBox) {
				_descent = 0;
			} else {
				_descent = Math.max(_descent, blockInfo.getDescent());
			}
			_height = Math.max(_height, _ascent + _descent);
		} else if (valign == MIDDLE) {
			int halfXHeight = getHalfXHeight();
			_ascent = Math.max(_ascent, (blockInfo.getHeight() + 1) / 2
					+ halfXHeight);
			_descent = Math.max(_descent, blockInfo.getHeight() / 2
					- halfXHeight);
			_height = Math.max(_height, _ascent + _descent);
		} else if (valign == TEXT_TOP) {
			_ascent = Math.max(_ascent, _fontAscent + _fontLeading);
			_descent = Math.max(_descent, blockInfo.getHeight() - _fontAscent
					- _fontLeading);
			_height = Math.max(_height, _ascent + _descent);
		} else if (valign == TEXT_BOTTOM) {
			_ascent = Math.max(_ascent, blockInfo.getHeight() - _fontDescent);
			_descent = Math.max(_descent, _fontDescent);
			_height = Math.max(_height, _ascent + _descent);
		} else if (valign == SUB) {
			int blockTop = blockInfo._height * _fontLeading / getFontHeight();
			_ascent = Math.max(_ascent, blockTop);
			_descent = Math.max(_descent, blockInfo.getHeight() - blockTop);
			_height = Math.max(_height, _ascent + _descent);
		} else if (valign == SUPER) {
			int blockTop = blockInfo._height;
			_ascent = Math.max(_ascent, getHalfXHeight() * 2 + blockTop);
			_height = Math.max(_height, _ascent + _descent);
		} else if (valign == LENGTH) {
			int increment = getIncrement(blockInfo);
			_ascent = Math.max(_ascent, blockInfo.getAscent() + increment);
			_descent = Math.max(_descent, blockInfo.getDescent() - increment);
			_height = Math.max(_height, _ascent + _descent);
		} else if (valign == TOP) {
			_descent = Math.max(_descent, blockInfo.getHeight() - _ascent);
			_height = Math.max(_height, _ascent + _descent);
		} else if (valign == BOTTOM) {
			// XXX:the render of IE is not consistent with spec, mozilla is. so
			// we follow mozilla's implementation.
			_ascent = Math.max(_ascent, blockInfo.getHeight() - _descent);
			_height = Math.max(_height, _ascent + _descent);
		} else {
			_ascent = Math.max(_ascent, blockInfo.getAscent());
			_descent = Math.max(_descent, blockInfo.getDescent());
			_height = Math.max(_height, blockInfo.getHeight());
		}

		_accumlatedWidth += blockInfo._width
				+ blockInfo._marginInsets.getWidth();
		if (_accumlatedWidth > _width) {
			_width = _accumlatedWidth;
		}
	}

	private int getIncrement(FlowBox blockInfo) {
		int valign = getVerticalAlignType(blockInfo);
		if (valign == LENGTH) {
			int increment = 0;
			Length length = (Length) blockInfo.getVerticalAlignData();
			if (length.isPercentage()) {
				increment = length.getValue() * getFontHeight() / 100;
			} else {
				increment = length.getValue();
			}
			return increment;
		}
		return 0;
	}

	/**
	 * @see org.eclipse.draw2d.geometry.Rectangle#isEmpty()
	 */
	public boolean isOccupied() {
		if (_width > 0) {
			return true;
		}

		if (_fragments.isEmpty()) {
			return false;
		}
		// int size = _fragments.size();
		// if (size > 1)
		// {
		// return true;
		// }
		// ok, we have one segment
		// FlowBox box = (FlowBox) _fragments.get(0);
		// if (box instanceof TextFragmentBox)
		// {
		// if (((TextFragmentBox) box).getTextData().length() == 0)
		// {
		// // this is an empty string text box.
		// return false;
		// }
		// }
		return true;
	}

	public boolean isEmptyStringLine() {
		// if(this.getWidth() == 0)
		// {
		// return true;
		// }
		// else
		// {
		// return false;
		// }
		if (_fragments.size() == 1) {
			FlowBox box = (FlowBox) _fragments.get(0);
			if (box instanceof TextFragmentBox) {
				if (box instanceof TextFragmentBox) {
					if (((TextFragmentBox) box).getTextData().length() == 0) {
						return true;
					}
				}
			}
		}
		return false;
	}

	/**
	 * @param fontMetrics
	 */
	public void setFontMetrics(FontMetrics fontMetrics) {
		if (fontMetrics != null) {
			_fontAscent = fontMetrics.getAscent();
			_fontDescent = fontMetrics.getDescent();
			_fontLeading = fontMetrics.getLeading();
			// if (_fragments == null || _fragments.isEmpty())
			// {
			// this._ascent = _fontAscent + _fontLeading;
			// this._descent = _fontDescent;
			// if (this._height < this._ascent + this._descent)
			// {
			// this._height = this._ascent + this._descent;
			// }
			// }
		} else {
			_fontAscent = 0;
			_fontDescent = 0;
			_fontLeading = 0;
		}
	}

	private int getHalfXHeight() {
		return (_fontAscent + _fontDescent + _fontLeading) / 5;
	}

	private int getFontHeight() {
		return _fontAscent + _fontDescent + _fontLeading;
	}

	/**
	 * @return Returns the horizonalData.
	 */
	public Object getHorizonalData() {
		return _horizonalData;
	}

	/**
	 * @param horizonalData
	 *            The horizonalData to set.
	 */
	public void setHorizonalData(Object horizonalData) {
		this._horizonalData = horizonalData;
	}

	/**
	 * @return Returns the htmlInitData.
	 */
	public Object getHtmlInitData() {
		return _htmlInitData;
	}

	/**
	 * @param htmlInitData
	 *            The htmlInitData to set.
	 */
	public void setHtmlInitData(Object htmlInitData) {
		this._htmlInitData = htmlInitData;
	}
}
