/*******************************************************************************
 * 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.viewer;

import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;

import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.jface.text.Assert;
import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
import org.eclipse.jst.pagedesigner.validation.caret.IPositionMediator;

/**
 * FlowBoxLine collects EditParts in a line that cover the x or y coordinate of
 * design view caret. An EditPart may be a widget that can't contains children,
 * a TextEditPart which contains a set of flowbox, or a widgets container which
 * contains some other editparts. For container, there are two types: white box
 * to visitor, that is the container * visitor should consider its content, like
 * <A>, <B>. etc, or black box to visitor, like <TABLE>. Black box means the
 * container will be considered as a whole from outside. For non-container
 * widget we only see TextEditPart can be broken at line end. For black box,
 * only start box or latest box are used for final reference, for white box, we
 * will process its content for reference <@see
 * EditPartPositionHelper.findEditPartPosition>. For Text, the char that is
 * closest to caret will be referenced. In this line class, tree types of
 * EditPart are collected: TextEditPart, Widget, BlackBox container.
 * 
 * @author mengbo
 */
public class FlowBoxLine {
	private int _x;

	private int _y;

	private int _height;

	private int _width;

	private HashMap _parts = new HashMap();

	private IPositionMediator _validator;

	private Point _point;

	public FlowBoxLine(Rectangle rect, IPositionMediator validator, Point point) {
		_x = rect.x;
		_y = rect.y;
		_width = rect.width;
		_height = rect.height;
		_validator = validator;
		_point = point;
	}

	/**
	 * @return Returns the _height.
	 */
	public int getHeight() {
		return _height;
	}

	/**
	 * @return Returns the _width.
	 */
	public int getWidth() {
		return _width;
	}

	/**
	 * @return Returns the _x.
	 */
	public int getX() {
		return _x;
	}

	/**
	 * @return Returns the _y.
	 */
	public int getY() {
		return _y;
	}

	public HashMap getPartsList() {
		return _parts;
	}

	public Point getRightBottom() {
		return new Point(_x + _width, _y + _height);
	}

	public boolean addLayoutPart(EditPart part, Point point) {
		Assert.isTrue(part != null && point != null);
		Rectangle rect = null;
		LayoutPart lPart = new LayoutPart(part, point);
		if (_parts.size() == 0) {
			resetBounds(lPart);
			return true;
		}
		if (!interact(lPart)) {
			if (closer(lPart)) {
				resetBounds(lPart);
				return true;
			} else {
				return false;
			}
		} else {
			rect = lPart.getAbsoluteBounds();
		}
		int xx = Math.min(rect.x, _x);
		int width = Math.max(rect.getRight().x, getRightBottom().x) - xx;
		int yy = Math.min(rect.y, _y);
		int height = Math.max(rect.getBottom().y, getRightBottom().y) - yy;
		_x = xx;
		_y = yy;
		_width = width;
		_height = height;
		_parts.put(part, lPart);
		return true;
	}

	public boolean interact(LayoutPart lPart) {
		Rectangle rect = lPart.getAbsoluteBounds();
		return !(rect.getBottom().y <= _y || getRightBottom().y <= rect.y);
	}

	public boolean contains(EditPart part) {
		return _parts.containsKey(part);
	}

	public boolean contains(LayoutPart part) {
		return _parts.containsValue(part);
	}

	public LayoutPart getLayoutPart(EditPart part) {
		return (LayoutPart) _parts.get(part);
	}

	// For vertical movement, we need to see if there is part cover p.x.
	public EditPart getClosestPart() {
		if (_parts.isEmpty()) {
			return null;
		}
		Collection parts = _parts.values();
		Iterator iterator = parts.iterator();
		LayoutPart closestPart = (LayoutPart) iterator.next();
		if (iterator.hasNext()) {
			while (iterator.hasNext()) {
				LayoutPart nextPart = (LayoutPart) iterator.next();
				closestPart = CaretPositionResolver.getCloserPart(closestPart,
						nextPart, _point);
			}
		}
		// for children.
		LayoutPart result = null;
		if (_validator.getActionData().getActionType() == ActionData.KEYBOARD_NAVAGATION
				|| //
				closestPart.isInline()) {
			result = CaretPositionResolver.getInstance(_validator, _point)
					.resolveClosestPartFrom(closestPart);
		} else {
			result = closestPart;
		}
		if (result != null) {
			return result.getPart();
		} else {
			return null;
		}
	}

	/**
	 * See how close the part,box is closer to point, if it is closer than
	 * current FlowBoxLine. return true;
	 */
	private boolean closer(LayoutPart lPart) {
		int lineYOffset = Math.abs(CaretPositionResolver.getYDistance(
				getBounds(), _point));
		int partYOffset = Math.abs(CaretPositionResolver.getYDistance(lPart
				.getAbsoluteBounds(), _point));
		return lineYOffset > partYOffset;
	}

	public Rectangle getBounds() {
		return new Rectangle(_x, _y, _width, _height);
	}

	private void resetBounds(Rectangle rect) {
		_x = rect.x;
		_y = rect.y;
		_width = rect.width;
		_height = rect.height;
	}

	private void resetBounds(LayoutPart lPart) {
		EditPart part = lPart.getPart();
		Rectangle rect = lPart.getAbsoluteBounds();
		resetBounds(rect);
		_parts.clear();
		_parts.put(part, lPart);
	}
}
