/*******************************************************************************
 * 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.draw2d.Cursors;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPart;
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.IHTMLGraphicalViewer;
import org.eclipse.swt.graphics.Cursor;

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

	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() {
        return Cursors.IBEAM;
//		if (isInState(STATE_INITIAL))
//        {
//            return Cursors.IBEAM;
//        }
//        else if (isInState(STATE_DRAG | STATE_ACCESSIBLE_DRAG))
//        {
//			return getDefaultCursor();
//		}
//        return Cursors.IBEAM;
//		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;
	}

	/**
	 * 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 is newly selected and not completely visible,
	 * {@link org.eclipse.gef.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;
		}
        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(org.eclipse.gef.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;
	}

	/**
	 * @return the html graphical viewer
	 */
	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());
		}
        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);
		}
		getHTMLGraphicalViewer().updateHorizontalPos();
	}

    protected boolean handleHover() {
        boolean retValue = super.handleHover();
        refreshCursor();
        return retValue;
    }
}
