/*******************************************************************************
 * 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");
		}
		if (height > 0) {
			map.put("height", height + "px");
		}
		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());

    }
}
