// File: ModeCreateAltEdge.java
// Classes: ModeCreateAltEdge
// Author: Kedar Patankar

package edu.neu.ccs.demeter.tools.apstudio.graphedit;

import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.Cursor;
import java.util.Vector;

public class ModeCreateAltEdge extends ModeCreate 
{
	private UVertex sourceNode;
	private int count; // this variable is used to store no of mouseup events. When this becomes 2 time to add

	public ModeCreateAltEdge(Document par)
	{
		super(par);
		parent.setMessage("In mode Create Alternation Edge. Click on the source node and drag it to the destination node");
		count =0;
	}
	
	public void setMessage(Editor ed)
	{
		ed.setMessage("In mode Create Alternation Edge. Click on the source node and drag it to the destination node");
	}

	public void setCursorType()
	{
		parent.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
	}

	public DiagramElement createNewItem(MouseEvent e) 
	{
		return new FigBentLine(e.getX(),e.getY());    
	}
	
	public void mouseDown(MouseEvent event)
	{
		if(count==1) // This is inbetween mousedown
			return;

		DiagramElement underMouse = parent.pick(event.getX(),event.getY());
		parent.deselect();

		if (underMouse != null) 
		{
			if(underMouse instanceof Perspective) 
			{
				sourceNode=(UVertex)((Perspective)underMouse).owner();
				newItem = createNewItem(event);
				parent.selectItem(underMouse);
			}	
		}
		else
			done(); 
	}
	
	public void mouseUp(MouseEvent e) 
	{
		count++;

		if(sourceNode == null)
		{ 
			newItem.damagedIn(parent);
			newItem = null;
			done();
			return;
		}

		DiagramElement de = parent.pick(e.getX(),e.getY());
// if the mouse up happens on the blank surface it means user wants to go for one more iteration of drawing
		if(de==null && count<2) 
		{
			((FigBentLine)newItem).setBendPoint(e.getX(),e.getY());
			return;
		}

		Point midPoint = ((FigBentLine)newItem).getBendPoint();
		
		newItem.damagedIn(parent);
		newItem = null;
		done();

// Checking for illegal conditions
		if(de==null) return;
		if(!(de instanceof Perspective)) return;
		UVertex destNode = (UVertex)((Perspective) de).owner();
		if(destNode == sourceNode) 
		{
			parent.setMessage("Source and destination of the alternation edge are same.");
			return;
		}
		if(sourceNode instanceof UConstVertex && destNode instanceof UConstVertex)
		{
			parent.setMessage("Alternation edge requires at least one alternation vertex.");
			return;
		}
		// checking if source and destination need interchanging
		if(sourceNode instanceof UConstVertex)
		{
			UVertex temp = new UAltVertex();
			temp = destNode;
			destNode = sourceNode;
			sourceNode = temp;
		}// check is complete
		if(destNode.isMultipleAlternation())
		{
			parent.setMessage("Demeter/Java doesn't support multiple inheritance.");
			return;
		}
		if(sourceNode instanceof UAltVertex && destNode instanceof UAltVertex)
		{// checking for bidirectional edging
			Vector v1 = destNode.get_outArcIdList();
			Vector v2 = sourceNode.get_inArcIdList();
			for(int i=0;i<v1.size();i++)
			{
				UID id = (UID)v1.elementAt(i);
				if(v2.contains(id))
				{
					UEdge edge = parent.net().getArc(id);
					if(! (edge instanceof UAltEdge)) 
						continue;
					else
					{
						parent.setMessage("Recursive Inheritance not allowed.");
						return;
					}
				}
			}
		}

// Legality checked. No problem go on make edge.

		Class arcClass;
		UEdge newArc;
		try { arcClass = Class.forName("edu.neu.ccs.demeter.tools.apstudio.graphedit.UAltEdge"); }
		catch (java.lang.ClassNotFoundException ignore) { return; }
		try { newArc = (UEdge)arcClass.newInstance(); }
		catch (java.lang.IllegalAccessException ignore) { return; }
		catch (java.lang.InstantiationException ignore) { return; }
		
		newArc.set_eid(parent.nextId());
//		newArc.connect(sourceNode, destNode);
		newArc.connectAlternation(sourceNode, destNode);
		ArcPerspective ap;
		if(midPoint==null)
			ap=new ArcPerspective(newArc,parent);
		else
			ap=new ArcPerspective(newArc,parent,midPoint);

		parent.showEdgePropertySheet(ap);
		parent.add(ap);
		showDefaultMessage();
		parent.selectItem(ap);
		parent.menuForsingleSelection();
	}

	public void showDefaultMessage(){parent.getEditor().setDefaultMessage();}

} /* end class ModeCreateAltEdge */


