/* $Id: DefaultState.java 722 2013-08-05 04:15:48Z shayashi $ */
package smart_gs.drawing_tool.state;

import java.awt.Component;
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.current_text_search.CurrentSearchTextWithoutDialog;
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.tmpDrawingModeSelectionPopupMenu;
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.LineSegEditorDrawMode;
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.logical.FirstIDAT;
import smart_gs.logical.Preference;
import smart_gs.reasoning_web.swingui.GlobalViewPanel;
import smart_gs.smleditor.swingui.GSEditor;
import smart_gs.smleditor.swingui.GSTabbedPane;
import smart_gs.smleditor.swingui.IDATPanel;
import smart_gs.swingui.AbstractGSWindow;
import smart_gs.swingui.GSMouseEvent;
import smart_gs.swingui.WorkspaceWindow;
import smart_gs.swingui.toolbar.GSEditorToolBar;
import smart_gs.swingui.toolbar.ImageToolBar;
import smart_gs.util.ImageToolBarSetModeByMouseEvent;
import smart_gs.util.GSWindowByMouseEvent;

public class DefaultState implements State{
	
	protected static DefaultState singleton = new DefaultState();
	static{
		singleton.addSetmodeEvent(new DefaultStateEvent());
	}
	
	private Mode mode = new DefaultDrawingMode();
	
	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) {
		boolean ctrlPressed = WorkspaceWindow.getInstance().isCtrl();
		boolean altPressed = WorkspaceWindow.getInstance().isAlt();
		boolean shiftPressed = WorkspaceWindow.getInstance().isShift();
		int clickCount = e.getClickCount();
		int button = e.getButton();
		
		// reset the mode to <none>
		if (ctrlPressed && button == MouseEvent.BUTTON1 && clickCount == 1){
			DefaultState.getInstance()
			.setMode(DefaultDrawingMode.getInstance());
			new ImageToolBarSetModeByMouseEvent().setMode(e,ImageToolBar.modeNone);
			changeCursorTo(DefaultDrawingMode.getInstance());
			return;
		}
		
		// mode selection
		if (button == MouseEvent.BUTTON3) {
			if (altPressed) return;
			if (ctrlPressed) return;
			if(shiftPressed){
				tempRegionRightButtonClickAction (e);
			} else {
				rightButtonClickAction (e);
			}
			return;
		}
		
		// mode selection for mouses only with Button1
		if (button == MouseEvent.BUTTON1 && clickCount == 1 && altPressed) {
			if (ctrlPressed) return;
			if(shiftPressed){
				tempRegionRightButtonClickAction (e);
			} else {
				rightButtonClickAction (e);
			}
			return;
		}
			
		// jump to text line
		Mode mode = getMode();
		AbstractGSWindow window = (new GSWindowByMouseEvent()).getWindow(e);
		if (button == MouseEvent.BUTTON1 && clickCount == 2 
				&& !ctrlPressed && !altPressed && !shiftPressed
				&& mode instanceof DefaultDrawingMode) {
			int index = canvas.getImageLabel().getLineIndex(e.getX(),e.getY());
			if (index>=0) {
				if (window instanceof WorkspaceWindow) {
					GSTabbedPane wrkspcwindowTabbedPane= WorkspaceWindow.getInstance().getTabbedPane();
					wrkspcwindowTabbedPane.setSelectedIndex(0);
					IDATPanel fstIdatPanel = (IDATPanel)wrkspcwindowTabbedPane.getSelectedComponent();
					GSEditorToolBar toolbar = fstIdatPanel.getGSEditorToolBar();
					((WorkspaceWindow)window).getGSEditorToolBar().getEditorTextPane().highlightOff();
					CurrentSearchTextWithoutDialog.search(toolbar,"$" + index + "$");
				} else if (window instanceof GSEditor){
					GSEditor editor = (GSEditor)window;
					GSTabbedPane editorTabbedPane = editor.getTabbedPane();
					editorTabbedPane.setSelectedIndex(0);
					IDATPanel fstIdatPanel = editorTabbedPane.getFirstIDATPanel();
					editorTabbedPane.setSelectedComponent(fstIdatPanel);
					GSEditorToolBar toolbar = fstIdatPanel.getGSEditorToolBar();
					editorTabbedPane.getFirstIDAT().highlightOff();
					CurrentSearchTextWithoutDialog.search(toolbar,"$" + index + "$");
				}
			}
		} else {
			this.mode.mouseClicked(e,canvas);
		}
		
		// default
		this.mode.mouseClicked(e,canvas);
	}

	private void tempRegionRightButtonClickAction(GSMouseEvent e) {
		JPopupMenu menu = new tmpDrawingModeSelectionPopupMenu(e);;
		menu.show(e.getComponent(),e.getOriginalPoint().x,e.getOriginalPoint().y);
		GlobalViewPanel.getInstance().repaint();
	}

	private void rightButtonClickAction (GSMouseEvent e) {
		JPopupMenu menu = new DrawingModeSelectionPopupMenu(e);;
		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 (addingMarkup()) {
			return;
		}
		if (!WorkspaceWindow.getInstance().isAlt() 
				&& canvas.containRegions(e.getPoint())) {
			this.mode.cancel();
			State state = UniSelectedState.getInstance();
			ImageLabel.setState(state);
			state.mousePressed(e, canvas);
		}
	}

	public boolean addingMarkup() {
//		return mode == RectangleMode.getInstance()
//		|| mode == PolygonMode.getInstance()
//		|| mode == MarkerMode.getInstance()
//		|| mode == MemoPadMode.getInstance()
//		|| mode == BookmarkMode.getInstance()
//		|| mode == AnchorMode.getInstance()
//		|| mode == LineSegEditorDrawMode.getInstance();
		return mode.addingMarkup() || mode instanceof LineSegEditorDrawMode;
	}

	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.getScaledInstance(60, 60, Image.SCALE_DEFAULT), hotSpot, name));
		} else if (mode instanceof BookmarkMode) {
			ImageIcon imageIcon = new ImageIcon(GSConstants.ICON_PATH+Preference.getInstance().getDefaultBookmarkPath());
			Image img = imageIcon.getImage();
			hotSpot = new Point(10,30);
			String name = "bookmark_cursor";
			this.setCursor(kit.createCustomCursor(img.getScaledInstance(70, 70, Image.SCALE_DEFAULT), 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.getScaledInstance(70, 70, Image.SCALE_DEFAULT), 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.getScaledInstance(48, 48, Image.SCALE_DEFAULT), 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.getScaledInstance(70, 70, Image.SCALE_DEFAULT), hotSpot, name));
		} else {
			this.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
		}
		
	}

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

	public Cursor getCursor() {
		return cursor;
	}

}
