import java.awt.*;


public class ShowAngle extends Canvas {
    private static final Color bgcolor = new Color(236,236,236);

    private Mod1State state;
    private int width, height;
    private int xcent, ycent;
    private Image im;
    private Graphics buf;
    private boolean display;
    private int x[], y[];
    public ShowAngle(Mod1State state){
	super();
	setBackground(bgcolor);
        this.state = state;
	display = false;
    }
    
    public void paint(Graphics g){
	xcent=getSize().width/2;
	ycent=getSize().height/2;
	width=2*xcent;
	height=2*ycent;
	if(im == null){
	    im = createImage(getSize().width,getSize().height);
	    buf = im.getGraphics();
	    drawArrow(buf);
	}
	drawArrow(buf);
    	g.drawImage(im,0,0,null);
    }

    
    private void drawArrow(Graphics g){
        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

	if(!display){
            g.clearRect(0,0,getSize().width-1,getSize().height-1);
	} else {
            g.clearRect(0,0,getSize().width-1,getSize().height-1);
            //g.drawLine(0,0,0,getSize().height-1);
            //g.drawLine(0,0,getSize().width-1,0);
            //g.drawLine(getSize().width-1,0,
            //           getSize().width-1,getSize().height-1);
            //g.drawLine(0,getSize().height-1,
            //           getSize().width-1,getSize().height-1);
            double from[] = new double[2];
            double to[] = new double[2];
            from[0] = -xcent+8;
            to[0] = xcent-8;
            from[1] = 0;
            to[1] = 0;
            plot_arrowline_local(g,from,to);
        }
    }

        
    
    public synchronized void reset(){
        display = false;
	repaint();
    }

    public synchronized void draw() {
        display = true;
        repaint();
    }
    
    
    public void update(Graphics g){
	paint(g);
    }




    private void plot_arrowline_local(Graphics imG,double from[], double to[]) {
        // from(2)           !  x,y coords in inches
        // to(2)             !  x,y coords in inches

        double x[] = new double[7];
        double y[] = new double[7];
        double dto[] = new double[2];

        double theta, L, lw, hw;
        // lw is linewidth in inches
        // hw is (headwidth-1)/2
            
        int i;
        double linewidth, headwidth;

        linewidth=3.0;
        headwidth=5.0;
        lw = linewidth;    //linewidth in pixels
        hw = (headwidth-1.0)*0.5;

        // angle of the arrowhead:
        dto[0] = to[0] - from[0];
        dto[1] = to[1] - from[1];
        //theta = Math.atan2(dto[1],dto[0]);
        theta = state.bfieldThetaAtCursor;

        // calc the arrowhead starting at 0,0, and going to L,0
        L = Math.sqrt((dto[0]*dto[0]) + (dto[1]*dto[1]));

        x[0] = 0.0;
        y[0] = 0.5*lw;
        x[1] = L-(headwidth-1.0)*lw;
        y[1] = y[0];
        x[2] = x[1];
        y[2] = y[1]+hw*lw*0.6;
        x[3] = L;
        y[3] = 0.0;
        // mirror the top to the bottom:
        x[4] = x[2];
        y[4] = -1.0*y[2];
        x[5] = x[1];
        y[5] = -1.0*y[1];
        x[6] = x[0];
        y[6] = -1.8*y[0];
        
        //rotate_polyline(x,y,theta,xcent/2,0.0);
        rotate_polyline(x,y,theta,12,1.5);
        translate_polyline(x,y,xcent/2,ycent);


        // Draw the arrow (fill the polygon):
        int ix[] = new int[x.length];
        int iy[] = new int[y.length];
        for (i=0; i<x.length; i++) {
            ix[i] = (int)x[i];
            iy[i] = (int)y[i];
        }
        // Outline the arrow:
        //imG.setColor(Color.black);
        //imG.setColor(Color.blue);
        imG.setColor(Color.orange.darker());
        //imG.drawPolygon(ix,iy, x.length);
        imG.fillPolygon(ix,iy, x.length);

        return;
    }



    private void rotate_polyline(double x[], double y[], double theta,
                                 double xcent, double ycent) {
        //  x(n),y(n) are coordinates of each point
        //  theta is the amount to rotate points counterclockwise, radians
        // xcent, ycent  is the center of rotation
        double xx, yy;
        int i;
        for (i=0; i<x.length; i++) {
            xx = (x[i]-xcent)*Math.cos(theta) - (ycent-y[i])*Math.sin(theta);
            yy = (x[i]-xcent)*Math.sin(theta) + (ycent-y[i])*Math.cos(theta);
            x[i] = xx+xcent;
            y[i] = ycent-yy;
        }
        return;
    }


    
    private void translate_polyline(double x[], double y[], 
                                    double dx, double dy) {
        // x(n),y(n) are coordinates of each point
        // dx,dy     are amount to translate points
        
        int i;
        for (i=0; i<x.length; i++) {
            x[i] = x[i] + dx;
            y[i] = y[i] + dy;
            //y[i] = dy - y[i];
        }
        return;
    }    
}
