import primitives.machines.*;
import primitives.geomtry.*;
import primitives.spaces.*;
import primitives.frames.*;
import java.awt.*;
public class FourArmsOrientDemo extends	FourArmsDemo implements MachineListener,FramesListener{
	boolean orientIsCont =false;
	Point direction,hArrow,vArrow	;
	ExtPoint startPoint;
	Dimension d;
	int maxDescent;
	boolean drawonBorder,extendOrientation = false;
	int index=0;
	public void start(){
		super.start();
		frames[0].drawArea.setCurrentObject(this);
		frames[1].drawArea.setCurrentObject(this);
		direction = new Point();
		hArrow = new Point();
		vArrow = new Point();
		Font f = frames[0].drawArea.getFont();
		f = new Font(f.getName(),f.getStyle(),f.getSize()+3);
		frames[0].drawArea.setFont(f);
		maxDescent = this.getFontMetrics(f).getMaxDescent();
		d = frames[0].drawArea.getSize();
		dstPoint = new Coordinate();
		endPoint = new Coordinate();
	}
	public void stop(){
		super.stop();
		direction = null;
		hArrow = null;
		vArrow = null;
		d = null;
		dstPoint = null;endPoint = null;
		startPoint = null;
 	}
	public void changeFrame(int index){
		this.index = index;
		 orientIsCont=(index>=1);
		 extendOrientation=(index>=2);
		 frames[0].drawArea.repaint();
	}
	Coordinate dstPoint;
	Coordinate endPoint;
	private void drawArrow(Graphics g,ExtPoint startPoint,Point vector){
		endPoint.move(startPoint.x+vector.x,startPoint.y+vector.y);
		g.drawLine(startPoint.x,startPoint.y,(int)endPoint.x,(int)this.endPoint.y);
		dstPoint.move(startPoint.x,startPoint.y);
		double angle=Geomtry.getAngle(this.endPoint,this.dstPoint);
		for(int i=-1;i<2;i=i+2){
			this.dstPoint = Geomtry.getPointByVector(endPoint,8,angle+i*Math.PI/4);
			g.drawLine((int)Math.rint(dstPoint.x),(int)Math.rint(dstPoint.y),(int)endPoint.x,(int)endPoint.y);
		}
	}
	private void setDirection(boolean isOutput){
		if (isOutput) 
			direction.move (((int)space.state.x/space.basicRect.width)%2,
			((int)space.state.y/space.basicRect.height)%2);
		else direction.move(0,0);		
	}
	private boolean stateOnBorder(){
		
		return (space.state.x%space.basicRect.width)/space.basicRect.width<0.05||
				(space.state.x%space.basicRect.width)/space.basicRect.width>0.95||
				(space.state.y%space.basicRect.height)/space.basicRect.height<0.05||
				(space.state.y%space.basicRect.height)/space.basicRect.height>0.95  ;
	}
	final static String str = "#Clockwise bends = ";
	void drawStrings(Graphics g){
		g.setColor(Color.red);
		int i= 0 ;
		for(int j=0;j<machine.arms;j++)
			if (machine.bendStates[j]==1){
				i++;
				Geomtry.drawJoint(g,machine.joints[j]);
			}
		 g.drawString(str+i,1,d.height-(maxDescent+1));
	}
	public void redraw(Graphics g){
		if (g==frames[0].drawArea.backBufferG){
			machine.redraw(g);
			setDirection(orientIsCont);
			startPoint=	machine.center;
			drawonBorder=!orientIsCont||!stateOnBorder();
			if(index==1)drawStrings(g);
		}else{
			space.redraw(g);
			setDirection(!orientIsCont);	
			startPoint = space.state.toPoint() ;
			drawonBorder=extendOrientation||!stateOnBorder();
		}
		if(drawonBorder){
		g.setColor(Color.blue);
		hArrow.move(-30+60*direction.x,0);
		vArrow.move(0,-30+60*direction.y);
		drawArrow(g,startPoint,vArrow);
		g.setColor(Color.magenta);
		drawArrow(g,startPoint,hArrow);
		}
	}
}