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

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
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.provider.ICSSTextProvider;
import org.eclipse.jst.pagedesigner.css2.style.DefaultStyle;
import org.eclipse.jst.pagedesigner.css2.style.StyleUtil;
import org.eclipse.jst.pagedesigner.viewer.CaretPositionResolver;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.RGB;

/**
 * @author mengbo
 */
public class CSSTextFigure extends FlowFigure implements ICSSFigure {
	private ICSSTextProvider _provider;

	private List _fragments = new ArrayList(1);

	/**
	 * @param provider
	 */
	public CSSTextFigure(ICSSTextProvider provider) {
		_provider = provider;
		this.setLayoutManager(createDefaultFlowLayout());
	}

	public ICSSStyle getCSSStyle() {
		IFigure parentFigure = this.getParent();
		if (parentFigure instanceof ICSSFigure) {
			ICSSStyle style = ((ICSSFigure) parentFigure).getCSSStyle();
			if (style != null) {
				return style;
			}
		}
		return DefaultStyle.getInstance();
	}

	/**
	 * @see org.eclipse.draw2d.IFigure#containsPoint(int, int)
	 */
	public boolean containsPoint(int x, int y) {
		if (!super.containsPoint(x, y)) {
			return false;
		}
		List frags = getFragments();
		for (int i = 0, n = frags.size(); i < n; i++) {
			if (((FlowBox) frags.get(i)).containsPoint(x, y)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * @return the default flow layout
	 * 
	 */
	protected FlowFigureLayout createDefaultFlowLayout() {
		return new CSSTextLayout(this);
	}

	/**
	 * Returns the <code>LineBox</code> fragments contained in this InlineFlow
	 * 
	 * @return The fragments
	 */
	public List getFragments() {
		return _fragments;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.jst.pagedesigner.css2.layout.ICSSFigure#getFragmentsForRead()
	 */
	public List getFragmentsForRead() {
		return getFragments();
	}

	/**
	 * @return the text
	 */
	public String getText() {
		return _provider.getTextData();
	}

	/**
	 * @see FlowFigure#postValidate()
	 */
	public void postValidate() {
		List list = getFragments();
		FlowBox box;
		int left = Integer.MAX_VALUE, top = left;
		int right = Integer.MIN_VALUE, bottom = right;
		for (int i = 0, n = list.size(); i < n; i++) {
			box = (FlowBox) list.get(i);
			left = Math.min(left, box._x);
			right = Math.max(right, box._x + box._width);
			top = Math.min(top, box._y);
			bottom = Math.max(bottom, box._y + box._height);
		}
		setBounds(new Rectangle(left, top, right - left, bottom - top));
		list = getChildren();
		for (int i = 0, n = list.size(); i < n; i++) {
			((FlowFigure) list.get(i)).postValidate();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.draw2d.Figure#paintBorder(org.eclipse.draw2d.Graphics)
	 */
	protected void paintBorder(Graphics graphics) {
		if (Debug.DEBUG_TEXTBORDER) {
			if (_fragments != null) {
				graphics.setForegroundColor(ColorConstants.darkBlue);
				for (int i = 0, size = _fragments.size(); i < size; i++) {
					FlowBox box = (FlowBox) _fragments.get(i);
					BoxUtil.drawBox(graphics, box);
				}
				graphics.restoreState();
			}
		}
	}

	/**
	 * @see org.eclipse.draw2d.Figure#paintFigure(Graphics)
	 */
	protected void paintFigure(Graphics g) {
		Object result = this.getCSSStyle().getColor();
		Color color;
		if (result instanceof Color) {
			color = (Color) result;
		} else if (result instanceof RGB) {
			color = new Color(null, (RGB) result);
		} else {
			color = null;
		}
		int[] range = null;
		if (!StyleUtil.isInWidget(this.getCSSStyle())) {
			range = _provider.getSelectedRange();
		}
		if (range == null || range[0] == range[1]) {
			// we are not in selection
			TextLayoutSupport.paintTextFigure(g, _fragments, getCSSStyle()
					.getCSSFont().getSwtFont(), color, ((Integer) getCSSStyle()
					.getStyleProperty(ICSSPropertyID.ATTR_TEXTDECORATION))
					.intValue());
		} else {
			TextLayoutSupport.paintTextFigureWithSelection(g, _fragments,
					_provider.getTextData(), getCSSStyle().getCSSFont()
							.getSwtFont(), color, ((Integer) getCSSStyle()
							.getStyleProperty(
									ICSSPropertyID.ATTR_TEXTDECORATION))
							.intValue(), range[0], range[1],
					ColorConstants.white, ColorConstants.blue);
		}
		if (color != result && color != null) {
			color.dispose();
		}
	}

	/**
	 * Find out lines which has closer y coordinate to point, and then line
	 * which has closer x coordinate.
	 * 
	 * @param relative
	 * @return return the offset
	 */
    // TODO: refactoring?
	public int getNewInsertionOffset(Point relative) {
		TextFragmentBox closestBox = null;
		// if there is one which are at the same line with relative, calculate
		// that line first;
		for (int i = 0, n = _fragments.size(); i < n; i++) {
			TextFragmentBox box = (TextFragmentBox) _fragments.get(i);
			if (box.containsPoint(relative.x, relative.y)) {
				int index = FlowUtilities.getTextInWidth(box.getTextData(),
						getCSSStyle().getCSSFont().getSwtFont(), relative.x
								- box._x, TextLayoutSupport
								.getAverageCharWidth(box));
				return box._offset + index;
			}
            if (closestBox == null) {
            	closestBox = box;
            } else {
            	// box is above point
            	TextFragmentBox tempBox = box;
            	int offset1 = Math
            			.abs(CaretPositionResolver.getYDistance(
            					new Rectangle(tempBox._x, tempBox._y,
            							tempBox._width, tempBox._height),
            					relative));
            	tempBox = closestBox;
            	int offset2 = Math
            			.abs(CaretPositionResolver.getYDistance(
            					new Rectangle(tempBox._x, tempBox._y,
            							tempBox._width, tempBox._height),
            					relative));
            	if (offset1 < offset2) {
            		closestBox = box;
            	}
            }
            // at the same line
            if (box.containsPoint(box._x, relative.y)) {
            	TextFragmentBox tempBox = box;
            	int offset1 = Math
            			.abs(CaretPositionResolver.getXDistance(
            					new Rectangle(tempBox._x, tempBox._y,
            							tempBox._width, tempBox._height),
            					relative));
            	tempBox = closestBox;
            	int offset2 = Math
            			.abs(CaretPositionResolver.getXDistance(
            					new Rectangle(tempBox._x, tempBox._y,
            							tempBox._width, tempBox._height),
            					relative));
            	if (offset1 < offset2) {
            		closestBox = box;
            	}
            }
		}

		if (closestBox.containsPoint(closestBox._x, relative.y)
				|| closestBox.containsPoint(relative.x, closestBox._y)) {
			int offset = relative.x - closestBox._x;
			int index = FlowUtilities.getTextInWidth(closestBox.getTextData(),
					getCSSStyle().getCSSFont().getSwtFont(), offset,
					TextLayoutSupport.getAverageCharWidth(closestBox));
			return closestBox._offset + index;
		}
        return -1;
	}

	/**
	 * @param relative
	 * @return the insertion offset
	 */
	public int getInsertionOffset(Point relative) {
		for (int i = 0, n = _fragments.size(); i < n; i++) {
			TextFragmentBox box = (TextFragmentBox) _fragments.get(i);
			if (box.containsPoint(relative.x, relative.y)) {
				int index = FlowUtilities.getTextInWidth(box.getTextData(),
						getCSSStyle().getCSSFont().getSwtFont(), relative.x
								- box._x, TextLayoutSupport
								.getAverageCharWidth(box));
				return box._offset + index;
			}
		}
		return -1;
	}

	/**
	 * the returned rectangle will be relative to this text figure.
	 * 
	 * @param offset
	 * @return the caret position
	 */
	public Rectangle calculateCaretPosition(int offset) {
		// search reverse order, find the latest box that has _offset small than
		// the specified one
		if (offset > 0) {
			for (int i = _fragments.size() - 1; i >= 0; i--) {
				TextFragmentBox box = (TextFragmentBox) _fragments.get(i);
				if (box._offset <= offset) {
					// ok, we find the box.
					if (box._offset + box._length < offset) {
						return new Rectangle(box._x + box._width, box._y, 1,
								box._height);
					}
                    String s = box.getTextData().substring(0,
                    		offset - box._offset);
                    int width = FlowUtilities.getTextExtents(s,
                    		getCSSStyle().getCSSFont().getSwtFont()).width;
                    return new Rectangle(box._x + width, box._y, 1,
                    		box._height);
				}
			}
		} else {
			if (_fragments.size() > 0) {
				TextFragmentBox box = (TextFragmentBox) _fragments.get(0);
				return new Rectangle(box._x, box._y, 1, box._height);
			}
		}
		// should only reach here when there is no fragments.
		return new Rectangle(getBounds().x, getBounds().y, 1, getBounds().height);
	}

}
