/* $Id: MarkerView.java 475 2011-12-02 08:46:54Z ohura $ */
package smart_gs.drawing_tool.view;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;

import javax.swing.ImageIcon;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import smart_gs.GSConstants;
import smart_gs.drawing_tool.ExLine2D;
import smart_gs.drawing_tool.view.View.ViewColor;
import smart_gs.logical.Preference;
import smart_gs.logical.URICreator;
import smart_gs.swingui.WorkspaceWindow;


public class MarkerView extends LineView{
	public static enum MarkerColor{YELLOW, CYAN, MAGENTA, GREEN}
	public static Color MARKER_YELLOW = new Color(Color.YELLOW.brighter().getRed(),Color.YELLOW.brighter().getGreen(),Color.YELLOW.brighter().getBlue(),128);
	public static Color MARKER_CYAN = new Color(0,255,255,128);
	public static Color MARKER_MAGENTA = new Color(255,153,255,128);
	public static Color MARKER_GREEN = new Color(153,255,0,128);

	private int breadth;
	private Color color;
	
	public MarkerView(Point2D start, Point2D end) {
		super(start, end);
		this.color = stringToColor(Preference.getInstance().getMarkerColor());
		this.breadth = new Integer(Preference.getInstance().getMarkerBreadth());
		this.init();
	}
	public MarkerView(ExLine2D line){
		super(line);
		this.color = stringToColor(Preference.getInstance().getMarkerColor());
		this.breadth = new Integer(Preference.getInstance().getMarkerBreadth());
		this.init();
	}
	public MarkerView(ExLine2D line,boolean isSelected,boolean isEmphasized, boolean isProtected){
		this(line);
		this.color = stringToColor(Preference.getInstance().getMarkerColor());
		this.breadth = new Integer(Preference.getInstance().getMarkerBreadth());
		this.isSelected = isSelected;
		this.isEmphasized = isEmphasized;
		this.isProtected = isProtected;
	}
	private void init(){
		Color selectColor = Color.red;
		selectColor = new Color(selectColor.getRed(),selectColor.getGreen(),selectColor.getBlue(),128);
		this.setSelectionColor(selectColor);
		this.setSelectionStroke(new BasicStroke(breadth));
		
		Color protectedColor = color;
		this.setProtectedColor(protectedColor);
		this.setProtectedStroke(new BasicStroke(breadth));
		
		this.defaultColor = color;
		this.defaultStroke = new BasicStroke(breadth);
	}
	@Override
	public int getType() {
		return View.MARKER;
	}
	@Override
	protected void drawShape(Graphics2D g) {
		if (isSelected) {
			g.setColor(this.selectionColor);
		} else if (isEmphasized) {
			g.setColor(this.emphasizeColor);
		} else {
			g.setColor(color);
		}
		g.setStroke(new BasicStroke(breadth));
		g.fill(this.enclosingRect(0));
		if (this.isProtected) {
			g.setColor(Color.BLACK);
			g.setStroke(new BasicStroke(1));
			g.draw(this.enclosingRect(3));
		}
	}

	@Override
	public View enlargedView(double ratio, double gapX, double gapY) {
		Point2D start = this.line.getP1();
		Point2D end = this.line.getP2();
		Point2D p1 = new Point2D.Double(start.getX()*ratio+gapX,start.getY()*ratio+gapY);
		Point2D p2 = new Point2D.Double(end.getX()*ratio+gapX,end.getY()*ratio+gapY);
		MarkerView mview = new MarkerView(new ExLine2D(p1,p2),this.isSelected,this.isEmphasized, this.isProtected);
		mview.color = this.color;
		mview.breadth = (int) (this.breadth*ratio);
		return mview;
	}
	@Override
	public String getTypeString() {
		return URICreator.MARKER;
	}
	@Override
	public boolean contains(Point2D point) {
		return this.enclosingRect(0).contains(point);
	}
	
	@Override
	public Element createXMLElement(Document document) {
		Element element = document.createElement("view");
		element.setAttribute("type",URICreator.MARKER);
		element.setAttribute("x1",this.line.x1+"");
		element.setAttribute("y1",this.line.y1+"");
		element.setAttribute("x2",this.line.x2+"");
		element.setAttribute("y2",this.line.y2+"");
		element.setAttribute("color", colorToString(this.color));
		element.setAttribute("breadth",this.breadth+"");
		return element;
	}
	public static String colorToString(Color c) {
		if (c.equals(MarkerView.MARKER_YELLOW)) {
			return "yellow";
		} else if (c.equals(MarkerView.MARKER_CYAN)) {
			return "cyan";
		} else if (c.equals(MarkerView.MARKER_MAGENTA)){
			return "magenta";
		} else {
			return "green";
		}
	}
	public static Color stringToColor(String s) {
		if (s.equals("yellow")) {
			return MarkerView.MARKER_YELLOW;
		} else if (s.equals("cyan")) {
			return MarkerView.MARKER_CYAN;
		} else if (s.equals("magenta")) {
			return MarkerView.MARKER_MAGENTA;
		} else {
			return MarkerView.MARKER_GREEN;
		}
	}
	@Override
	public void drawLinkedShape(Graphics2D g, Image image) {
		this.draw(g);
		this.drawLinkIcon(g, image);
		return;
	}
	public static MarkerView restore(Element elem) {
		double x1 = new Double(elem.getAttribute("x1"));
		double y1 = new Double(elem.getAttribute("y1"));
		double x2 = new Double(elem.getAttribute("x2"));
		double y2 = new Double(elem.getAttribute("y2"));
		Color col;
		if (elem.hasAttribute("color")) {
			col = stringToColor(elem.getAttribute("color"));
		} else {
			col = stringToColor(Preference.getInstance().getMarkerColor());
		}
		int br;
		if (elem.hasAttribute("breadth")) {
			br = Integer.parseInt(elem.getAttribute("breadth"));
		} else {
			br = new Integer(Preference.getInstance().getMarkerBreadth());
		}
		MarkerView mview =  new MarkerView(new ExLine2D(x1,y1,x2,y2));
		mview.color = col;
		mview.breadth = br;
		return mview;
	}
	@Override
	public Rectangle2D getRectangle2D() {
		double x1 = this.getMinX();
		double x2 = this.getMaxX();
		double y1 = this.getMinY();
		double y2 = this.getMaxY();
		double width = ((BasicStroke)this.defaultStroke).getLineWidth();
		return new Rectangle2D.Double(x1-1,y1-25,(x2-x1),y2-y1+width+50);
	}
	@Override
	public void setViewColor(ViewColor c) {
		switch(c) {
		case YELLOW:
			this.color = MarkerView.MARKER_YELLOW;
			WorkspaceWindow.getInstance().repaint();
			return;
		case CYAN:
			this.color = MarkerView.MARKER_CYAN;
			WorkspaceWindow.getInstance().repaint();
			return;
		case MAGENTA:
			this.color = MarkerView.MARKER_MAGENTA;
			WorkspaceWindow.getInstance().repaint();
			return;
		case GREEN:
			this.color = MarkerView.MARKER_GREEN;
			WorkspaceWindow.getInstance().repaint();
			return;
		default:
			this.color = MarkerView.MARKER_YELLOW;
			WorkspaceWindow.getInstance().repaint();
			return;
		}
	}
	public int getBreadth() {
		return breadth;
	}
	public void setBreadth(int b) {
		this.breadth = b;
		WorkspaceWindow.getInstance().repaint();
	}
	public double length() {
		return line.getP1().distance(line.getP2());
	}
	public Point2D leftPoint() {
		if (this.line.getP1().getX() <= this.line.getP2().getX()) {
			return this.line.getP1();
		} else {
			return this.line.getP2();
		}
	}
	public Point2D rightPoint() {
		if (this.line.getP1().getX() >= this.line.getP2().getX()) {
			return this.line.getP1();
		} else {
			return this.line.getP2();
		}
		
	}
	public double angle() {
		double r = this.length();
		double h = this.rightPoint().getY() - this.leftPoint().getY();
		return Math.asin(h/r);
	}
	public Shape enclosingRect(double margin) {
		double x0 = this.leftPoint().getX();
		double y0 = this.leftPoint().getY();
		double x = x0 - margin;
		double y = y0 - margin;
		double w = this.length() + (margin * 2);
		double h = breadth + margin * 2;
		double theta = angle();
		AffineTransform rotate = AffineTransform.getRotateInstance(theta, x0, y0);
		Rectangle2D rect = new Rectangle2D.Double(x, y, w, h);
		return rotate.createTransformedShape(rect);
	}
	@Override
	public String getTypeStringForDisplay() {
		return "Marker";
	}
	@Override
	public void drawLinkIcon(Graphics2D g, Image image) {
		int x = (int)this.getMaxX();
		int y = (int)this.getMaxY();
		int w = image.getWidth(null) / 3;
		int h = image.getHeight(null) / 3;
		g.drawImage(image, x, y, w, h, null);
	}
}
