package primitives.machines;
import java.awt.*;
import primitives.geomtry.*;
/**
* A class which implements methods for the CircularMotion inteface and
* adds labels to the arms of the Narmsmachine. Used by <i>i</i>-armsProof applets
*@see CircularMotion
*@author Dori Eldar
*/
public class NarmsMachineProof extends NarmsMachine implements CircularMotion{
	/**
	* Stores the limit angles of motion [should be declared private].
	*/
	public double[] limits;
	/**
	* Stores the change rate.
	*/
	private double dalpha;
	/**
	*@see NarmsMachine#NarmsMachine
	*/
	public 	NarmsMachineProof(Dimension d,int arms, double ratio){
		super(d,arms,ratio);
		double a = dAnchors[0].x-dCenter.x;
		moveCenterEx(a-2*barLength+10,0);
		limits = new double[2];
	}
	/**
	*Sets the change rate of this CircularMotion Object.
	*@param a the the new change rate.
    *@see CircularMotion
	*/
	public  void setChangeRate(double a){
		dalpha = a;
	}
    /**
	*@return the current change rate of this object.
	*@see CircularMotion
	*/
	public double getChangeRate(){
		return dalpha;
	}
    /**
	*@return the total change of this object.
	*@see CircularMotion
	*/
	public double getTotalChange(){
		return Math.abs(4*(limits[0]-limits[1]));
	}
	/**
	*@return the current angle of the state of this object.
	*@see CircularMotion
	*/
	public double getCurrentAngle(){
		int i=0;
		if (bendStates[1]==bendStates[arms-1]) i = (1-bendStates[1]);
		else i=2+bendStates[1];
		double a = Geomtry.getAngle(dCenter,dAnchors[0]);
		if (i%2==0) a = limits[1]-a+limits[0];
		return a+i*(limits[1]-limits[0])-limits[0];
	}
	/**
	*preforms a virtual motion to compute the angle limits of the objects motion.
	*/
	public void testRun(){
		double dalpha = 0.001;
		int tries = 0;
		int sign = 1;
		double result;
		while(tries<2){
			 result = rotateCenterEx(0,sign*dalpha);
			 if(result>0){
				 tries++;
				 sign = sign*(-1);
				 if (result==1) limits[0] = Geomtry.getAngle(dCenter,dAnchors[0]);
				 else limits[1] = Geomtry.getAngle(dCenter,dAnchors[0]);
			 }
		}
	}
	/** Strings used as arms labels.
	*/
	 final static String A="A";
	 final static String B="B";
	 final static String C="C";
	 final static String D="D";
	 final static String U="U";
	 final static String L="L";
	/**
	*Draws the machine to a graphic context.
    *@param g the graphic context to draw to.
	*@see NarmsMachine#redraw
	*/
	 public void redraw(Graphics g){
		g.setColor(Color.black);
		center = dCenter.toPoint();
		updatePoints(dJoints,joints);
		joints[0] = Geomtry.getMidPoint(dCenter,dAnchors[0],0.5).toPoint();
		 for(int i=1;i<arms;i++){
			drawLine(g,center,joints[i]);
			drawLine(g,anchors[i],joints[i]);
		}
		for(int i=0;i<arms;i++){
			g.setColor(Color.green);
			Geomtry.drawJoint(g,joints[i]);
			g.setColor(Color.red);
			Geomtry.drawAnchor(g,anchors[i]);
		}
		g.setColor(Color.black);
		g.drawString(U,anchors[arms-1].x+10,anchors[arms-1].y);
		g.drawString(D,anchors[1].x+10,anchors[1].y);
		if(arms==4) g.drawString(L,anchors[2].x-15,anchors[2].y);
		else{
			g.drawString(B,anchors[2].x,anchors[2].y-5);
			g.drawString(C,anchors[3].x-15,anchors[3].y+5);
		}
		g.setColor(Color.green);					   
		Geomtry.drawJoint(g,center);
		g.setColor(Color.blue);
		drawLine(g,anchors[0],center);
		g.drawString(A,anchors[0].x-10,anchors[0].y+15);
	}
    /**
	*Sets object fields to null
	*@exception java.lang.Throwable .
	*/
	public void finalize()throws Throwable{
		limits = null;
		super.finalize();
	}
}