/* $Id: DefaultState.java 476 2011-12-02 08:52:40Z ohura $ */
package smart_gs.drawing_tool.state;

import java.awt.Cursor;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.ImageIcon;
import javax.swing.JPopupMenu;

import smart_gs.GSConstants;
import smart_gs.debugprint.Debugprint;
import smart_gs.drawing_tool.DrawingModeSelectionPopupMenu;
import smart_gs.drawing_tool.ImageLabel;
import smart_gs.drawing_tool.RightClickMenu;
import smart_gs.drawing_tool.SpreadCanvas;
import smart_gs.drawing_tool.drawing_mode.AnchorMode;
import smart_gs.drawing_tool.drawing_mode.BookmarkMode;
import smart_gs.drawing_tool.drawing_mode.DefaultDrawingMode;
import smart_gs.drawing_tool.drawing_mode.EraserMode;
import smart_gs.drawing_tool.drawing_mode.MarkerMode;
import smart_gs.drawing_tool.drawing_mode.MemoPadMode;
import smart_gs.drawing_tool.drawing_mode.Mode;
import smart_gs.drawing_tool.drawing_mode.PolygonMode;
import smart_gs.drawing_tool.drawing_mode.RectangleMode;
import smart_gs.reasoning_web.swingui.GlobalViewPanel;
import smart_gs.swingui.GSMouseEvent;
import smart_gs.swingui.WorkspaceWindow;
import smart_gs.swingui.toolbar.ImageToolBar;

public class DefaultState implements State{
	
	protected static DefaultState singleton = new DefaultState();
	static{
		singleton.addSetmodeEvent(new DefaultStateEvent());
	}
	
	private Mode mode;
	
	private ArrayList<StateEvent> eventList = new ArrayList<StateEvent>();
	
	private Cursor cursor;
	
	protected DefaultState(){
		this.mode = DefaultDrawingMode.getInstance();
		this.setCursor(Cursor.getDefaultCursor());
	}
	
	public static DefaultState getInstance(){
		return singleton;
	}
	public void setMode(Mode mode){
		this.mode.cancel();
		this.mode = mode;
		for(int i=0;i<eventList.size();i++){
			StateEvent stateEvent = eventList.get(i);
			stateEvent.setMoveEvent(mode);
		}
		changeCursorTo(mode);
	}
	public static void setDefaultState(DefaultState state){
		singleton = state;
		ImageLabel.setState(state);
	}
	public static void restoreDefaultState(){
		singleton = new DefaultState();
		ImageLabel.setState(singleton);
	}
	public void mouseClicked(GSMouseEvent e, SpreadCanvas canvas) {
		if (e.getButton() == MouseEvent.BUTTON1) {
			if (WorkspaceWindow.getInstance().onlyOneOfAltCtrlShiftIsPressed()) {
				if(WorkspaceWindow.getInstance().isAlt()){
					/* alternative for right button click */
					rightButtonClickAction(e);					
				} else if(WorkspaceWindow.getInstance().isCtrl()){
					DefaultState.getInstance()
					.setMode(DefaultDrawingMode.getInstance());
					ImageToolBar.setModeListItem(ImageToolBar.modelistarray[ImageToolBar.modeNone]);
				} 
			} else {
				this.mode.mouseClicked(e,canvas);
			}
		} else if (e.getButton() == MouseEvent.BUTTON3) {
			rightButtonClickAction (e);
		} else {
			this.mode.mouseClicked(e,canvas);
		}
	}

	private void rightButtonClickAction (GSMouseEvent e) {
		JPopupMenu menu = new DrawingModeSelectionPopupMenu();;
		menu.show(e.getComponent(),e.getOriginalPoint().x,e.getOriginalPoint().y);
		GlobalViewPanel.getInstance().repaint();
	}
		
	public void mouseDragged(GSMouseEvent e, SpreadCanvas canvas) {
		this.mode.mouseDragged(e,canvas);
	}

	public void mouseEntered(GSMouseEvent e, SpreadCanvas canvas) {
		this.mode.mouseEntered(e,canvas);
	}

	public void mouseExited(GSMouseEvent e, SpreadCanvas canvas) {
		this.mode.mouseExited(e,canvas);
	}

	public void mouseMoved(GSMouseEvent e, SpreadCanvas canvas) {
		mode.mouseMoved(e,canvas);		
	}

	public void mousePressed(GSMouseEvent e, SpreadCanvas canvas) {
		if (mode != EraserMode.getInstance()) {
			mode.mousePressed(e, canvas);
		}
		canvas.getSpread().clearSelection();
		if (!WorkspaceWindow.getInstance().isAlt() && canvas.containRegions(e.getPoint())) {
			this.mode.cancel();
			State state = UniSelectedState.getInstance();
			ImageLabel.setState(state);
			state.mousePressed(e, canvas);
		}
	}

	public void mouseReleased(GSMouseEvent e, SpreadCanvas canvas) {
		mode.mouseReleased(e, canvas);
	}

	public void paint(Graphics g, SpreadCanvas canvas) {
		mode.paint(g,canvas);
	}

	public Mode getMode() {
		return this.mode;
	}
	
	public void addSetmodeEvent(StateEvent stateEvent){
		if(stateEvent != null){
			eventList.add(stateEvent);
		}
	}

	@Override
	public int getType() {
		return State.DEFAULT;
	}

	
	public void changeCursorTo(Mode mode) {
		Point hotSpot = new Point(0, 0);
		Toolkit kit = Toolkit.getDefaultToolkit();
		if (mode instanceof DefaultDrawingMode) {
			this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		} else if (mode instanceof RectangleMode) {
			this.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
		} else if (mode instanceof PolygonMode) {
			this.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
		} else if (mode instanceof AnchorMode) {
			Image img = new ImageIcon(GSConstants.ICON_PATH+"anchor_cursor.png").getImage();
			String name = "anchor_cursor";
			this.setCursor(kit.createCustomCursor(img, hotSpot, name));
		} else if (mode instanceof BookmarkMode) {
			ImageIcon imageIcon = new ImageIcon(GSConstants.ICON_PATH+"bookmark.png");
			Image img = imageIcon.getImage();
			hotSpot = new Point(10,30);
			String name = "bookmark_cursor";
			this.setCursor(kit.createCustomCursor(img, hotSpot, name));
		} else if (mode instanceof EraserMode) {
			Image img = new ImageIcon(GSConstants.ICON_PATH+"eraser.png").getImage();
			String name = "eraser_cursor";
			this.setCursor(kit.createCustomCursor(img, new Point(5,5), name));
		} else if (mode instanceof MemoPadMode) {
			Image img = new ImageIcon(GSConstants.ICON_PATH+"memopad_cursor.png").getImage();
			String name = "memopad_cursor";
			this.setCursor(kit.createCustomCursor(img, hotSpot, name));
		} else if (mode instanceof MarkerMode) {
			Image img = new ImageIcon(GSConstants.ICON_PATH+"marker_cursor.png").getImage();
			String name = "marker_cursor";
			hotSpot = new Point(0,30);
			this.setCursor(kit.createCustomCursor(img, hotSpot, name));
		} else {
			this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		}
		
	}

	public void setCursor(Cursor cursor) {
		this.cursor = cursor;
	}

	public Cursor getCursor() {
		return cursor;
	}

}
