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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.Assert;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.PositionConstants;
import org.eclipse.draw2d.RectangleFigure;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PrecisionRectangle;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.DragTracker;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.GraphicalEditPart;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.Request;
import org.eclipse.gef.RequestConstants;
import org.eclipse.gef.SharedCursors;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.ResizableEditPolicy;
import org.eclipse.gef.handles.NonResizableHandleKit;
import org.eclipse.gef.requests.ChangeBoundsRequest;
import org.eclipse.gef.requests.LocationRequest;
import org.eclipse.gef.requests.SelectionRequest;
import org.eclipse.gef.tools.SelectEditPartTracker;
import org.eclipse.jst.pagedesigner.commands.single.ChangeStyleCommand;
import org.eclipse.jst.pagedesigner.css2.ICSSStyle;
import org.eclipse.jst.pagedesigner.css2.layout.BlockBox;
import org.eclipse.jst.pagedesigner.css2.layout.CSSFigure;
import org.eclipse.jst.pagedesigner.dom.EditModelQuery;
import org.eclipse.jst.pagedesigner.parts.ElementEditPart;
import org.eclipse.jst.pagedesigner.parts.NodeEditPart;
import org.eclipse.jst.pagedesigner.requests.LocationModifierRequest;
import org.eclipse.jst.pagedesigner.tools.ObjectModeDragTracker;
import org.eclipse.jst.pagedesigner.tools.RangeDragTracker;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * @author mengbo
 * @version 1.5
 */
public class ElementResizableEditPolicy extends ResizableEditPolicy implements IEnhancedSelectionEditPolicy 
{
	private static final Insets INSETS_1 = new Insets(1, 1, 1, 1);

	private static final int THRESHHOLD = 3;
    
    // the number of pixels to offset the top left of tooltop feedback
    // below the current mouse cursor location
    private static final int TOOLTIP_VERTICAL_OFFSET = 25;

	private static final Insets INSETS_CONST = new Insets(THRESHHOLD,
			THRESHHOLD, THRESHHOLD, THRESHHOLD);

	private boolean _showLabelFeedback = true;

	private IFigure[] _hoverFeedbackFigure;
    
    //private NonVisualChildDecorator   _selectionDecoratorNorthWest; // = null;
    private MouseSelectableChildDecorator   _nonVisualChildDecorator; // = null;
    
	private final static Color HOVER_FEEDBACK_COLOR = ColorConstants.blue;

	public void deactivate() 
    {
        super.deactivate();
        if (_nonVisualChildDecorator != null)
        {
            _nonVisualChildDecorator.dispose();
            _nonVisualChildDecorator = null;
        }
    }

    /*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#showTargetFeedback(org.eclipse.gef.Request)
	 */
	public void showTargetFeedback(Request request) {
		if (RequestConstants.REQ_SELECTION_HOVER.equals(request.getType())) {
			if (_hoverFeedbackFigure != null) {
				for (int i = 0; i < _hoverFeedbackFigure.length; i++) {
					removeFeedback(_hoverFeedbackFigure[i]);
				}
				_hoverFeedbackFigure = null;
            }
            
            // <gripe>this is what I hate about GEF, if it's a location dependent
            // request why aren't we guaranteed a LocationRequest?!
            // even GEF interal code protects casts by checking getType()
            // rather than an instanceof!</gripe>
            Assert.isTrue(request instanceof LocationRequest);
            // don't show tooltip if drag is active
            _showLabelFeedback = !((NodeEditPart)getHost()).isDragActive();
			_hoverFeedbackFigure = showHoverFeedback((LocationRequest)request);
		} else {
			super.showTargetFeedback(request);
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editpolicies.AbstractEditPolicy#eraseTargetFeedback(org.eclipse.gef.Request)
	 */
	public void eraseTargetFeedback(Request request) {
		if (RequestConstants.REQ_SELECTION_HOVER.equals(request.getType())) {
			if (_hoverFeedbackFigure != null) {
				for (int i = 0; i < _hoverFeedbackFigure.length; i++) {
					removeFeedback(_hoverFeedbackFigure[i]);
				}
				_hoverFeedbackFigure = null;
                getNonVisualChildDecorator().updateState(MouseSelectableChildDecorator.EVENT_HOST_HOVER_LOST);
			}
		} else {
			super.eraseTargetFeedback(request);
		}
	}

	/**
	 * @param request
	 */
	private IFigure[] showHoverFeedback(LocationRequest request) {
		if (!shouldUseObjectMode(request) && !isStyleTags(getHost())) {
			return null;
		}

        final IFigure figure = this.getHostFigure();
		Rectangle[] rects;
		if (figure instanceof CSSFigure) {
			rects = ((CSSFigure) figure).getFragmentsBounds();
		} else {
			rects = new Rectangle[] { figure.getBounds() };
		}
        int figureSize = rects.length;
        
        if (_showLabelFeedback)
        {
            figureSize++;
        }
        
		IFigure[] figures = new IFigure[figureSize];
		for (int i = 0; i < rects.length; i++) {
			RectangleFigure fig = new RectangleFigure();
			fig.setFill(false);
			fig.setOutline(true);
			fig.setLineWidth(1);
			fig.setForegroundColor(HOVER_FEEDBACK_COLOR);
			addFeedback(fig);

			Rectangle r = rects[i].getCopy();
			figure.translateToAbsolute(r);
			fig.translateToRelative(r);
			fig.setBounds(r);

			figures[i] = fig;
		}
       
		if (_showLabelFeedback) 
        {
            getNonVisualChildDecorator().updateState(MouseSelectableChildDecorator.EVENT_HOST_HOVER_RECEIVED);
            
			BasicLabelToolTip label = new BasicLabelToolTip(getTooltipText());
			addFeedback(label);

            // use mouse cursor plus an offset so the tooltip doesn't
            // appear z-ordered below the mouse cursor
            AbsolutePointLocator locator = AbsolutePointLocator.getInstance();
            locator.setReferencePoint(request.getLocation(), 0, TOOLTIP_VERTICAL_OFFSET);
            //  to avoid enlargemeent of the feedback layer
            locator.setIntersectFigure(getFeedbackLayer());
            locator.relocate(label);
			figures[rects.length] = label;
		}
		return figures;
	}

	private String getTooltipText() {
		Element element = (Element) this.getHost().getModel();
		StringBuffer text = new StringBuffer(element.getTagName());
		return text.toString();
	}

	private boolean isStyleTags(EditPart part) {
		if (part != null && part.getModel() instanceof Node) {
			return EditModelQuery.HTML_STYLE_NODES.contains(((Node) part
					.getModel()).getNodeName());
		}
        return false;
	}
    private MouseSelectableChildDecorator getNonVisualChildDecorator()
    {
        if  (_nonVisualChildDecorator == null)
        {
            _nonVisualChildDecorator = 
                new MouseSelectableChildDecorator((GraphicalEditPart)getHost()
                        , PositionConstants.NORTH_EAST
                        , getLayer(LayerConstants.FEEDBACK_LAYER)
                        , getLayer(LayerConstants.HANDLE_LAYER));
        }
        return _nonVisualChildDecorator;
    }

	/**
	 * @param request
	 * @return true if we should be using object mode for this request
	 */
	public boolean shouldUseObjectMode(Request request) {
		ElementEditPart part = (ElementEditPart) this.getHost();
		if (isStyleTags(part)) {
			return false;
		}
		if (part.isWidget()
				|| (!part.canHaveDirectTextChild() && !part
						.haveNonWhitespaceTextChild())) {
			return true;
		}
		if (request instanceof SelectionRequest
				&& ((SelectionRequest) request).isControlKeyPressed()) {
			return true;
		}
		if (request instanceof LocationModifierRequest
				&& ((LocationModifierRequest) request).isControlKeyPressed()) {
			return true;
		}

		// for other elements
		if (request instanceof LocationRequest) {
			Point location = ((LocationRequest) request).getLocation()
					.getCopy();
			part.getFigure().translateToRelative(location);
			return shouldUseObjectMode(location);
		}
        return false; // should not happen
	}

	/**
	 * @param location
	 * @return
	 */
	private boolean shouldUseObjectMode(Point location) {
		// when the location is close to the border/padding of the element, then
		// we think it is default to
		// object mode selection.
		CSSFigure figure = (CSSFigure) this.getHostFigure();
		if (figure.getFragmentsBounds().length != 1) {
			return false;
		}
		Rectangle bounds = figure.getBounds().getCopy();
		Insets insets = figure.getInsets();
		bounds.crop(insets);
		if (insets.top > THRESHHOLD && insets.left > THRESHHOLD
				&& insets.right > THRESHHOLD && insets.bottom > THRESHHOLD) {
			return !bounds.contains(location);
		}

		// since the figure insets could be 0, so we expand it a little, thus
		// even the point is
		// a little inside the content area, we still think it is selection the
		// object.
		if (bounds.height < 3 * THRESHHOLD || bounds.width < 3 * THRESHHOLD) {
			bounds.crop(INSETS_1);
		} else {
			bounds.crop(INSETS_CONST);
		}
		return !bounds.contains(location);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editpolicies.ResizableEditPolicy#createSelectionHandles()
	 */
	protected List createSelectionHandles() {
		// we have three different kinds of handles.
		// 1. Those element that is resizable.
		// 2. Those element that is rectangle but not resizable.
		// 3. Those element that is not rectangle (fragments)

		IFigure figure = this.getHostFigure();
		if (figure instanceof CSSFigure && getHost() instanceof ElementEditPart) {
			CSSFigure cssfigure = (CSSFigure) figure;
			List fragments = cssfigure.getFragmentsForRead();

			// XXX: only one fragment and is blockbox, then we think it is
			// resizable by figure
			// should move this test to somewhere else.
			if (fragments != null && fragments.size() == 1
					&& fragments.get(0) instanceof BlockBox) {
				if (((ElementEditPart) getHost()).isResizable()) {
					// super is Resizable policy, will create a resize handles.
					return super.createSelectionHandles();
				}
                return createNonResizeHandles();
			}
            return createFragmentsHandles();
		}
        // second case
        return createNonResizeHandles();
	}

	/**
	 * @return
	 */
	private List createFragmentsHandles() {
		List list = new ArrayList();
		list.add(new FragmentHandle((GraphicalEditPart) getHost()));
		return list;
	}

	/**
	 * @return
	 */
	private List createNonResizeHandles() {
		// following code copied from NonResizableEditPolicy
		List list = new ArrayList();
		if (isDragAllowed()) {
			NonResizableHandleKit.addHandles((GraphicalEditPart) getHost(),
					list);
		} else {
			NonResizableHandleKit.addHandles((GraphicalEditPart) getHost(),
					list, new SelectEditPartTracker(getHost()),
					SharedCursors.ARROW);
		}

		return list;
	}


    protected void hideSelection() {
        super.hideSelection();
        // handle removing the menu bar handle separately because it will decide
        // when to remove itself (not removeSelectionHandles)
        getNonVisualChildDecorator().updateState(MouseSelectableChildDecorator.EVENT_HOST_SELECTION_LOST);

    }

    protected void showSelection() {
        super.showSelection();
        // handle adding the menu bar handle separately because it will decide
        // when to remove itself (not removeSelectionHandles
        getNonVisualChildDecorator().updateState(MouseSelectableChildDecorator.EVENT_HOST_SELECTION_RECEIVED);
    }

    /**
	 * child class could override this method.
	 * 
     * @param element 
	 * @param width
	 * @param height
	 * @return the resize command or null  if none
	 */
	protected Command getResizeCommand(IDOMElement element, int width,
			int height) {
		Map map = new HashMap();
		if (width > 0) {
			map.put("width", width + "px"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (height > 0) {
			map.put("height", height + "px"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		if (!map.isEmpty()) {
            return new ChangeStyleCommand(element, map);
		}
        return null;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.gef.editpolicies.ResizableEditPolicy#getResizeCommand(org.eclipse.gef.requests.ChangeBoundsRequest)
	 */
	protected Command getResizeCommand(ChangeBoundsRequest request) {
		ElementEditPart part = (ElementEditPart) this.getHost();

		Rectangle rect = part.getFigure().getBounds();
		rect = request.getTransformedRectangle(rect);
		int width = rect.width;
		int height = rect.height;

		// since the user dragged rectangle included border/padding of the
		// element. And if the element's
		// width/height style setting don't include border padding, then we need
		// to set the element's width/height
		// style property a little smaller.
		if (part.getFigure() instanceof CSSFigure) {
			CSSFigure cssfigure = (CSSFigure) part.getFigure();
			ICSSStyle style = cssfigure.getCSSStyle();
			if (style != null && !style.isSizeIncludeBorderPadding()) {
				width -= (style.getBorderInsets().getWidth() + style
						.getPaddingInsets().getWidth());
				height -= (style.getBorderInsets().getHeight() + style
						.getPaddingInsets().getHeight());
			}
		}

		//make sure to only change the dimensions for the direction of the resize request.
		int resizeDirection = request.getResizeDirection();
		switch (resizeDirection) {
			case PositionConstants.EAST:
			case PositionConstants.WEST:
				//resizing, only the width, so set the height to -1;
				height = -1;
				break;
			case PositionConstants.NORTH:
			case PositionConstants.SOUTH:
				//resizing only the height, so set the width to -1
				width = -1;
				break;
			default:
				//all others are changing both directions...
		}
		return getResizeCommand((IDOMElement) part.getIDOMNode(), width, height);
	}

	/**
	 * Shows or updates feedback for a change bounds request.
	 * 
	 * @param request
	 *            the request
	 */
	protected void showChangeBoundsFeedback(ChangeBoundsRequest request) {
		IFigure feedback = getDragSourceFeedbackFigure();

		PrecisionRectangle rect = new PrecisionRectangle(
				getInitialFeedbackBounds().getCopy());
		getHostFigure().translateToAbsolute(rect);
		rect.translate(request.getMoveDelta());
		rect.resize(request.getSizeDelta());

		// to avoid enlarge feedback pane.
		// when draging a editpart inside designer to move/copy it, we do not
		// want to
		// enlarge the canvas, since that may resulting in relayout.
		rect = (PrecisionRectangle) rect.intersect(getFeedbackLayer()
				.getBounds());

		feedback.translateToRelative(rect);
		feedback.setBounds(rect);
	}

    public Cursor getSelectionToolCursor(Point mouseLocation) {
        // by default return null to indicate system default.  
        // sub-classes should override to customize
        return null;
    }

    /**
     * by default, return null
     * sub-classes should override to customize
     * @param request
     * @return the selectin tracker
     */
    protected DragTracker getSelectionTracker(LocationRequest request)
    {
        return null;
    }
    
    public DragTracker getSelectionDragTracker(LocationRequest request) 
    {
        if (org.eclipse.jst.pagedesigner.requests.PageDesignerRequestConstants.REQ_SELECTION_TRACKER.equals(request.getType())){
            return getSelectionTracker(request);
        }
        
        // be default don't specify a selection drag tracker
        // sub-classes should override to customize
        if (shouldUseObjectMode(request)) {
            return new ObjectModeDragTracker(getHost());
        }
        return new RangeDragTracker(getHost());

    }
}
