package org.eclipse.stp.bpmn.diagram.edit.parts;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.geometry.Dimension;
import org.eclipse.draw2d.geometry.Insets;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gmf.runtime.common.ui.services.parser.CommonParserHint;
import org.eclipse.gmf.runtime.diagram.ui.editparts.ShapeNodeEditPart;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.EditPolicyRoles;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.OpenDiagramEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.editpolicies.ViewComponentEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.figures.NoteFigure;
import org.eclipse.gmf.runtime.diagram.ui.internal.editpolicies.DiagramLinkDragDropEditPolicy;
import org.eclipse.gmf.runtime.diagram.ui.internal.editpolicies.NonSemanticEditPolicy;
import org.eclipse.gmf.runtime.draw2d.ui.figures.ConstrainedToolbarLayout;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.IMapMode;
import org.eclipse.gmf.runtime.draw2d.ui.mapmode.MapModeUtil;
import org.eclipse.gmf.runtime.gef.ui.figures.DefaultSizeNodeFigure;
import org.eclipse.gmf.runtime.gef.ui.figures.NodeFigure;
import org.eclipse.gmf.runtime.notation.View;
import org.eclipse.stp.bpmn.policies.ResizableActivityEditPolicy;

/**
 * Future TextAnnotations editpart.
 * @author jcorchis
 */
public class TextAnnotationEditPart extends ShapeNodeEditPart {

    /**
     * constructor
     * @param view the view controlled by this edit part
     */
    public TextAnnotationEditPart(View view) {
        super(view);
    }

    /**
     * Creates a note figure.
     */
    protected NodeFigure createNodeFigure() {
        IMapMode mm = getMapMode();
        Insets insets = new Insets(mm.DPtoLP(5), mm.DPtoLP(10), mm.DPtoLP(5), mm.DPtoLP(14));
        TextAnnotationFigure noteFigure = new TextAnnotationFigure(mm.DPtoLP(50), mm.DPtoLP(30), insets);
        return noteFigure;
    }

    /** Adds support for diagram links. */
    protected void createDefaultEditPolicies() {
        super.createDefaultEditPolicies();

        // Remove semantic edit policy and install a non-semantic edit policy
        removeEditPolicy(EditPolicyRoles.SEMANTIC_ROLE);
        installEditPolicy(EditPolicyRoles.SEMANTIC_ROLE,
            new NonSemanticEditPolicy());

        // Add Note support for diagram links
        // The following two edit policies support the links.       
        installEditPolicy(
            EditPolicyRoles.DRAG_DROP_ROLE,
            new DiagramLinkDragDropEditPolicy());
        
        installEditPolicy(
            EditPolicyRoles.OPEN_ROLE,
            new OpenDiagramEditPolicy());

        // This View doesn't have semantic elements so use a component edit
        // policy that only gets a command to delete the view
        installEditPolicy(
            EditPolicy.COMPONENT_ROLE,
            new ViewComponentEditPolicy());
        
        // replace ConnectionHandleEditPolicy with our own
        

    }
    
    /**
     * this method will return the primary child EditPart  inside this edit part
     * @return the primary child view inside this edit part
     */
    public EditPart getPrimaryChildEditPart(){
        return getChildBySemanticHint(CommonParserHint.DESCRIPTION);
    }
    
    /**
     * @notgenerated This is what creates the custom selection shape.
     */
    @Override
    public EditPolicy getPrimaryDragEditPolicy() {
        return new ResizableActivityEditPolicy();
    }

    
}
/**
 * @author hmalphettes @see {@link NoteFigure}
 * @author <a href="http://www.intalio.com">&copy; Intalio, Inc.</a>
 */
class TextAnnotationFigure extends DefaultSizeNodeFigure {
    
    /**
     * Constructor
     * 
     * @param width <code>int</code> value that is the default width in logical units
     * @param height <code>int</code> value that is the default height in logical units
     * @param insets <code>Insets</code> that is the empty margin inside the note figure in logical units
     */
    public TextAnnotationFigure(int width, int height, Insets insets) {
        super(width, height);
        setBorder(
            new MarginBorder(insets.top, insets.left, insets.bottom, insets.right));

        ConstrainedToolbarLayout layout = new ConstrainedToolbarLayout();
        layout.setMinorAlignment(ConstrainedToolbarLayout.ALIGN_TOPLEFT);
        layout.setSpacing(insets.top);
        setLayoutManager(layout);
    }
    
    protected void paintFigure(Graphics graphics) {
        int lineWidth = MapModeUtil.getMapMode(this).LPtoDP(1);
        graphics.setForegroundColor(ColorConstants.black);
        graphics.setLineWidth(lineWidth);
        Rectangle rect = getBounds().getCopy();
        rect.height--;
        rect.width = Math.min(rect.width, MapModeUtil.getMapMode(this).LPtoDP(30));
        PointList pl = new PointList();
        pl.addPoint(rect.getTop());
        pl.addPoint(rect.getTopLeft());
        pl.addPoint(rect.getBottomLeft());
        pl.addPoint(rect.getBottom());
        graphics.drawPolyline(pl);
    }

    /**
     * @see org.eclipse.draw2d.IFigure#getPreferredSize(int, int)
     */
    public Dimension getPreferredSize(int wHint, int hHint) {
        return super.getPreferredSize(wHint, hHint).getUnioned(new Dimension(
                                MapModeUtil.getMapMode(this).DPtoLP(50), 
                                MapModeUtil.getMapMode(this).DPtoLP(30)));
    }

}