import primitives.frames.*;
import primitives.machines.MachineListener;
import primitives.geomtry.*;
import java.awt.*;
import java.awt.event.MouseEvent;
public class SquareToRing extends Frames implements MachineListener{
	Dimension d;
	int r;
	Coordinate[] vertex;
	public void init(){
		super.init();
		frames[0].drawArea.setCurrentObject(this);
	}
	public void start(){
			run = false;
		d = frames[0].drawArea.getSize();
		r=Math.min(d.width,d.height)/3-5;
		vertex = new Coordinate[2];
		vertex[0] = new Coordinate((int)((d.width-r)/2),10);
		vertex[1] = new Coordinate((int)((d.width+r)/2),10);
		t2 = new Coordinate();
		t3 = new Coordinate();
		tx = new Coordinate();
		startThread();
		mouseClicked(null);
	}
	public void stop(){
		super.stop();
		vertex = null;
		t2 = null;
		t3 = null;
		tx = null;
		d = null;
	}
	public void mouseClicked(MouseEvent m){
		super.mouseClicked(m);
		if (!run) labels[0].setText("Click Mouse to Start");
		j = 0;
	}
	public void changeFrames(){
		frames[0].drawArea.repaint();
		
	}
	int j=0;
	Coordinate tx;
	public void redraw(Graphics g){
		if (j<=r*5/12){
			if(j==1) labels[0].setText("Deforming Square...");
			for (int i=0;i<5;i++){
				int xtop = (int)(i*0.25*vertex[0].x+(4-i)*0.25*vertex[1].x);
				int xdown = (int)(i*0.25*(vertex[0].x+j)+(4-i)*0.25*(vertex[1].x-j));
				int yleft =(int)(vertex[0].y+i*0.25*r);
				double xleft = (4-i)*0.25*xtop+i*0.25*xdown; 
				g.drawLine(xtop,(int)vertex[0].y,xdown,(int)vertex[0].y+r);
				if (j==0)	g.drawLine((int)vertex[0].x,yleft,(int)vertex[0].x+r,yleft);
				else{
					tx.move(xleft,yleft);
					drawArc(g,tx,(int)(0.25*(4-i)*r*5/12+i*0.25*(r*5/12-j)));
				}
			}
			
		}else{
			sectionToRing(g);
			if(j==360+r*5/12-46) mouseClicked(null);
			if(j==r*5/12+1) labels[0].setText("Stretching Square...");
		}
		if(run)j++;
	}
	void drawArc(Graphics g,Coordinate v,int scale){
		 Coordinate center = getCenter();
		 double dis=Geomtry.distance(v,center);
		 int i = -scale-6;
		 double y ;
		 double nextY =-Math.sqrt(dis*dis-(i)*(i));
		 while(i<=0){
		 	 y = nextY ;
			 int i0 = i	;
			 do{
				nextY=-Math.sqrt(dis*dis-(++i)*(++i));
			 }while((i<=0)&&(Math.rint(nextY)==Math.rint(y)));
			 int dy = (int)Math.rint(center.y+y);
			 g.drawLine(d.width/2+i0,dy,d.width/2+i-1,dy);
			 g.drawLine(d.width/2-i0,dy,d.width/2-i+1,dy);
		 }
	}
	Coordinate t2;
	Coordinate getCenter(double j){
		t2.move((d.width-r)/2+j,10+r);
		double rad = Geomtry.distance(vertex[0],t2);
		//double j= this.j;
		double r = this.r;
		rad = rad/((2*j)/r);
		t2.move(d.width/2,d.height);
		return Geomtry.getTriPointEx(vertex[0],rad,vertex[1],rad,t2,null);
	}
	Coordinate getCenter(){
		return getCenter(j);
	}
	Coordinate t3;
	void sectionToRing(Graphics g){
		Coordinate center = getCenter(r*5/12);
		double angle = Geomtry.getStandartAngle(Geomtry.getAngle(center,vertex[1]));
		double dis = Geomtry.distance(vertex[1],center);
		t3.move(vertex[1].x-r*5/12,vertex[1].y+r);
		double smallDis = Geomtry.distance(center,t3);
		angle = 360-Geomtry.toAngle(angle);
		for(int i=0;i<5;i++){
			int rDis = (int)(i*0.25*smallDis+(4-i)*0.25*dis);
			g.drawArc((int)(center.x-rDis),(int)(center.y-rDis),(int)(2*rDis),(int)(2*rDis),(int)angle,j-r*5/12+(90-(int)(angle))*2);
		}
		double nangle = (int)angle+j-r*5/12+(90-(int)(angle))*2;
		angle = Geomtry.toRadian(360-angle);
		nangle = Geomtry.toRadian(360-nangle);
		for(int i=0;i<5;i++){
			double rAngle = (4-i)*0.25*angle+i*0.25*nangle;
			Coordinate v = Geomtry.getPointByVector(center,dis,rAngle);
			Coordinate v1 = Geomtry.getPointByVector(center,smallDis,rAngle);
			g.drawLine((int)v.x,(int)v.y,(int)v1.x,(int)v1.y);
		}
	}

			  
}		
	