/*
 * Created on Aug 10, 2003
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */
package APStudio.editparts;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.draw2d.Connection;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.ManhattanConnectionRouter;
import org.eclipse.draw2d.PolygonDecoration;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.RelativeBendpoint;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.gef.AccessibleEditPart;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.editparts.AbstractConnectionEditPart;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;

import APStudio.models.Connector;
import APStudio.models.ConnectorBendpoint;
/**
 * @author rajags
 *
 * Manages the construction edge.
 * Creates a construction edge object and responds to the
 * property event changes on the object. Called the connector
 * as a general reference.
 */
public class ConnectorEditPart
	extends AbstractConnectionEditPart
	implements PropertyChangeListener {

	AccessibleEditPart acc;

	public static final Color
		dead = new Color(Display.getDefault(),0,74,168),
		alive  = new Color(Display.getDefault(),255,0,0);

	public void activate(){
		super.activate();
		getConnector().addPropertyChangeListener(this);
	}
	
	/**
	 * This method is called when the EditPart is no longuer active.
	 * We use this call to unregister our listener from HelloConnectionModel.
	**/
	public void deactivate(){
	  getConnector().removePropertyChangeListener(this);
	  super.deactivate();
	}

	public void activateFigure(){
		super.activateFigure();
		/*Once the figure has been added to the ConnectionLayer, start listening for its
		 * router to change.
		 */
		getFigure().addPropertyChangeListener(Connection.PROPERTY_CONNECTION_ROUTER, this);
	}			
	/* (non-Javadoc)
	 * @see org.eclipse.gef.editparts.AbstractEditPart#createEditPolicies()
	 */
	protected void createEditPolicies() {
		installEditPolicy(EditPolicy.CONNECTION_ENDPOINTS_ROLE, new ConnectorEndpointEditPolicy());
		//Note that the Connection is already added to the diagram and knows its Router.
		refreshBendpointEditPolicy();
		installEditPolicy(EditPolicy.CONNECTION_ROLE,new ConnectorEditPolicy());

	}

	/**
	 * Returns a newly created Figure to represent the connection.
	 *
	 * @return  The created Figure.
	 */
	protected IFigure createFigure() {
		if (getConnector() == null)
			return null;
		PolylineConnection connx =  new PolylineConnection();
		
		PolygonDecoration decoration = new PolygonDecoration();
		PointList decorationPointList = new PointList();
		decorationPointList.addPoint(0,0);
		decorationPointList.addPoint(-2,2);
		if(getConnector().is_ConOrAlt())
			decorationPointList.addPoint(-2,0);
		else
			decorationPointList.addPoint(0,0);
		decorationPointList.addPoint(-2,-2);
		decoration.setTemplate(decorationPointList);
		decoration.setFill(true);
		if(getConnector().is_ConOrAlt())
			connx.setTargetDecoration(decoration);
		else
			connx.setSourceDecoration(decoration);

		return (Connection) connx;
	}

	public void deactivateFigure(){
		getFigure().removePropertyChangeListener(Connection.PROPERTY_CONNECTION_ROUTER, this);
		super.deactivateFigure();
	}

	public AccessibleEditPart getAccessibleEditPart(){
		if (acc == null)
			acc = new AccessibleGraphicalEditPart(){
				public void getName(AccessibleEvent e) {
					e.result = "Connectors";
				}
			};
		return acc;
	}	
	/* (non-Javadoc)
	 * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
	 */
	public void propertyChange(PropertyChangeEvent arg0) {
		String propName = arg0.getPropertyName();
		if (Connection.PROPERTY_CONNECTION_ROUTER.equals(propName)){
			refreshBendpoints();
			refreshBendpointEditPolicy();
		}
		if ("value".equals(propName)){   //$NON-NLS-1$
			refreshVisuals();
		}
		if ("bendpoint".equals(propName)){   //$NON-NLS-1$
			refreshBendpoints();
		}
	}

	/**
	 * Returns the model of this represented as a Connector.
	 * 
	 * @return  Model of this as <code>Wire</code>
	 */
	protected Connector getConnector() {
		return (Connector)getModel();
	}
	
	/**
	 * Returns the Figure associated with this, which draws the
	 * Connector.
	 *
	 * @return  Figure of this.
	 */
	protected IFigure getConnectorFigure() {
		return (PolylineConnection) getFigure();
	}

	/**
	 * Updates the bendpoints, based on the model.
	 */
	protected void refreshBendpoints() {
		if (getConnectionFigure().getConnectionRouter() instanceof ManhattanConnectionRouter)
			return;
		List modelConstraint = getConnector().getBendpoints();
		List figureConstraint = new ArrayList();
		for (int i=0; i<modelConstraint.size(); i++) {
			ConnectorBendpoint wbp = (ConnectorBendpoint)modelConstraint.get(i);
			RelativeBendpoint rbp = new RelativeBendpoint(getConnectionFigure());
			rbp.setRelativeDimensions(wbp.getFirstRelativeDimension(),
										wbp.getSecondRelativeDimension());
			rbp.setWeight((i+1) / ((float)modelConstraint.size()+1));
			figureConstraint.add(rbp);
		}
		getConnectionFigure().setRoutingConstraint(figureConstraint);
	}

	private void refreshBendpointEditPolicy(){
		if (getConnectionFigure().getConnectionRouter() instanceof ManhattanConnectionRouter)
			installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE, null);
		else
			installEditPolicy(EditPolicy.CONNECTION_BENDPOINTS_ROLE, new ConnectorBendpointEditPolicy());
	}
	
	/**
	 * Refreshes the visual aspects of this, based upon the
	 * model (Wire). It changes the wire color depending on
	 * the state of Wire.
	 * 
	 */
	protected void refreshVisuals() {
		refreshBendpoints();
		if (getConnector().getValue())
			getConnectorFigure().setForegroundColor(alive);
		else
			getConnectorFigure().setForegroundColor(dead);
	}
}
