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

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

import java.awt.Frame;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Graphics;
import java.awt.Event;
import java.awt.Color;
import java.awt.Cursor;

import java.awt.event.MouseEvent;

import java.util.Vector;
import java.util.Enumeration;


public class ModeSelect extends Mode
{
	/** If the user drags a selection rectangle, this is the first corner */
	private Point selectAnchor  = new Point(0, 0);

	/** This is the seclection rectangle. */
	private Rectangle selectRect = new Rectangle(0,0,0,0);

	/** True when the selection rectangle should be drawn */
	private boolean showSelectRect = false;

	private DiagramElement selected;
	/** Construct a new ModeSelect with the given parent */
	public ModeSelect(Document par,Editor ed)
	{ 
		super(par);
		parent.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		ed.setMessage("Ready. In mode select");
	}
	
	public void setCursorType(){parent.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));}

	public void setMessage(Editor ed){ed.setMessage("Ready. In mode select");}

	public void mouseDown(MouseEvent event)
	{
		int x = event.getX();
		int y = event.getY();
		selectAnchor = new Point(x, y);
		selectRect.setBounds(x, y, 0, 0);
		
		// If mouse is clicked on selected item meaning going for either mouseDrag or simple
		// mouseUp underMouse item is put into selected list
		DiagramElement underMouse = parent.pick(selectAnchor);
		// If mouse clicked on blank canvas deselect previous selection
		if (underMouse == null)
		{
			parent.deselect();
			return;
		}
		// If mouse clicked on some object outside current selection
		if(!parent.selection().contains(underMouse))
		{
			parent.deselect();
			parent.selectItem(underMouse);
		}
	}

	/** On mouse dragging, modify the selection rectangle */
	public void mouseDrag(MouseEvent event)
	{
		int x = event.getX();
		int y = event.getY();
		int changeX = Math.abs(selectAnchor.x - x);
		int changeY = Math.abs(selectAnchor.y - y);
		if(changeX > 3 || changeY > 3)           // if really dragged goto modeModify
		{
			Selection sel = parent.selection();
			if(sel.size()>0) // Mouse down before this occured inside some figure if size>0
			{
				gotoModifyMode(event);
				return;
			}
		}
		showSelectRect = true;
		int bound_x = Math.min(selectAnchor.x, x);
		int bound_y = Math.min(selectAnchor.y, y);
		int bound_w = Math.abs(selectAnchor.x - x);
		int bound_h = Math.abs(selectAnchor.y - y);
		selectRect.setBounds(bound_x, bound_y, bound_w, bound_h);
		parent.damaged(selectRect);
	}

	/** On mouse up, select or toggle the selection of items under the
	* mouse or in the selection rectangle. */
	public void mouseUp(MouseEvent event)
	{
		showSelectRect = false;

		if(selectRect.getSize().width<=1 && selectRect.getSize().height<=1)
		{ //User only clicked so select only one item and stop
			Vector v = parent.selectedDEs();
			if(v.size()<1)
			{
				parent.showDefaultPropertySheet();
				return;
			}
			selected=(DiagramElement)parent.selectedDEs().elementAt(0); //selectionsingle();
			if (selected==null) 
			{
				parent.showDefaultPropertySheet();
				return;
			}
			parent.menuForsingleSelection();
			if (selected instanceof Perspective)
				parent.showVertexPropertySheet((Perspective)selected);
			else
				parent.showEdgePropertySheet((ArcPerspective)selected);
			return;
		}

		Vector selectList = new Vector();
		Enumeration eles = parent.view().contents().elements();
		selected = null;
		while (eles.hasMoreElements())
		{
			DiagramElement de = (DiagramElement) eles.nextElement();
			if (de.intersects(selectRect)) 
				selectList.addElement(de);
		}
		
		switch(selectList.size())   // newly added stuff for menu consistency
		{
			case 0 : 	parent.menuFornoSelection();
						parent.showDefaultPropertySheet();
						break;
			case 1 :	parent.menuForsingleSelection();
						DiagramElement de = (DiagramElement) selectList.firstElement();
						if (de instanceof Perspective)
							parent.showVertexPropertySheet((Perspective)de);
						else
							parent.showEdgePropertySheet((ArcPerspective)de);
						break;
			default:	parent.menuFormultipleSelection();
						parent.showDefaultPropertySheet();
		}
		
		parent.selectItems(selectList);
//		selectRect.grow(1,1); /* make sure it is not empty for redraw */
		parent.damaged(selectRect);
	}
	public void doPopupMenu(MouseEvent event)
	{
		int x = event.getX();
		int y = event.getY();

		selected = parent.pick(new Point(x,y));

		if(selected == null)
		{
			parent.showDefaultPropertySheet();
			return;
		}

		parent.selectItem(selected);
		if(selected instanceof Perspective)
		{
			UVertex uv= (UVertex)selected.owner();
			parent.showTraversalPopup(x,y,uv);
			parent.showVertexPropertySheet((Perspective)selected);
		}
		else
		{
			UEdge ue= (UEdge)((ArcPerspective)selected).owner();
			parent.showTraversalPopup(x,y,ue);
			parent.showEdgePropertySheet((ArcPerspective)selected);
		}
	}

	
	/** Draw this mode by drawing the selection rectangle if appropriate */
	public void draw(Graphics g) 
	{
		if (showSelectRect)
		{
			Color selectRectColor = (Color) Globals.prefs().rubberbandAttrs().get("LineColor");
			g.setColor(selectRectColor);
			g.drawRect(selectRect.x, selectRect.y,selectRect.width, selectRect.height);
		}
	}

	/** Set the Editor's Mode to ModeModify */ 
	private void gotoModifyMode(MouseEvent e)
	{
		Mode m=new ModeModify(parent);
		parent.mode(m);
		m.mouseDown(e);
	}

	public void handleDoubleClick(MouseEvent event)
	{
		int x = event.getX();
		int y = event.getY();
		selectAnchor = new Point(x, y);
		DiagramElement underMouse = parent.pick(selectAnchor);
		// If mouse clicked on blank canvas deselect previous selection
		if (underMouse == null)
			return;
		parent.getEditor().showPropertyWindow(true);
		parent.getEditor().getmenu().setMenuPropertySheetState(true);
	}

} /* end class ModeSelect */

