/* $Id: PolygonMode.java 692 2013-04-03 14:20:43Z ohura $ */
package smart_gs.drawing_tool.drawing_mode;

import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;


import smart_gs.debugprint.Debugprint;
import smart_gs.drawing_tool.ExLine2D;
import smart_gs.drawing_tool.SpreadCanvas;
//import smart_gs.drawing_tool.state.DefaultState;
import smart_gs.drawing_tool.state.DefaultState;
import smart_gs.drawing_tool.state.UniSelectedState;
import smart_gs.drawing_tool.view.LineView;
import smart_gs.logical.region.PolygonRegion;
import smart_gs.swingui.GSMouseEvent;
import smart_gs.swingui.toolbar.ImageToolBar;
import smart_gs.util.ImageToolBarSetModeByMouseEvent;

public class PolygonMode extends DrawingModeAdapter{
	
	private static Mode singleton = new PolygonMode();
	
	private Point2D start;
	private Point2D end;
	
	private boolean temporary = false;

	private List<Point2D> points;
	
	private Point2D tempStart;
	private Point2D tempEnd;
	private List<Point2D> tempPoints;
	private List<ExLine2D> lines;

	private Component startcomponent;
	private boolean out = false;
	
	private PolygonMode() {
		this.lines = new ArrayList<ExLine2D>();
		this.points = new ArrayList<Point2D>();
		this.tempPoints = new ArrayList<Point2D>();
	}
	public static Mode getInstance(){
		return singleton;
	}
	
	@Override
	public boolean isTemporary() {
		return temporary;
	}
	@Override
	public void setTemporary(boolean sw) {
		temporary = sw;
	}
	
	@Override
	public void mousePressed(GSMouseEvent e, SpreadCanvas canvas) {
		if (start == null) startcomponent = null;
		if(startcomponent != null && (e.getComponent() != startcomponent)){
			setCursor(canvas);
			return ;
		}
		super.mousePressed(e, canvas);

		if (e.getButton() != MouseEvent.BUTTON1) {
			this.cancel();
			setCursor(canvas);
			return;
		}

		if(this.start == null){
			startcomponent = e.getComponent();
			this.start = e.getPoint();
			this.tempStart = e.getOriginalPoint();
			this.points.add(this.start);
			this.tempPoints.add(this.tempStart);
			setCursor(canvas);
			return;
		}
		this.end = e.getPoint();
		this.tempEnd = e.getOriginalPoint();
		
		this.lines.add(new ExLine2D(start,end));
//		this.lines.add(new ExLine2D(tempStart,tempEnd));
		this.points.add(this.end);
		this.tempPoints.add(this.tempEnd);
		this.start = this.end;
		this.tempStart = this.tempEnd;
		setCursor(canvas);
	}
	@Override
	public void mouseClicked(GSMouseEvent e,SpreadCanvas canvas) {
		if(startcomponent != null && (e.getComponent() != startcomponent)){
			return ;
		}
		if (e.getButton() != MouseEvent.BUTTON1) {
//			this.cancel();
			setCursor(canvas);
			return;
		}
//		super.mouseClicked(e,canvas);

		if(e.getClickCount() == 2){
			double minX, maxX, minY, maxY;
			if (points.size() == 0) {
				setCursor(canvas);
				return;
			}
			else {
				minX = points.get(0).getX();
				maxX = minX;
				minY = points.get(0).getY();
				maxY = minY;
			}
			for (int i=0;i<points.size()-1;i++) {
				minX = Math.min(minX,points.get(i).getX());
				maxX = Math.max(maxX,points.get(i).getX());
				minY = Math.min(minY,points.get(i).getY());
				maxY = Math.max(maxY,points.get(i).getY());
			}
			if (maxX-minX > 10 && maxY-minY > 10) {
				PolygonRegion poly = new PolygonRegion(canvas.getSpread(),this.points);
				poly.setTemporary(this.isTemporary());
				canvas.getSpread().addRegion(poly);
				
				// 2013/03/23 kukita
				// The created region will be automatically selected.
				UniSelectedState.getInstance().changeSelectedRegions(poly);

			}

			this.lines = new ArrayList<ExLine2D>();
			this.points = new ArrayList<Point2D>();
			this.tempPoints = new ArrayList<Point2D>();
			this.start = null;
			this.end = null;
			this.tempStart = null;
			this.tempEnd = null;
			// shayashi 2012.07.07 When a region is drawed, the mode is reset to the default.
			// This prevents unintended region creations and fixes a bug.
//			DefaultState.getInstance().setMode(PolygonMode.getInstance());
			DefaultState.getInstance().setMode(DefaultDrawingMode.getInstance());
			new ImageToolBarSetModeByMouseEvent().setMode(e,ImageToolBar.modeNone);
			setCursor(canvas);
			return;
		}
	}
	@Override
	public void mouseMoved(GSMouseEvent e,SpreadCanvas canvas) {
		if (e.getComponent() == startcomponent) {
			out = false;
		} else {
			out = true;
		}
		setCursor(canvas);
		if(startcomponent != null && (e.getComponent() != startcomponent)){
			return ;
		}
		super.mouseMoved(e,canvas);
		this.end = e.getPoint();
		this.tempEnd = e.getOriginalPoint();
		setCursor(canvas);
	}

	@Override
	public void paint(Graphics g,SpreadCanvas canvas) {
		if (out) return;
		super.paint(g,canvas);	
		if(this.start == null || this.end == null){
			return ;
		}
		double ratio = canvas.getImageLabel().getRatio();
		double gapX = canvas.getImageLabel().getGapWidth();
		double gapY = canvas.getImageLabel().getGapHeight();
		for(int i=0;i<this.lines.size();i++){
			ExLine2D line = this.lines.get(i);
			new LineView(line).enlargedView(ratio,gapX,gapY).draw((Graphics2D)g);
		}

		new LineView(new ExLine2D(start,end)).enlargedView(ratio,gapX,gapY).draw((Graphics2D)g);
		setCursor(canvas);
	}
	@Override
	public void cancel() {
		this.lines = new ArrayList<ExLine2D>();
		this.points = new ArrayList<Point2D>();
		this.tempPoints = new ArrayList<Point2D>();
		this.start = null;
		this.end = null;
		this.tempStart = null;
		this.tempEnd = null;
		return;
	}
}
