package primitives.spaces;
import java.awt.*;
import primitives.machines.*;
import primitives.geomtry.*;
public class CircleSpace implements CircularMotion, MachineUpdate{
	protected  CircularMotion machine = null;
	protected Point state;
	protected double currentAngle = 0;
	protected Dimension d;
	protected Point center;
	protected Coordinate dcenter;
	protected double dalpha = 0.1;
	protected  double startAngle=0;
	protected  double endAngle = Math.PI*2;
	protected  int r  ;
	protected int a,b;
	public Point getState(){
		return state;
	}
	public CircleSpace(Dimension d,double startAngle,double endAngle){   //in radians
		super();
		this.d = d;
		this.startAngle = startAngle;
		this.endAngle = endAngle;
		r = Math.min(d.width,d.height)/2-2;
		center = new Point(d.width/2,d.height/2);
		state = new Point(d.width/2,d.width/2-r);
		dcenter = new Coordinate(d.width/2,d.height/2);
		a = r;
		b = r;
	}
	
	public double getTotalChange(){
		return Math.abs(startAngle-endAngle);
	}
	public double getChangeRate(){
		return dalpha;
	}		
	public double getCurrentAngle(){
		return Math.abs(startAngle-currentAngle);
	}
	public double setChangeRate(){
		if (machine!=null){
			return Math.abs(startAngle-endAngle)*machine.getChangeRate()/machine.getTotalChange();
		}else return 0.1;
	}
	public void setMachine(CircularMotion machine){
		this.machine = machine;
		dalpha = setChangeRate();
	}
	public void changeState(){
		  if (machine!=this) currentAngle = dalpha*machine.getCurrentAngle()/machine.getChangeRate()+startAngle; 
		  else currentAngle = currentAngle+dalpha;
		  state = Geomtry.getPointByVector(dcenter,r,currentAngle).toPoint();
	}
	public void changeState(double offset){
		if (machine!=this) currentAngle = dalpha*machine.getCurrentAngle()/machine.getChangeRate()+startAngle; 
		  else currentAngle = currentAngle+dalpha;
		  state = Geomtry.getPointByVector(dcenter,r,currentAngle+offset).toPoint();
		  }
	public void update(Graphics g){
		g.clearRect(0,0,d.width,d.height);
		g.setColor(Color.black);
		if(machine==this){
			g.setColor(Color.red);
			Geomtry.drawAnchor(g,center);
		}else{
			if (Math.abs(startAngle-endAngle)>=Math.PI*2) g.drawOval(d.width/2-a,d.height/2-b,a*2,b*2);
			else g.drawArc(d.width/2-r,d.height/2-r,r*2,r*2,
				(int)Geomtry.toAngle(startAngle),(int)Geomtry.toAngle(startAngle-endAngle));
		}

	}
	public void redraw(Graphics g){
		if(machine==this){
			g.setColor(Color.black);
			g.drawLine(d.width/2,d.height/2,state.x,state.y);
		}
		g.setColor(Color.green);
		Geomtry.drawJoint(g,state);
	}
	public void finalize() throws Throwable{
		machine = null;
		state = null;
		d = null;
		dcenter = null;
		center = null;
	}
}
		

		