package awt;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;

/**
 * Hinzufügen von Pfeilen auf Grafikkontext Graphics g.
 * @author Daniel Weschke
 *
 */
public class Arrow {
	/**
	 * �fnnungswinkel der Pfeilspitze
	 */
	private double ang;
	
	/**
	 * L�nge der Pfeilspitze
	 */
	private double length;
	
	private Color color;

	/**
	 * Konstruktor mit default-Werten.
	 * Spitze 10 px, Winkel 20� und Farbe dunkel grau.
	 */
	Arrow() {
		length = 10;
		ang = 20*Math.PI/180;
		color = new Color(80,80,80);
	}
	
	/**
	 * Form der Pfeilspitze setzen.
	 * �fnnungswinkel min. 5�, L�nge min. 5 px.
	 * @param a �fnnungswinkel der Pfeilspitze
	 * @param len L�nge der Pfeilspitze
	 */
	public void setShape(double a, double len) {
		ang = a;       if(ang<5) ang=5;
		ang *= Math.PI/180;
		length = len;  if(len<5) len=5;
	}

	/**
	 * Farbe nach RGB-Anteile setzen.
	 * @param r Rotanteil
	 * @param g Gr�nanteil
	 * @param b Blauanteil
	 */
	public void setColor(int r, int g, int b) { color = new Color(r,g,b); }

	/**
	 * Farbe setzen.
	 * @param col Color-Objekt
	 */
	public void setColor(Color col) { color = col; }

	/**
	 * Pfeil zeichnen. Vom Anfangspunkt x0, y0 zum Endpunkt x1, y1.
	 * @param g Grafikkontext
	 * @param x0 Startwert x
	 * @param y0 Startwert y
	 * @param x1 Endwert x
	 * @param y1 Endwert y
	 */
	public void draw(Graphics g, double x0, double y0, double x1, double y1){
		// in Pfeilrichtung; rechts Punkt 2, links Punkt 3
	    int ix2, iy2, ix3, iy3;
	    double sinPhi, cosPhi, dx, dy, x, y, s;
	    dx = x1-x0;
	    dy = y1-y0;
	    s = Math.sqrt(dy*dy+dx*dx);
	    sinPhi = dy/s;
	    cosPhi = dx/s;
	    if(s<length) {
	    	x0 = x1 - length*cosPhi;
	    	y0 = y1 - length*sinPhi;
	    }
	    x = -length*Math.cos(ang);
	    y =  length*Math.sin(ang);
	    ix2 = (int)(x1 + x*cosPhi - y*sinPhi);
	    iy2 = (int)(y1 + x*sinPhi + y*cosPhi);
	    ix3 = (int)(x1 + x*cosPhi + y*sinPhi);
	    iy3 = (int)(y1 + x*sinPhi - y*cosPhi);
	    Color c = g.getColor();
	    g.setColor(color);
	    g.drawLine((int)x0,(int)y0,(int)x1,(int)y1);
	    g.drawLine(ix2,iy2,(int)x1,(int)y1);
	    g.drawLine(ix3,iy3,(int)x1,(int)y1);
	    g.setColor(c);
	}
	public void drawBoth(Graphics g, double x0, double y0, double x1, double y1){
	    double sinPhi, cosPhi, dx, dy, x, y, s;
	    dx = x1 - x0;
	    dy = y1 - y0;
	    s = Math.sqrt(dy*dy+dx*dx);
	    sinPhi = dy/s;
	    cosPhi = dx/s;
	    if(s<length) {
	      x0 = x1 - length*cosPhi;
	      y0 = y1 - length*sinPhi;
	    }
	    x = -length*Math.cos(ang);
	    y =  length*Math.sin(ang);
	    draw(g, x0, y0, x1, y1);
	    int ix22, iy22, ix32, iy32;
	    ix22 = (int)(x0 - x*cosPhi + y*sinPhi);
	    iy22 = (int)(y0 - x*sinPhi - y*cosPhi);
	    ix32 = (int)(x0 - x*cosPhi - y*sinPhi);
	    iy32 = (int)(y0 - x*sinPhi + y*cosPhi);
	    
	    Color c = g.getColor();
	    g.setColor(color);
	    g.drawLine(ix22,iy22,(int)x0,(int)y0);
	    g.drawLine(ix32,iy32,(int)x0,(int)y0);
	    g.setColor(c);
	}


  	/**
  	 * Scalierbarer und dick ausgef�llter Pfeil 
  	 * @param screen
  	 * @param x
  	 * @param y
  	 */
  	public final void drawFillArrow(Graphics screen, int x, int y) {
		Graphics2D g = (Graphics2D)screen;
		BasicStroke pen = new BasicStroke(2F,
				BasicStroke.CAP_ROUND, BasicStroke.JOIN_MITER);
		Polygon p = new Polygon();
		double peakLength = 0.4;
		double tailThickness = 0.3;
      
		p.addPoint(1, y/2);
		p.addPoint((int) (x * peakLength), 1);
		p.addPoint((int) (x * peakLength), (int) ((y - (y * tailThickness))/2));
		p.addPoint((x-1), (int) ((y - (y * tailThickness))/2));
      	p.addPoint((x-1), 
      			(int) ((y - (y * tailThickness))/2 + (y * tailThickness)));
      	p.addPoint((int) (x * peakLength), 
      			(int) ((y - (y * tailThickness))/2 + (y * tailThickness)));
      	p.addPoint((int) (x * peakLength), y-1);

      	g.setStroke(pen);
      	g.fillPolygon(p);
      	g.drawPolygon(p);
  	}

}
