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

import java.util.Collections;

import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPartViewer;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.requests.SelectionRequest;
import org.eclipse.gef.tools.TargetingTool;
import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
import org.eclipse.jst.pagedesigner.parts.TextEditPart;
import org.eclipse.jst.pagedesigner.range.RangeUtil;
import org.eclipse.jst.pagedesigner.validation.caret.ActionData;
import org.eclipse.jst.pagedesigner.validation.caret.IPositionMediator;
import org.eclipse.jst.pagedesigner.validation.caret.InlineEditingPositionMediator;
import org.eclipse.jst.pagedesigner.validation.caret.Target;
import org.eclipse.jst.pagedesigner.viewer.DesignPosition;
import org.eclipse.jst.pagedesigner.viewer.DesignRange;
import org.eclipse.jst.pagedesigner.viewer.EditPartPositionHelper;
import org.eclipse.jst.pagedesigner.viewer.HTMLGraphicalViewer;
import org.eclipse.jst.pagedesigner.viewer.IHTMLGraphicalViewer;
import org.eclipse.swt.graphics.Cursor;

/**
 * @author mengbo
 */
public class RangeDragTracker extends TargetingTool implements DragTracker {
	/** Flag to indicate selection has been performed. */
	protected static final int FLAG_SELECTION_PERFORMED = TargetingTool.MAX_FLAG << 1;

	/** Max flag */
	protected static final int MAX_FLAG = FLAG_SELECTION_PERFORMED;

	private EditPart editpart;

	/**
	 * Constructs a new SelectEditPartTracker with the given edit part as the
	 * source.
	 * 
	 * @param owner
	 *            the source edit part
	 */
	public RangeDragTracker(EditPart owner) {
		setSourceEditPart(owner);
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#calculateCursor()
	 */
	protected Cursor calculateCursor() {
		if (isInState(STATE_INITIAL | STATE_DRAG | STATE_ACCESSIBLE_DRAG)) {
			return getDefaultCursor();
		}
		return super.calculateCursor();
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#getCommandName()
	 */
	protected String getCommandName() {
		return "Range Drag Tracker";//$NON-NLS-1$
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#getDebugName()
	 */
	protected String getDebugName() {
		return "Range Drag Tracker";//$NON-NLS-1$
	}

	/**
	 * Returns the source edit part.
	 * 
	 * @return the source edit part
	 */
	protected EditPart getSourceEditPart() {
		return editpart;
	}

	/**
	 * Performs a conditional selection if needed (if right or left mouse button
	 * have been pressed) and goes into the drag state. If any other button has
	 * been pressed, the tool goes into the invalid state.
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleButtonDown(int)
	 */
	protected boolean handleButtonDown(int button) {
		if (button == 3 && isInState(STATE_INITIAL)) {
			EditPart sourcePart = this.getSourceEditPart();
			IHTMLGraphicalViewer viewer = (IHTMLGraphicalViewer) sourcePart
					.getViewer();
			if (viewer != null && viewer.isInRangeMode()) {
				DesignRange range = viewer.getRangeSelection();
				if (range != null && range.isValid()) {
					if (RangeUtil.intersect(range, sourcePart)) {
						return true;
					}
				}
			}
		}

		if ((button == 1 || button == 3) && isInState(STATE_INITIAL)) {
			peroformSelectionBegin();
		}

		if (button != 1) {
			setState(STATE_INVALID);
			if (button == 3)
				setState(STATE_TERMINAL);
			handleInvalidInput();
		} else {
			stateTransition(STATE_INITIAL, STATE_DRAG);
		}
		return true;
	}

	/**
	 * Calls {@link #performSelection()}if the source is not selected. If the
	 * source is selected and there are no modifier keys pressed (i.e. the user
	 * isn't selecting multiple edit parts or deselecting edit parts), sets the
	 * direct edit flag so that when the mouse is released, a direct edit will
	 * be performed.
	 */
	protected void peroformSelectionBegin() {
		// if (getCurrentInput().isControlKeyDown())
		// {
		// // when control key is down, switch to object selection mode.
		// getHTMLGraphicalViewer().ensureObjectSelectionMode();
		// setFlag(FLAG_SELECTION_PERFORMED, true);
		// EditPartViewer viewer = getCurrentViewer();
		// List selectedObjects = viewer.getSelectedEditParts();
		//
		// if (selectedObjects.contains(getSourceEditPart()))
		// viewer.deselect(getSourceEditPart());
		// else
		// viewer.appendSelection(getSourceEditPart());
		// }
		// else
		if (getCurrentInput().isShiftKeyDown()) {
			getHTMLGraphicalViewer().ensureRangeSelectionMode();
			rangeSelection(true);
		} else {
			if (shouldStartRangeSelection()) {
				rangeSelection(false);
			} else {
				getCurrentViewer().select(getSourceEditPart());
			}
		}
	}

	/**
	 * If in the drag state, the tool selects the source edit part. If the edit
	 * part was already selected, {@link #performDirectEdit()}is called. If the
	 * edit part is newly selected and not completely visible,
	 * {@link EditPartViewer#reveal(EditPart)}is called to show the selected
	 * edit part.
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleButtonUp(int)
	 */
	protected boolean handleButtonUp(int button) {
		if (isInState(STATE_DRAG)) {
			// XXX: commented the following two line (lium)
			// performSelection();
			// if (button == 1 && getSourceEditPart().getSelected() !=
			// EditPart.SELECTED_NONE)
			// getCurrentViewer().reveal(getSourceEditPart());
			setState(STATE_TERMINAL);
			return true;
		}
		return false;
	}

	/**
	 * Calls {@link #performOpen()}if the double click was with mouse button 1.
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleDoubleClick(int)
	 */
	protected boolean handleDoubleClick(int button) {
		if (button == 1) {
			performOpen();
		}
		return true;
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#handleDragStarted()
	 */
	protected boolean handleDragStarted() {
		return stateTransition(STATE_DRAG, STATE_DRAG_IN_PROGRESS);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.tools.AbstractTool#handleDragInProgress()
	 */
	protected boolean handleDragInProgress() {
		if (getHTMLGraphicalViewer().isInRangeMode()) {
			rangeSelection(true);
			return true;
		} else {
			return super.handleDragInProgress();
		}
	}

	/**
	 * Returns <code>true</code> if selection has already occured.
	 * 
	 * @return <code>true</code> if selection has occured
	 */
	protected boolean hasSelectionOccurred() {
		return getFlag(FLAG_SELECTION_PERFORMED);
	}

	/**
	 * Creates a {@link SelectionRequest}and sends it to the source edit part
	 * via {@link EditPart#performRequest(Request)}. Possible uses are to open
	 * the selected item in another editor or replace the current editor's
	 * contents based on the selected item.
	 */
	protected void performOpen() {
		SelectionRequest request = new SelectionRequest();
		request.setLocation(getLocation());
		request.setType(RequestConstants.REQ_OPEN);
		getSourceEditPart().performRequest(request);
	}

	/**
	 * @see org.eclipse.gef.tools.AbstractTool#resetFlags()
	 */
	protected void resetFlags() {
		super.resetFlags();
		setFlag(FLAG_SELECTION_PERFORMED, false);
	}

	/**
	 * Sets the source edit part.
	 * 
	 * @param part
	 *            the source edit part
	 */
	protected void setSourceEditPart(EditPart part) {
		this.editpart = part;
	}

	public IHTMLGraphicalViewer getHTMLGraphicalViewer() {
		return (IHTMLGraphicalViewer) getCurrentViewer();
	}

	/**
	 * @return
	 */
	private boolean shouldStartRangeSelection() {
		IPositionMediator positionMediator = new InlineEditingPositionMediator(
				new ActionData(ActionData.INLINE_EDIT, null));
		if (positionMediator.isEditable(new Target(getSourceEditPart()))) {
			return getSourceEditPart() instanceof TextEditPart
					|| !(((NodeEditPart) getSourceEditPart()).isWidget());
		} else {
			return false;
		}
	}

	/**
	 * @param b
	 *            true means remain the old range start position.
	 */
	private void rangeSelection(boolean b) {
		// XXX: not using updateTargetEditPartUnderMouse. Maybe should. Don't
		// want to
		// go through the request mechanism, so simple implementation for now.
		EditPart editPart = getCurrentViewer().findObjectAtExcluding(
				getLocation(), Collections.EMPTY_LIST);
		IPositionMediator positionMediator = new InlineEditingPositionMediator(
				new ActionData(ActionData.INLINE_EDIT, null));
		ExposeHelper exposeHelper = new ExposeHelper(getHTMLGraphicalViewer());
		exposeHelper.adjustVertical(getCurrentInput().getMouseLocation());
		DesignPosition position = EditPartPositionHelper.findEditPartPosition(
				editPart, getCurrentInput().getMouseLocation(),
				positionMediator);
		if (b) {
			getHTMLGraphicalViewer().setRangeEndPosition(position);
		} else {
			getHTMLGraphicalViewer().setRange(position, position);
		}
		if (getHTMLGraphicalViewer() instanceof HTMLGraphicalViewer) {
			((HTMLGraphicalViewer) getHTMLGraphicalViewer())
					.updateHorizontalPos();
		}
	}
}
