import java.awt.event.*;
import java.awt.*;
import java.awt.geom.*;
import java.util.Arrays;



public class EnhancedPolygon extends PolygonWrapper {
    boolean READY;
    boolean PERFECT;
    boolean SOLVED;
    int free_count;
    int control_point; //which vertex we move
    int current_vertex; //a selected graph vertex
    int[] degrees=new int[22];
    
    int[] free=new int[22]; //free vertices: 0 is determined and 1 is free.
    int[] scratch=new int[22]; //this is the scratch work for filling in the edges*/
    int[] pair=new int[22]; //edge pairing pattern
    int[] holo=new int[22];  //edge holonomy data
    int[][] geom=new int[22][2]; //initial positions of free vertices
    Complex[] V;  //this lists the coords of the nodes in the polygon
    int INFINITE;  //the vertex at infinity
    
    Complex[] embed; //this is the graph embedding.
    
    int[][] equiv; //equivalence classes of vertices
    int[][] graph; //the raw incidence structure
    int[][] graph2; //the correctly ordered incidence structure
    int[][] flower; //the flower structure -- triangles around a vertex
    int[][] triangles; //the list of triangles. Each triangle has 3 vertices
    int[][] triangles2; //this list the triple of triangles adjacent to a given one
    
    int[] solution;  //this is the solution set.  parallels the triangles.
    int[] local; //this is the local solution set. parallels the flowers


    public EnhancedPolygon() {}
    

    /**This makes the whole graph.
       The mode specifies the ordering method*/

    public int[] buildGraph(int mode) {
	DataToPolygon.createPolygon(this);
	boolean test=this.isEmbedded();
	if(test==false) return null;
	PolygonToGraph.getVertices(this,mode);
	PolygonToGraph.getEdges(this);
	GraphDiamondImprover.improve(this);
	GraphFlowerImprover.improve(this);
	current_vertex=0;
	GraphEmbed.setGeometry(this);
	GraphAnalyzer.setTriangles(this); 
	initSolution();
	SOLVED=false;
	int[] A={this.triangles.length,this.graph.length};
	return A;
    }

    /**This sets the initial geometry of the graph to be all vertices at the origin.
       Later routines start with this and get to the harmonic embedding*/
    
    public void initEmbed() {
	embed=new Complex[graph.length];
	for(int i=0;i<graph.length;++i) embed[i]=new Complex(0,0);
    }

    public void initSolution() {
	solution=new int[triangles.length];
	for(int i=0;i<triangles.length;++i) {
  	    solution[i]=-1;
	}
    }

    public void setControlPoint(Complex z) {
	int index=-1;
	double dist=10000;
	int n=1;
	for(int i=1;i<count;++i) {
  	    if(free[i]==1) {
		Complex w=Complex.eis(geom[n]);
		++n;
		double test=Complex.dist(z,w);
		if(test<dist) {
		    dist=test;
		    index=i;
		}
	    }
	}
	control_point=index;
     }


    public int setCurrentVertex(Complex w) {
	int index=0;
	double dist=10000;
	int n=1;
	for(int i=0;i<V.length;++i) {
	    double test=Complex.dist(w,V[i]);
	    if(test<dist) {
		 dist=test;
		 index=i;
	    }
	}
	for(int i=0;i<equiv.length;++i) {
	    if(ListHelp.onList(index,equiv[i])==true) current_vertex=i;
	}
	return 0;
    }

    public int convert(int x) {
	int n=1;
	for(int i=1;i<count;++i) {
	    if(i==x) return n;
  	    if(free[i]==1) ++n;
	}
	return -1;
    }

    /***This changes the geometry of the (s)th free vertex in the direction 
        specified by t*/

     public void changeGeometry(int s,int t) {
	
	if(t==0) {
	     ++geom[s][0];
	}
	
	if(t==5) {
	     ++geom[s][1];
	}

	if(t==4) {
	     --geom[s][0];
	     ++geom[s][1];
	}

	if(t==3) {
	     --geom[s][0];
	}
	
	if(t==2) {
	     --geom[s][1];
	}

	if(t==1) {
	     ++geom[s][0];
	     --geom[s][1];
	}
	
	DataToPolygon.createPolygon(this);
	READY=false;
	SOLVED=false;
	PERFECT=false;
     }
    /**end change geometry*/


    /**printout*/

    public void print() {
	System.out.println("===========================================");
  	System.out.println("vertex total  "+ equiv.length);
	System.out.println("");
	System.out.println("interior vertices");
	for(int i=0;i<equiv.length;++i) {
	    int j=equiv[i][0];
	    if(V[j].a[0]==0) System.out.print(j+" ");
	}
	System.out.println("");
	System.out.println("");
	System.out.println("edge vertices");
	for(int i=0;i<equiv.length;++i) {
	    int j=equiv[i][0];
	    if(V[j].a[0]==1) ListHelp.print(equiv[i]);
	}
	System.out.println("");
	System.out.println("vertex vertices");
	for(int i=0;i<equiv.length;++i) {
           int j=equiv[i][0];
	   if(V[j].a[0]==2) ListHelp.print(equiv[i]);
	}

	if(READY==false) return;
	System.out.println("incidence relations");
	for(int i=0;i<graph.length;++i) {
	    System.out.print(i+"   ("+graph[i].length+")   ");
	    ListHelp.print(graph[i]);
	    System.out.print("                                                       ");
	    ListHelp.print(graph2[i]);
	}

	System.out.println("degree sequence");
	for(int i=0;i<graph.length;++i) {
	    if(graph[i].length<6) {
		Complex z=V[equiv[i][0]];
		System.out.print(graph[i].length);
		if(z.a[0]==2) System.out.println("");
		else System.out.println("*");
	    }
	}
	
	System.out.println("triangle list");
  	for(int i=0;i<triangles.length;++i) ListHelp.print(triangles[i]);

	System.out.println("triangle flowers");
	for(int i=0;i<flower.length;++i) ListHelp.print(flower[i]);

	System.out.println("perfect?" + PERFECT);
	System.out.println("ready?" + READY);
	
	System.out.println("===========================================");
    }







    
}


