/*******************************************************************************
 * Copyright (c) 2001, 2006 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.wsdl.ui.internal.asd.design.editparts;

import java.util.Iterator;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.Panel;
import org.eclipse.draw2d.Polygon;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.LayerConstants;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.editpolicies.DirectEditPolicy;
import org.eclipse.gef.requests.DirectEditRequest;
import org.eclipse.swt.graphics.Image;
import org.eclipse.wst.wsdl.ui.internal.adapters.basic.W11ParameterForPart;
import org.eclipse.wst.wsdl.ui.internal.asd.ASDEditorPlugin;
import org.eclipse.wst.wsdl.ui.internal.asd.ASDMultiPageEditor;
import org.eclipse.wst.wsdl.ui.internal.asd.design.DesignViewGraphicsConstants;
import org.eclipse.wst.wsdl.ui.internal.asd.design.directedit.TypeReferenceDirectEditManager;
import org.eclipse.wst.wsdl.ui.internal.asd.design.editpolicies.ASDSelectionEditPolicy;
import org.eclipse.wst.wsdl.ui.internal.asd.design.layouts.RowLayout;
import org.eclipse.wst.wsdl.ui.internal.asd.facade.IParameter;
import org.eclipse.wst.wsdl.ui.internal.asd.util.IOpenExternalEditorHelper;

import org.eclipse.draw2d.MouseMotionListener.Stub;

public class ParameterTypeEditPart extends BaseEditPart implements IFeedbackHandler, INamedEditPart
{   
	protected SimpleDirectEditPolicy simpleDirectEditPolicy = new SimpleDirectEditPolicy();
	  protected Label parameterType;
	  protected RowLayout rowLayout = new RowLayout();

	  protected MyMouseEventListener mouseEventListener;
	  
	  protected IFigure createFigure()
	  {
	    IFigure figure = new Panel();
	    figure.setLayoutManager(rowLayout); 

	    parameterType = new Label();
	    parameterType.setLabelAlignment(Label.LEFT);
	    parameterType.setBorder(new MarginBorder(4,12,4,12));
        figure.add(parameterType);
        
	    return figure;
	  }

	  protected void refreshVisuals()
	  {   
	    super.refreshVisuals();
	    IParameter param = (IParameter) getModel();
	    String name = param.getComponentName();
	    parameterType.setText(name);
        
        
        // TODO (cs) this evil bit of code needs to be fixed post WTP 1.5 when we have more freedom to 
        // clean up our internal code structure.  We shouldn't have hardcoded adapter references here!
        if (getModel() instanceof W11ParameterForPart)
        {
          Image image = ((W11ParameterForPart)getModel()).getSecondaryImage();
          if (image != null)
          {
            parameterType.setIcon(image);
          }            
        }        
        
        if (isReadOnly()) 
        {
          parameterType.setForegroundColor(DesignViewGraphicsConstants.readOnlyLabelColor);
        }
        else
        {
          parameterType.setForegroundColor(ColorConstants.black);
        }          
	  }
	  
	  public void addFeedback() {	 		          
		  figure.setBackgroundColor(DesignViewGraphicsConstants.tableCellSelectionColor);
	  }

	  public void removeFeedback() {
         figure.setBackgroundColor(figure.getParent().getBackgroundColor());
	  }
	  
	  public Label getLabelFigure() {
		  return parameterType;
	  }

	  protected void createEditPolicies()
	  {
		  installEditPolicy(EditPolicy.SELECTION_FEEDBACK_ROLE, new ASDSelectionEditPolicy());
		  installEditPolicy(EditPolicy.DIRECT_EDIT_ROLE, simpleDirectEditPolicy);
	  }
	  
	  public void performDirectEdit(Point cursorLocation) {
		  IParameter param = (IParameter) getModel();
		  
		  TypeReferenceDirectEditManager manager = new TypeReferenceDirectEditManager(param, this, parameterType);   
		  simpleDirectEditPolicy.setDelegate(manager);
		  manager.show();
	  }
	  
	  public void activate() {
		  super.activate();
		  
		  // Setup a MouseMotionListener so we know when to display the 'open in XSD Editor' figure
		  IFigure feedBackLayer = getLayer(LayerConstants.FEEDBACK_LAYER);
		  if (!(feedBackLayer.getLayoutManager() instanceof XYLayout)) {
			  feedBackLayer.setLayoutManager(new XYLayout());					// We could probably move this line elsewhere
		  }
		  
		  IFigure primaryLayer = getLayer(LayerConstants.PRIMARY_LAYER);
		  mouseEventListener = new MyMouseEventListener(getModel());
		  primaryLayer.addMouseMotionListener(mouseEventListener);
		  primaryLayer.addMouseListener(mouseEventListener);
	  }
	  
	  public void deactivate() {
		  if (mouseEventListener != null) {
			  mouseEventListener.discardLinkFigure();
			  IFigure primaryLayer = getLayer(LayerConstants.PRIMARY_LAYER);
			  primaryLayer.removeMouseMotionListener(mouseEventListener);
			  primaryLayer.removeMouseListener(mouseEventListener);
		  }
	  }
	  
	  private class MyLinkFigure extends Polygon {
		  private PointList points = new PointList();
		  public int horizontalBuffer = 4;
		  public int verticalBuffer = 6;

		  public MyLinkFigure() {
			  // Draw the arrow
			  points.addPoint(new Point(horizontalBuffer + 0, 4 + verticalBuffer));
			  points.addPoint(new Point(horizontalBuffer + 9, 4 + verticalBuffer));
			  points.addPoint(new Point(horizontalBuffer + 9, 0 + verticalBuffer));
			  points.addPoint(new Point(horizontalBuffer + 14, 5 + verticalBuffer));
			  points.addPoint(new Point(horizontalBuffer + 9, 10 + verticalBuffer));
			  points.addPoint(new Point(horizontalBuffer + 9, 6 + verticalBuffer));
			  points.addPoint(new Point(horizontalBuffer + 0, 6 + verticalBuffer));
			  points.addPoint(new Point(horizontalBuffer + 0, 4 + verticalBuffer));
			  setFill(true);
		  }

		  public void setLocation(Point newLocation) {
			  PointList translatedPoints = new PointList();
			  
			  for (int index = 0; index < points.size(); index++) {
				  Point origPoint = points.getPoint(index);
				  translatedPoints.addPoint(origPoint.translate(newLocation));
			  }
			  
			  setPoints(translatedPoints);
		  }
	  }
	  
	  private class MyMouseEventListener extends Stub implements MouseListener {
		  private MyLinkFigure linkFigure;
		  private Object object;
		  private IOpenExternalEditorHelper openExternalEditorHelper;
		  
		  public MyMouseEventListener(Object object) {
			  this.object = object;
			  linkFigure = new MyLinkFigure();
			  unemphasizeLinkFigure();
		  }
		  
		  public void mouseMoved(MouseEvent me) {
			  Point pointer = me.getLocation();
			  Rectangle figBounds = getFigure().getParent().getParent().getBounds();
			  
			  if (getExternalEditorOpener().linkApplicable()) {
				  getLayer(LayerConstants.FEEDBACK_LAYER).add(linkFigure);
				  setLinkFigureLocation();
				  if (pointerInRange(figBounds, pointer)) {
					  emphasizeLinkFigure();
				  }
				  else {
					  unemphasizeLinkFigure();
				  }
			  }
			  else {
				  if (containsLinkFigure()) {
					  getLayer(LayerConstants.FEEDBACK_LAYER).remove(linkFigure);
				  }
			  }
		  }
		  
		  private boolean containsLinkFigure() {
			  IFigure figure = getLayer(LayerConstants.FEEDBACK_LAYER);
			  Iterator it = figure.getChildren().iterator();
			  while (it.hasNext()) {
				  Object item = it.next();
				  if (item.equals(linkFigure)) {
					  return true;
				  }
			  }
			  
			  return false;
		  }
		  
		  private Rectangle getLinkFigureBounds() {
			  if (containsLinkFigure()) {
			  return linkFigure.getBounds();
			  }
			  else {
				  return null;
			  }
		  }
		  
		  private boolean pointerInRange(Rectangle figBounds, Point pointer) {
			  Rectangle linkBounds = getLinkFigureBounds();
			  
			  int entireX = figBounds.x;
			  int entireY = figBounds.y;
			  int entireWidth = figBounds.width + linkBounds.width + linkFigure.horizontalBuffer;
			  int entireHeight = figBounds.height;
			  Rectangle entireBounds = new Rectangle(entireX, entireY, entireWidth, entireHeight);

			  return entireBounds.contains(pointer);
		  }
		  
		  protected void setLinkFigureLocation() {
			    Rectangle figureBounds = getFigure().getBounds();
			    int xStart = figureBounds.x + figureBounds.width;
			    int yStart = figureBounds.y;
				  
			    Point aPoint = new Point(xStart, yStart);
			    linkFigure.setLocation(aPoint);
		  }
		  
		  public void discardLinkFigure() {
			  if (containsLinkFigure()) {
				  getLayer(LayerConstants.FEEDBACK_LAYER).remove(linkFigure);
			  }
		  }
		  
		  protected void emphasizeLinkFigure() {
			  linkFigure.setForegroundColor(ColorConstants.blue);
			  linkFigure.setBackgroundColor(ColorConstants.blue);
		  }
		  
		  protected void unemphasizeLinkFigure() {
			  linkFigure.setForegroundColor(ColorConstants.lightGray);
			  linkFigure.setBackgroundColor(ColorConstants.lightGray);
		  }

		  public void mouseReleased(MouseEvent me) { }
		  public void mouseDoubleClicked(MouseEvent me) { }
		  public void mousePressed(MouseEvent me) {
			  Point pointer = me.getLocation();
			  Rectangle linkFigBounds = getLinkFigureBounds();
			  if (linkFigBounds == null) {
				  return;
			  }
			  
			  Rectangle testbounds = new Rectangle(linkFigBounds.x, linkFigBounds.y, 0, linkFigBounds.height);
			  
			  if (getExternalEditorOpener().linkApplicable() && pointerInRange(testbounds, pointer)) {
				  setLinkFigureLocation();
				  // Open in XSD Editor
				  getExternalEditorOpener().openExternalEditor();				  
			  }
		  }
		  
		  private IOpenExternalEditorHelper getExternalEditorOpener() {
			  if (openExternalEditorHelper == null) {
				  openExternalEditorHelper = ((ASDMultiPageEditor) ASDEditorPlugin.getActiveEditor()).getOpenExternalEditorHelper();
				  openExternalEditorHelper.setModel(object);
			  }
			  
			  return openExternalEditorHelper;
		  }
	  }
	  
	  private class SimpleDirectEditPolicy extends DirectEditPolicy 
	  {
	    protected TypeReferenceDirectEditManager delegate;

	    public void setDelegate(TypeReferenceDirectEditManager delegate)
	    {                                           
	      this.delegate = delegate;
	    }

	    protected org.eclipse.gef.commands.Command getDirectEditCommand(final DirectEditRequest request) 
	    { 
	    	return new Command() //AbstractCommand()
	      {
	        public void execute()
	        {                       
	          if (delegate != null)
	          {
	            delegate.performEdit(request.getCellEditor());
	          }  
	        }     
	    
	        public void redo()
	        {
	        }  
	    
	        public void undo()
	        {
	        }     
	    
	        public boolean canExecute()
	        {
	          return true;
	        }
	      };
	    }
	    
	    protected void showCurrentEditValue(DirectEditRequest request) 
	    {      
	    	//hack to prevent async layout from placing the cell editor twice.
	    	getHostFigure().getUpdateManager().performUpdate();
	    }
	  }
	}