//package maestro.lib.graphics;
//PolarCanvas.java
//Singh T. Junior and Umberto Ravaioli
//NCCE, Beckman Institute

import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.lang.*;
//import maestro.lib.graphics.*;
//import maestro.lib.math.*;

public class PolarCanvas extends Canvas implements Runnable{
	//private static final Color acolor = new Color(196,196,171);
	//private static final Color acolor = new Color(152,152,152);
	private static final Color ccolor = new Color(230,230,230);
	private static final Color acolor = new Color(176,176,176);
	private Image im;
	private Graphics buf;
	private int rcx, rcy, raio;
	private Polarization_State state;
	Thread tron;
	private boolean isTronRunning;
	public int SleepTime = 10;

	public PolarCanvas(){
		super();
                setBackground(acolor);
		isTronRunning = false;
		state = new Polarization_State();
	}
	
	public void paint(Graphics g){
	    if(im == null){
		im = createImage(getSize().width,getSize().height);
		buf = im.getGraphics();
		drawCanvas(buf);
		drawState(buf);
	    }
	    else{
		drawCanvas(buf);
		drawState(buf);
	    }
	    g.drawImage(im,0,0,null);
	    state.preset();
	}
	
	private void drawCanvas(Graphics g){
		double resmag, resphase;
		g.setColor(Color.black);
		//g.draw3DRect(0,0,getSize().width-1,getSize().height-1,false);
		rcx=getSize().width/2;
		rcy=getSize().height/2;
		raio=(75*getSize().width/200);
		g.setColor(acolor);
		if(state.RESET){g.fillRect(0,0,getSize().width-1,getSize().height-1);}
		
		//draw axis system
		g.setColor(Color.black);
		g.drawLine(getSize().width/2,10,getSize().width/2,getSize().height-11);
		g.drawLine(10,getSize().height/2,getSize().width-11,getSize().height/2);
		g.drawLine(getSize().width-44,getSize().height/2+5,getSize().width-44,getSize().height/2-5);
		g.drawLine(getSize().width/2-5,44,getSize().width/2+5,44);
		g.drawLine(44,getSize().height/2+5,44,getSize().height/2-5);
		g.drawLine(getSize().width/2-5,getSize().height-45,getSize().width/2+5,getSize().height-45);
		
		MaestroG.drawArrow(getSize().width-15,getSize().height/2,7,g);
		MaestroG.drawArrow(getSize().width/2,13,5,g);
	    
		g.drawString("X",getSize().width-20,getSize().height/2+20);
		g.drawString("Y",getSize().width/2-20,15);		
	}	
	
	public void drawState(Graphics g){
	   double resmag;
                
		rcx=getSize().width/2;
		rcy=getSize().height/2;
		raio=(75*getSize().width/200);
		
		//draw the resultant vector
		resmag=Math.sqrt(
                        state.ampAA*Math.cos(state.phaseAA+state.wt) *  state.ampAA*Math.cos(state.phaseAA+state.wt)
		     +  state.ampBB*Math.cos(state.phaseBB+state.wt) *  state.ampBB*Math.cos(state.phaseBB+state.wt)
		);
		g.setColor(acolor);

		g.setXORMode(getBackground());
		
		//Paint tracer on path 

		//Delete old tracer
		g.setColor(acolor);
                //Delete old x and y components
		g.setPaintMode();
		
                Graphics2D g2d = (Graphics2D)g;
                //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                if(!state.isTracerOn){
                    g.fillOval((int)(rcx-2+raio*state.ampAA*Math.cos(state.phaseAA+(state.wt-state.dwt)))-2,
                           (int)(rcy-2-raio*state.ampBB*Math.cos(state.phaseBB+(state.wt-state.dwt)))-2,10,10);
                }
                //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
                		
		//Paint new tracer
		
		resmag=Math.sqrt(
                        state.ampA*Math.cos(state.phaseA+state.wt) *  state.ampA*Math.cos(state.phaseA+state.wt)
		     +  state.ampB*Math.cos(state.phaseB+state.wt) *  state.ampB*Math.cos(state.phaseB+state.wt)
		     );
		
		//Draw axes
		g.setColor(Color.black);
		g.setPaintMode();
		g.drawLine(getSize().width/2,10,getSize().width/2,getSize().height-11);
		g.drawLine(10,getSize().height/2,getSize().width-11,getSize().height/2);
		
		g.setColor(acolor);
                //Delete old x and y components
		g.setPaintMode();
		g.drawLine(getSize().width/2+1,45,getSize().width/2+1,getSize().height-46);
		g.drawLine(45,getSize().height/2-1,getSize().width-45,getSize().height/2-1);
		g.drawLine(getSize().width/2-1,45,getSize().width/2-1,getSize().height-46);
		g.drawLine(45,getSize().height/2+1,getSize().width-45,getSize().height/2+1);
		g.drawLine(getSize().width/2+2,45,getSize().width/2+2,getSize().height-46);
		g.drawLine(getSize().width/2-2,45,getSize().width/2-2,getSize().height-46);
		g.drawLine(45,getSize().height/2-2,getSize().width-45,getSize().height/2-2);
		g.drawLine(45,getSize().height/2+2,getSize().width-45,getSize().height/2+2);
		
		g.setColor(Color.red);
                //g.setPaintMode();
		g.drawLine(rcx+1,rcy,rcx+1,(int)(rcy-raio*state.ampB*Math.cos(state.phaseB+state.wt)));
		g.drawLine(rcx+2,rcy,rcx+2,(int)(rcy-raio*state.ampB*Math.cos(state.phaseB+state.wt)));
		g.drawLine(rcx-1,rcy,rcx-1,(int)(rcy-raio*state.ampB*Math.cos(state.phaseB+state.wt)));
		g.drawLine(rcx-2,rcy,rcx-2,(int)(rcy-raio*state.ampB*Math.cos(state.phaseB+state.wt)));

		g.setColor(Color.green);
		//g.setPaintMode();
		g.drawLine(rcx,rcy+1,(int)(rcx+raio*state.ampA*Math.cos(state.phaseA+state.wt)),rcy+1);
		g.drawLine(rcx,rcy+2,(int)(rcx+raio*state.ampA*Math.cos(state.phaseA+state.wt)),rcy+2);
		g.drawLine(rcx,rcy-1,(int)(rcx+raio*state.ampA*Math.cos(state.phaseA+state.wt)),rcy-1);
		g.drawLine(rcx,rcy-2,(int)(rcx+raio*state.ampA*Math.cos(state.phaseA+state.wt)),rcy-2);
		
                //Draw resultant vector 

		//Repaint old line 
		if(!state.isTracerOn){
			g.setColor(acolor);
		}
		else {
			g.setColor(ccolor);
		}
		
                int rad = 5;
                int rad2 = 4; 
		g.drawLine(rcx,rcy,(int)(rcx+(raio-rad)*state.ampA*Math.cos(state.phaseA+(state.wt-state.dwt))),
                                   (int)(rcy-(raio-rad)*state.ampB*Math.cos(state.phaseB+(state.wt-state.dwt))));

		//Paint new line 
		g.setColor(Color.magenta);
		
		g.drawLine(rcx,rcy,(int)(rcx+(raio-rad)*state.ampA*Math.cos(state.phaseA+state.wt)),
                                   (int)(rcy-(raio-rad)*state.ampB*Math.cos(state.phaseB+state.wt)));
		//Paint new tracer
		g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                g.setColor(Color.yellow);
		g.fillOval((int)(rcx-2+raio*state.ampA*Math.cos(state.phaseA+state.wt)),
                           (int)(rcy-2-raio*state.ampB*Math.cos(state.phaseB+state.wt)),rad2,rad2);		
		g.setColor(Color.black);
                g.drawOval((int)(rcx-2+raio*state.ampA*Math.cos(state.phaseA+state.wt)),
                           (int)(rcy-2-raio*state.ampB*Math.cos(state.phaseB+state.wt)),rad2,rad2);		
		
                g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
                
		g.setColor(Color.black);
		g.drawLine(getSize().width-44,getSize().height/2+5,getSize().width-44,getSize().height/2-5);
		g.drawLine(getSize().width/2-5,44,getSize().width/2+5,44);
		g.drawLine(44,getSize().height/2+5,44,getSize().height/2-5);
		g.drawLine(getSize().width/2-5,getSize().height-45,getSize().width/2+5,getSize().height-45);

		//state.push();
		state.phaseAA=state.phaseA;
		state.phaseBB=state.phaseB;
		state.ampAA=state.ampA;
		state.ampBB=state.ampB;
	}
	
	
	public void update(Graphics g){
		paint(g);
	}
	
	
	public void start(){
		if(tron == null){
		    tron = new Thread(this);
		    tron.start();
		}
	}
	
	public void stop(){
		if(tron != null){
		    //tron.stop();
		    tron = null;
		}
	}
	
	
	public void run(){
	    while(true){
		try{
		    Thread.sleep(SleepTime);
		}
		catch(InterruptedException e){e.printStackTrace();}   
		if(isTronRunning){
		    repaint();
		    state.increment();
		}
	    }
	}
	
	public void pause(boolean tmp){
	    if(tmp){
		isTronRunning = false;
		//tron.suspend();
	    }
	    else {
		isTronRunning = true;
		//tron.resume();
	    }
	}
	
	public void setSleepTime(int SleepTime){
	
	    this.SleepTime = SleepTime;
	}
	
	public synchronized void setState(Polarization_State state){
	    this.state = state;
	}
}
