
/**This short class animates the polyhedron exchange display**/

public class Animator implements Runnable {
    Manager M;
    boolean halt;
    Solver[] MEM=new Solver[100];
    int COUNT=0;

    public Animator() {}

    public Animator(Manager MM) {
	this.M=MM;
    }

    public void run() {
	halt=false;
	resetPictureWindow();
	M.C.STR[0]="Working";
	M.C.repaint();

	Solver SOL=new Solver(M.P.SOLV);
	SOL.SOLID_MAX=M.C.SOLID.val;
	int[] match=initialConditions(SOL);
	int[] t=new int[4];
	for(int i=0;i<4;++i) t[i]=M.P.INIT[match[i]];
	SOL.initialGuess(t);
	
	while(halt==false) {
	    for(int i=0;i<3;++i) SOL.MODE[i]=M.C.ACTION.L[i].on;
	    SOL.ANNEAL=M.C.ANNEAL.val;
	    SOL=SOL.improve();
	    sendSol(SOL);
	    if(SOL.ERROR==0) halt=true;
	}
	
	SOL.print(false);
	setString(SOL);
	M.P.SOLV=new Solver(SOL);
	M.C.repaint();
	M.P.repaint();
    }

    public void resetPictureWindow() {
	for(int i=0;i<1000;++i) M.P.SOL[i]=0;
    }

    public void sendSol(Solver SOL) {
	for(int i=0;i<SOL.MAX+1;++i) {
	    M.P.SOL[i]=SOL.SOL[i];
	}
	Integer e=Integer.valueOf(SOL.ERROR);
	M.C.STR[0]="Error: "+e.toString();
	e=Integer.valueOf(SOL.SOLID);
	M.C.STR[1]="fold count: "+e.toString();
	M.C.repaint();
	M.P.repaint();
    }



    public void setString(Solver SOL) {
	if(SOL.ERROR>0) {
  	    M.C.STR[0]="failed";
	    return;
	}
	int[] c=SOL.solCount();
	Integer a1=Integer.valueOf(c[1]);
	Integer a2=Integer.valueOf(c[2]);
	M.C.STR[0]="Solved!  "+a1.toString()+"   "+a2.toString();
    }
    

    public int[] initialConditions(Solver SOL) {
	int[] match=new int[4];
	for(int i=0;i<4;++i) {
  	    int u=SOL.QUAD[i];
	    int a=M.P.VERTEX[u][0];
	    int b=M.P.VERTEX[u][1];
	    Complex z=Complex.eis(a,b);
	   match[i]=bestMatch(z,M.P.QUAD[0]);
	}
	return match;
    }


    public static int bestMatch(Complex z,PolygonWrapper QUAD) {
	    for(int j=0;j<4;++j) {
		double d=Complex.dist(z,QUAD.z[j]);
		if(d<.00001) return j;
	    }
	return -1;
    }



    
    
}



