/*
	Module: 	GraphAnimApplet.java
	Author: 	F. Michael O'Brien (michael@obrienm.com)
	Version:	1.00
	Date:		10 Mar 2001
	Documents:	_projv[nnn].doc
	Notes:		
				written for the Sun JDK 1.2.2
	History:
	10 Mar 2001 - Class started
	15 Mar 2001 - Vector.add method n/a in ie/ns
	17 Mar 2001 -
				- wrote finalize()

*/

import java.applet.Applet;
import java.applet.*;
import java.awt.*;
// AWT layout
import java.awt.BorderLayout;
import java.util.StringTokenizer;
import java.lang.Exception;
import java.awt.event.*;
//import java.util.BitSet;
import java.io.*;
//----------------------------------------------------------------
// Implements:		Graph,Vertex,Edge,Path
// Inherits:		AnimApplet
// Implementors:	-
//----------------------------------------------------------------
public class GraphAnimApplet extends AnimApplet2 { //implements MouseListener, MouseMotionListener, ActionListener {

// encapsulated objects
private Graph 				aGraph, priGraph, auxGraph;
//private Edge  				anEdge;
//private Vertex				aVertex;
private Path 				aPath;
private Vertex				selectedVertex;
private int					selectedVertexIndex;

private int	ivGridCounter=0;

// for sound
private AudioClip			sound;
//private AudioClip			soundDigit[];

private static int 			izGridHeight;
private static int			izGridWidth;
private static int 			izGridHeight2;
private static int			izGridWidth2;
private static int			izVertexRadius;
private static int			izColorMode;

//				ivFirstTime=0,
//				ivGridGreen2=0;

protected boolean			singleStepSimulation=false;
//protected boolean			singleStepSimulation=true;
protected boolean			advanceSingleStep=false;

// vars used to blink objects
protected boolean 			bvOddFrame=true;
protected int 				ivFrameCount=0;
protected static final int	ivFrameFlipCount=10;
// counter for frames within current gen
protected int 				ivFrames=0;
// counter for current cSwarm simulation frame count
protected int 				ivFrames2=0;
// show statistics
protected static boolean	bvShowStatistics=true;
// turn off display for subsequent init() calls
private boolean				bQuietInit=false;

//protected int 		counter=0;

// constants
private long 				lvGeneration=0;

// constants needed for colors
private int 				izSpacing,izSpacing2,izSpacing3,
							izSpacing4,izSpacing6,izCenterx,izCentery;
private static Color		color_vertex, color_edge,color_none,color_text,
							color_vertex_text,color_background,color_edge_text,
							color_edge_disabled,color_edge_selected,
							color_vertex_selected;
//private static final int 		ndir[]={9,8,11,10,5,4,7,6};
private static final int	xdir[]={1,0,-1,0};
private static final int	ydir[]={0,-1,0,1};

// keep track of vars for circ (target found) anim
private int					ivBullsEye[];
private boolean 			bvDestFound[];
private int					izMaxBullsEye=30;
private int					izBullsEyeDecrement=1;
private int					ivBullsEyeSelected=izMaxBullsEye;

private static int 			izMaxSimulationSteps;

// for Statistics file output
//private byte 				fileBuffer[] = new byte[80];
private DataOutputStream 	outFile;
// eigentest

// popup menu
private static final String svPopupNames[]= 
	{"Single Step Mode On","Single Step Mode Off","Reset","Show Spanning Tree"};

private MenuItem thePopupMenuItems[]; private
	PopupMenu aPopupMenu;

// load the images when the applet begins executing
public void init()
{
	int ivParameterCount;	// used to parse multi-parameter strings
	int ivTemp; 			// used in parsing while loop
	int ivNodeCount;		// current node

	if(bvApplet) {
		sound = getAudioClip(getCodeBase(),"blip.wav"); //vesna_belly.wav");
	}

	izSleepTime				=0;    // milliseconds to sleep
	//super.init();
	if(bvApplet) {
		izMaxHeight=Integer.parseInt(getParameter("pixelHeight"));
		izMaxWidth=Integer.parseInt(getParameter("pixelWidth"));
		izColorMode=Integer.parseInt(getParameter("colorMode"));
	}
	// create graphics subsystem
	buffer = createImage(izMaxWidth,izMaxHeight); // create image buffer
	gContext = buffer.getGraphics(); // get graphics context

	initializeConstants();

	// set background of buffer to black
	gContext.setColor(color_background);	  
	gContext.fillRect(0,0,izMaxWidth,izMaxHeight+30);

	// applet listen for mouse events, ok
	addMouseListener(this);
	addMouseMotionListener(this);

	// get parameters when in applet mode		
	if(bvApplet) {
		//izMaxHeight=Integer.parseInt(getParameter("pixelHeight"));
		//izMaxWidth=Integer.parseInt(getParameter("pixelWidth"));
		izGridHeight=Integer.parseInt(getParameter("gridHeight"));
		izGridWidth=Integer.parseInt(getParameter("gridWidth"));
		//izColorMode=Integer.parseInt(getParameter("colorMode"));
		izVertexRadius=Integer.parseInt(getParameter("vertexRadius"));
		izMaxSimulationSteps=Integer.parseInt(getParameter("maxSimulationSteps"));
		if(Integer.parseInt(getParameter("showStatistics"))>0)
			bvShowStatistics=true;
		else
			bvShowStatistics=false;


		if(!bQuietInit) {
			System.out.println("_izGridHeight: " + (new Integer(izGridHeight)).toString());
			System.out.println("_izGridWidth: " + (new Integer(izGridWidth)).toString());
		}
	} else { // taken care of in main()
		// preset some values										   
		//loadBoardExample1(0, 0);
	}

	if(bvShowStatistics)
		izMaxWidth=izMaxWidth-160;
	izCenterx = (int)(izMaxWidth-60)/2;
	izCentery = (int)(izMaxHeight-60)/2;
	izGridHeight2 = (int)(izGridHeight/2);
	izGridWidth2 = (int)(izGridWidth/2);
	izMaxBullsEye=izVertexRadius*2;

	izSpacing=(int)(izMaxHeight-60)/izGridHeight;
	izSpacing2=(int)(izMaxHeight-60)/izGridHeight/2;
	izSpacing3=(int)(izMaxHeight-60)/izGridHeight/3;
	izSpacing4=(int)(izMaxHeight-60)/izGridHeight/6;
	izSpacing6=(int)(izMaxHeight-60)/izGridHeight/12;
	if(!bQuietInit) {
		System.out.println("izSpacing " + (new Integer(izSpacing)).toString());
		System.out.println("izSpacing2 " + (new Integer(izSpacing2)).toString());
		System.out.println("izSpacing3 " + (new Integer(izSpacing3)).toString());
		System.out.println("izSpacing4 " + (new Integer(izSpacing4)).toString());
		System.out.println("izSpacing6 " + (new Integer(izSpacing6)).toString());

		// create objects
//		loadGraphTest();
		loadGraphTest2();
	}


	// create popup menu
	aPopupMenu = new PopupMenu("Popup");
	thePopupMenuItems = new MenuItem[svPopupNames.length];

	for(int i=0;i<svPopupNames.length;i++)	{
		thePopupMenuItems[i] = new MenuItem(svPopupNames[i]);
		aPopupMenu.add(thePopupMenuItems[i]);
		thePopupMenuItems[i].addActionListener(this);
	}


	// the status line at the bottom of the screen
	Panel statusPanel = new Panel();
	TextArea statusTextArea = new TextArea("Press: [SPACE] to select/deselect\n[UP/DOWN_ARROW] = X  [LEFT/RIGHT_ARROW] = Y  [ . ][ , ] = Z"
			,2,60,TextArea.SCROLLBARS_NONE);

		statusTextArea.setBackground(color_background);
		statusTextArea.setForeground(color_text);
		statusPanel.setBackground(color_background);
		statusPanel.add(statusTextArea);


  	// add popup menu to this canvas
	add(aPopupMenu);
	enableEvents(AWTEvent.MOUSE_EVENT_MASK);

//	add(statusPanel,BorderLayout.SOUTH);

  	// write output header to disk for non-applets
  	if(!bvApplet) {
  		try {
  			// create output stream
  			outFile = new DataOutputStream(new FileOutputStream("out.txt",true));
			if(!bQuietInit) {
  			outFile.writeBytes("GraphAnimApplet:\r\n");
  			outFile.writeBytes("izGridHeight: \t" + (new Integer(izGridHeight)).toString() + "\r\n");
  			outFile.writeBytes("izGridWidth: \t" + (new Integer(izGridWidth)).toString() + "\r\n");
			}
  			outFile.close();
  		} catch (Exception e) {
  			String err = e.toString();
  			System.out.println(err);
  		}
		if(!bQuietInit) {
		  	System.out.println("\nF.Michael O'Brien: GraphAnimApplet.java");
  			System.out.println("must alt-tab out and back in to step past");
		  	System.out.println("sun.awt.windows.WGraphics.drawImage(WGraphics.java:360) bug");
		  	System.out.println("when using double-buffering");
		}
  	}
	// turn off printing for subsequent init() calls
	bQuietInit=true;
}


// display the image in the Applet's Graphics context
public void paint(Graphics g) {
	int xd,yd;
	int tempx, tempy;
	int ivDirx, ivDiry;
	String stringRep;	// string binary rep of grid cell 0-izBoardEdgeValue	
	boolean connected;
	int cellColor;
	int ivMaxConnections=0;
	int lastIndex;
	int p1,p2;
	int tempBitPos;
//	BitSet aBitSet;

	//super.paint(g);
	g.drawImage(buffer,0,0,this);
	// clear previous image from buffer
	gContext.setColor(color_background);
	gContext.fillRect(0,0,izMaxWidth,izMaxHeight);
	
	// initialize arrays?
	//initializeSimulation();
	getSelectedVertex();
 
	// display current solution
	displayCurrentSolution();

	// display genome statistics
	if(bvShowStatistics) {
		displayStatistics();
	}

	// increment timestep
	simulationTimeStep(g);


	// write out numerical parameters
	gContext.setColor(color_text);
	//gContext.drawString("G:" + (new Long(lvGeneration)).toString(),10,izMaxHeight-40);
	gContext.drawString("SFRM: " + (new Integer(ivFrames2)).toString() + " GFRM: " + (new Integer(ivFrames)).toString() ,(int)(izMaxWidth/2),izMaxHeight-40);


  	//try {Thread.sleep( izSleepTime );}
	//catch ( InterruptedException e ){showStatus(e.toString());}
	repaint();  // display buffered image
} // paint()

private void getSelectedVertex() {
	Vertex aVertex;
	// look for closest vertex
	for(int n=0;n<aGraph.getNumberVertices();n++) {
		aVertex=aGraph.getVertex(n);
		if((Math.abs(izCenterx+aVertex.getx()*izGridWidth-xPos)<=izGridWidth)&&
		(Math.abs(izCentery+aVertex.gety()*izGridHeight-yPos)<=izGridHeight))
		{
			// get selected vertex
			selectedVertex = aVertex;
			selectedVertexIndex = n;
			// move the offset of the vertex
		}
	}
}

// display current solution
private void displayCurrentSolution() {
	Vertex v1,v2;
	Edge e1;
	int xo, yo;
	int xm,ym;

	//gContext.drawString("G:" + (new Long(lvGeneration)).toString(),10,izMaxHeight-40);

	// draw the edges of the graph
	for(int i=0;i<aGraph.getNumberEdges();i++) {
		// draw edge
		// skip deleted objects
//		if(aGraph.getEdge(i)!=null) {
		e1 = aGraph.getEdge(i);
		v1 = e1.getStartVertex();
		v2 = e1.getEndVertex();
		if(aGraph.getEdge(i).disabled()) {

		gContext.setColor(color_edge);
//		if(v1.getId()<v2.getId()) {
		if(v1.getx()<v2.getx()) xm=-1; else xm=1;
		if(v1.gety()>v2.gety()) ym=-1; else ym=1;
		// check special vert/horiz case
		if(v1.gety()==v2.gety()) ym=xm;
		if(v1.getx()==v2.getx()) xm=ym;

		// center edge for undirected edges
		if(e1.isDirected()) {
			ym=0; xm=0;
		}

			gContext.drawLine(izCenterx+v1.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				izCentery+v1.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2,
				izCenterx+v2.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				izCentery+v2.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2);

		// draw arrow
/*		// get center of edge
		int cx,cy;
		cy=((v2.gety()-v1.gety());
		cx=((v2.getx()-v1.getx());
		cx=Math.atn((v2.gety()-v1.gety())/(v2.getx()-v1.getx()))/(57.29577951);
//
gContext.drawLine(izCenterx+v1.getx()*izGridWidth+izGridWidth2,
//
izCentery+v1.gety()*izGridHeight+izGridHeight2,
//
izCenterx+v2.getx()*izGridWidth+izGridWidth2,
//
izCentery+v2.gety()*izGridHeight+izGridHeight2);
*/
		// draw value
		gContext.setColor(color_edge_text);
		gContext.drawString("" + e1.getValue() + ""
		,izCenterx+e1.getMidx()*izGridHeight+izGridHeight2+xm*izGridWidth*2
		,izCentery+e1.getMidy()*izGridWidth+izGridWidth2+ym*izGridHeight*2);

		} else {

		gContext.setColor(color_edge_disabled);
//		if(v1.getId()<v2.getId()) {
		if(v1.getx()<v2.getx()) xm=-1; else xm=1;
		if(v1.gety()>v2.gety()) ym=-1; else ym=1;
		// check special vert/horiz case
		if(v1.gety()==v2.gety()) ym=xm;
		if(v1.getx()==v2.getx()) xm=ym;

		// center edge for undirected edges
		if(e1.isDirected()) {
			ym=0; xm=0;
		}
			gContext.drawLine(izCenterx+v1.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				izCentery+v1.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2,
				izCenterx+v2.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				izCentery+v2.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2);

		// draw thick line, if selected
		//if(e1.getSelected()) {
			for(int t=0;t<4;t++) {
			gContext.drawLine(xdir[t]+izCenterx+v1.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				ydir[t]+izCentery+v1.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2,
				xdir[t]+izCenterx+v2.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				ydir[t]+izCentery+v2.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2);
/*			gContext.drawLine(izCenterx+v1.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				1+izCentery+v1.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2,
				izCenterx+v2.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				1+izCentery+v2.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2);
			gContext.drawLine(izCenterx+v1.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				-1+izCentery+v1.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2,
				izCenterx+v2.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				-1+izCentery+v2.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2);
			gContext.drawLine(-1+izCenterx+v1.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				izCentery+v1.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2,
				-1+izCenterx+v2.getx()*izGridWidth+izGridWidth2+xm*izGridWidth*2,
				izCentery+v2.gety()*izGridHeight+izGridHeight2+ym*izGridHeight*2);
			*/
			}
		//}

		// draw arrow
/*		// get center of edge
		int cx,cy;
		cy=((v2.gety()-v1.gety());
		cx=((v2.getx()-v1.getx());
		cx=Math.atn((v2.gety()-v1.gety())/(v2.getx()-v1.getx()))/(57.29577951);
//
gContext.drawLine(izCenterx+v1.getx()*izGridWidth+izGridWidth2,
//
izCentery+v1.gety()*izGridHeight+izGridHeight2,
//
izCenterx+v2.getx()*izGridWidth+izGridWidth2,
//
izCentery+v2.gety()*izGridHeight+izGridHeight2);
*/
		// draw value
		gContext.setColor(color_edge_text);
		gContext.drawString("" + e1.getValue() + ""
		,izCenterx+e1.getMidx()*izGridHeight+izGridHeight2+xm*izGridWidth*2
		,izCentery+e1.getMidy()*izGridWidth+izGridWidth2+ym*izGridHeight*2);
		}
	}

	// draw the vertices of the graph
	for(int i=0;i<aGraph.getNumberVertices();i++) {
		v1 = aGraph.getVertex(i);
		xo = v1.getx();					   
		yo = v1.gety();
		// fill vertex
		gContext.setColor(color_background);
		gContext.fillOval(izCenterx+xo*izGridWidth+izGridWidth2-izVertexRadius,
			izCentery+yo*izGridHeight+izGridHeight2-izVertexRadius,
			izVertexRadius*2,izVertexRadius*2);
		// draw outline
		gContext.setColor(color_vertex);
		gContext.drawOval(izCenterx+xo*izGridWidth+izGridWidth2-izVertexRadius,
			izCentery+yo*izGridHeight+izGridHeight2-izVertexRadius,
			izVertexRadius*2,izVertexRadius*2);


		// write out numerical parameters
		gContext.setColor(color_vertex_text);
//		gContext.drawString("" + (new Integer(aVertex.getName())).toString()
		gContext.drawString("" + v1.getName()
			,izCenterx+xo*izGridWidth+izGridWidth2
			,izCentery+yo*izGridHeight+izGridHeight2);
	}

	// display selection
	if((ivBullsEyeSelected>izMaxBullsEye)||(ivBullsEyeSelected<izVertexRadius))
		izBullsEyeDecrement=-izBullsEyeDecrement;		
//	if(ivBullsEyeSelected<izGridHeight)
//		izBullsEyeDecrement=-izBullsEyeDecrement;
//	else
		ivBullsEyeSelected=ivBullsEyeSelected-izBullsEyeDecrement;

	gContext.setColor(color_vertex_selected);
	gContext.drawOval(izCenterx+aGraph.getVertex(selectedVertexIndex).getx()*izGridWidth+izGridWidth2-ivBullsEyeSelected,
		izCentery+aGraph.getVertex(selectedVertexIndex).gety()*izGridHeight+izGridHeight2-ivBullsEyeSelected,
		ivBullsEyeSelected*2,ivBullsEyeSelected*2);
}

private void initializeSimulation() {}

// executed on each anim frame
private void simulationTimeStep(Graphics g) {
	int x,y,l;
	boolean solved=false;
	//System.out.println("_simulationTimeStep()");

	// first place all the ants in the current swarm
/*	for(int n=0;n<izTotalNumberNodes;n++) {
		ivBoard[][0][antSwarms[cSwarm][n].getPosx()][antSwarms[cSwarm][n].getPosy()]=antSwarms[
	}
*/
	if((!singleStepSimulation)||(advanceSingleStep)) {
		advanceSingleStep=false;

//	if(ivFrames>2000) {
//		ivFrames=0;
//		init();
//	} 

		// update frame and frameflip count
		ivFrames++;
		if(ivFrameCount<ivFrameFlipCount) {
			bvOddFrame=false;
			ivFrameCount++;
		} else {
			if(ivFrameCount<ivFrameFlipCount*2) {
				bvOddFrame=true;
				ivFrameCount++;
			} else {
				bvOddFrame=false;
				ivFrameCount=0;
			}				
		}


		if(ivFrames2<izMaxSimulationSteps) {
			ivFrames2++;
			//solved=determineIfCurrentSwarmIsSolved(g);
		} else {
			//solved=determineIfCurrentSwarmIsSolved(g);
			ivFrames2=0;
			//ivFrames=0;
		}
	
		// advance swarm
		if(ivFrames2==0) {
		 	//g.setColor(Color.cyan);
			//g.drawString("Initializing Gen: " + (new Long(lvGeneration)).toString(),4*izSpacing,4*izSpacing+10);
			
			ivFrames=0;
			//performSelectionAndCrossoverWithMutation();
			//resetSwarms();
			//determineIfAllSwarmsAreCyclicStable(g);
			lvGeneration++;
		}
		//loadBoardParadc(7,1);
		//init();
	}
}

private void writeStatistics() {
	int max;
//	int swarmBestTime=izMaxSimulationSteps;

  	// write output header to disk for non-applets
  	if(!bvApplet) {
  		try {
  			// create output stream
  			outFile = new DataOutputStream(new FileOutputStream("out.txt",true));
//  			outFile = new DataOutputStream(new FileOutputStream(
//  				"log\\pheno_bf_g"+(new Long(lvGeneration)).toString()+
//  				"s"+(new Integer(s)).toString()+
//  				"n"+(new Integer(node)).toString()+
//  				"_t"+(new Integer(ivBestTime)).toString()+
//  				".txt",true));
  			outFile.writeBytes(
  				"G:\t"+ (new Long(lvGeneration)).toString() +
				"\r\n");
   			outFile.close();
  		} catch (Exception e) {
  			String err = e.toString();
  			System.out.println(err);
  		}
	}
}



// display genome statistics
private void displayStatistics() {
	// draw Ants
	int px,py,prox,l;
//	Ant4 anAnt;
//	int proxAnt[];
	int sx=izMaxHeight-36;
	int sy=50;
	int hy=13;

	// global stats
 	gContext.setColor(Color.white);
	//gContext.drawString("POP: " + (new Long(lvGeneration)).toString(),sx,sy-36);
	//gContext.drawString("SF: " + (new Integer(ivFrames2)).toString() + " GF: " + (new Integer(ivFrames)).toString() ,sx+80,sy-36);
 	gContext.setColor(Color.blue);
	//gContext.drawString("Nd",sx,sy-16);
	//gContext.drawString("Nt",sx+16,sy-16);

	// draw box around selected node
	gContext.setColor(Color.green);
	//gContext.drawRect(sx-20,sy-12+hy*selectedAnt.getNodeId(),200,hy);
}


private void loadGraphTest() {
	aGraph = new Graph();
	// add vertices to graph
/*	v0 = new Vertex("a",0,-10,0);
	v1 = new Vertex("b",0,0,-5);
	v2 = new Vertex("c",0,0,5);
	v3 = new Vertex("d",0,10,-5);
	v4 = new Vertex("e",0,10,5);

	aGraph.addVertex(v0);
	aGraph.addVertex(v1);
	aGraph.addVertex(v2);
	aGraph.addVertex(v3);
	aGraph.addVertex(v4);
*/

	aGraph.addVertex(new Vertex(2,"S",0,-32,00));
	aGraph.addVertex(new Vertex(1,"A",0,00,-16));
	aGraph.addVertex(new Vertex(1,"B",0,00,16));
	aGraph.addVertex(new Vertex(1,"C",0,32,-16));
	aGraph.addVertex(new Vertex(1,"D",0,32,16));
	aGraph.addVertex(new Vertex(0,"T",0,64,00));

	// add edges
	aGraph.addEdge(true,"sa",0,1,1);
	aGraph.addEdge(true,"as",1,0,1);
	aGraph.addEdge(true,"sb",0,2,1);
	aGraph.addEdge(true,"bs",2,0,1);
	aGraph.addEdge(true,"ab",1,2,1);
	aGraph.addEdge(true,"ba",2,1,1);
	aGraph.addEdge(true,"ad",1,4,1);
	aGraph.addEdge(true,"da",4,1,1);
	aGraph.addEdge(true,"ca",3,1,1);
	aGraph.addEdge(true,"ac",1,3,1);
	aGraph.addEdge(true,"bd",2,4,1);
	aGraph.addEdge(true,"db",4,2,1);
	aGraph.addEdge(true,"dc",4,3,1);
	aGraph.addEdge(true,"cd",3,4,1);
	aGraph.addEdge(true,"dt",4,5,1);
	aGraph.addEdge(true,"td",5,4,1);
	aGraph.addEdge(true,"tc",5,3,1);


	// set selection default
	selectedVertex = aGraph.getVertex(0);
	selectedVertexIndex = 0;	 
/*	aGraph.getEdge(2).setSelected(true);
	aGraph.getEdge(5).setSelected(true);
	aGraph.getEdge(8).setSelected(true);
	aGraph.getEdge(10).setSelected(true);
*/
	// setup animation arrays
	//ivBullsEye = new int[aGraph.getNumberVertices()];
	ivBullsEyeSelected=izMaxBullsEye;
	
}


private void loadGraphTest2() {
	aGraph = new Graph();
	// add vertices to graph

	aGraph.addVertex(new Vertex(2,"A",0,-32,-28));
	aGraph.addVertex(new Vertex(1,"B",0,-31,28));
	aGraph.addVertex(new Vertex(1,"R",0,-20,00));
	aGraph.addVertex(new Vertex(1,"Q",0,2,-32));
	aGraph.addVertex(new Vertex(1,"P",0,0,6));
	aGraph.addVertex(new Vertex(1,"D",0,2,32));
	aGraph.addVertex(new Vertex(1,"H",0,20,00));
	aGraph.addVertex(new Vertex(1,"G",0,32,-28));
	aGraph.addVertex(new Vertex(0,"F",0,32,28));
//	aGraph.addVertex(new Vertex("Z",0,64,16));

	// add edges
	aGraph.addEdge(false,"ab",0,1,15);
	aGraph.addEdge(false,"ar",0,2,4);
	aGraph.addEdge(false,"aq",0,3,7);
	aGraph.addEdge(false,"br",1,2,13);
	aGraph.addEdge(false,"bd",1,5,17);
	aGraph.addEdge(false,"rp",2,4,11);
	aGraph.addEdge(false,"rh",2,6,8);
	aGraph.addEdge(false,"pq",4,3,14);
	aGraph.addEdge(false,"ph",4,6,10);
	aGraph.addEdge(false,"pf",4,8,6);
	aGraph.addEdge(false,"pd",4,5,2);
	aGraph.addEdge(false,"df",5,8,5);
	aGraph.addEdge(false,"qg",3,7,12);
	aGraph.addEdge(false,"qh",3,6,16);
	aGraph.addEdge(false,"hg",6,7,3);
	aGraph.addEdge(false,"fg",8,7,9);

	// set selection default
	selectedVertex = aGraph.getVertex(0);
	selectedVertexIndex = 0;	 
/*	aGraph.getEdge(2).setSelected(true);
	aGraph.getEdge(5).setSelected(true);
	aGraph.getEdge(8).setSelected(true);
	aGraph.getEdge(10).setSelected(true);
*/
	// setup animation arrays
	//ivBullsEye = new int[aGraph.getNumberVertices()];
	ivBullsEyeSelected=izMaxBullsEye;
	
}

public void reset() {
	// set disabled status to false for each edge
	for(int i=0;i<aGraph.getNumberEdges();i++) {
		aGraph.getEdge(i).enable();
	}
}


	// override update to eliminate flicker
	public void update(Graphics g){paint(g);}


	private void setValues(String event, int x, int y) {
		s=event; xPos=x; yPos=y; //repaint();
	}

	public void mouseClicked(MouseEvent e) { 
		setValues("Clicked",e.getX(),e.getY());
		//advanceSingleStep=true;
 	}

	public void mousePressed(MouseEvent e) { 
		setValues("Pressed",e.getX(),e.getY());
	}

	public void mouseReleased(MouseEvent e)	{ 
		setValues("Released",e.getX(),e.getY());
	}

	public void mouseEntered(MouseEvent e) { 
		setValues("Entered",e.getX(),e.getY());
	}

	public void mouseExited(MouseEvent e) { 
		setValues("Exited",e.getX(),e.getY());
	}

	public void mouseDragged(MouseEvent e) {
		setValues("Dragging",e.getX(),e.getY());
	}

	public void mouseMoved(MouseEvent e) {
		setValues("Moving",e.getX(),e.getY());
		advanceSingleStep=true;
	}

	// capture popup menu event
	public void processMouseEvent(MouseEvent e) {
		if(e.isPopupTrigger())
			aPopupMenu.show(this,e.getX(),e.getY());
		//super.processMouseEvent(e); // only when not sublassed twice
	}
	
	// process popup menu event
	public void actionPerformed(ActionEvent e) {
//	private String svPopupNames[] = {"Single Step Mode On","Single Step Mode Off","Reset"};
		//"Single Step Mode On"
		if(e.getSource()==thePopupMenuItems[0]) {
			singleStepSimulation=true;
			advanceSingleStep=true;
		}
		
		//"Single Step Mode Off"
		if(e.getSource()==thePopupMenuItems[1]) {
			singleStepSimulation=false;
		}
		
		//"Reset"
		if(e.getSource()==thePopupMenuItems[2]) {
			//init();
			reset();
//			loadBoardParadc(7,1);
		}

		// Show Spanning Tree
		if(e.getSource()==thePopupMenuItems[3]) {
			aGraph.getMinimumSpanningTree();
		}
	}	

// start the applet
public void start() {
	super.start();
}

public void stop() {
	super.stop();
}

//static boolean bvApplet=true;
// allow application use outside of browser, appletviewer
public static void main(String args[]) {
	bvApplet=false;
	// cl-parameters = Population MaxHeight MaxWidth GridHeight MutationMultiplier dzReplacementRatio
	// enumerate arguments passed from the console
	if(args.length > 7) {
		//for(int i=0;i<args.length;i++)
		//	if(args[i].equals("-debug")) 
				//bzDebug = true; // set global debug flag
		//	else { usage(); System.exit(0); }
		// get arguments
		izMaxHeight=Integer.parseInt(args[1]);
		izMaxWidth=Integer.parseInt(args[0]);
		izGridHeight=Integer.parseInt(args[3]);
		izGridWidth=Integer.parseInt(args[2]);
		izVertexRadius=Integer.parseInt(args[4]);
		izMaxSimulationSteps=Integer.parseInt(args[5]);
		if(Integer.parseInt(args[6])>0) {
			// when running as an app, adjust screen size depending on stats
			izMaxWidth=izMaxHeight+160;
			bvShowStatistics=true;
		} else {
			izMaxWidth=izMaxHeight;
			bvShowStatistics=false;
		}
		izColorMode=Integer.parseInt(args[7]);
	} else {
		// set defaults
		//bzDebug = false;
		usage(); System.exit(0);
	}	

	initializeConstants();

	// the status line at the bottom of the screen
	Panel statusPanel = new Panel();
	TextArea statusTextArea = new TextArea("Press: [SPACE] to select/deselect\n[UP/DOWN_ARROW] = X  [LEFT/RIGHT_ARROW] = Y  [ . ][ , ] = Z"
			,2,60,TextArea.SCROLLBARS_NONE);

	statusTextArea.setBackground(color_background);
	statusTextArea.setForeground(color_text);
	statusPanel.setBackground(color_background);
	statusPanel.add(statusTextArea);

	Frame aFrame = new Frame("Graph Theory: Combinatorics (c) F.Michael O'Brien V1.03.10");
	GraphAnimApplet anApplet=new GraphAnimApplet();
	aFrame.add("Center",anApplet);
//	aFrame.add("South",statusPanel);
	aFrame.setSize(izMaxWidth+10,izMaxHeight+30);
	aFrame.setBackground(color_background);
	aFrame.show();	
	// must alt-tab out and back in to step past 
	// sun.awt.windows.WGraphics.drawImage(WGraphics.java:360) bug
	// when using double-buffering
	anApplet.init();
	anApplet.start();
}

private static void initializeConstants() {
	// set colors for white paper
	if(izColorMode==1) {
	color_vertex			= new Color(0,64,0);
	color_edge				= new Color(0,0,64);
	color_edge_selected		= new Color(0,0,64);
	color_edge_disabled		= new Color(0,0,64);

	color_vertex_selected	= new Color(64,64,0);
	color_vertex_text		= new Color(0,0,0);
	color_text				= new Color(0,0,0);
	color_edge_text	  		= new Color(64,0,0);
	color_background		= new Color(255,255,255);
	color_none 				= Color.darkGray;
	} else {
	// set colors for black board
	color_vertex			= new Color(255,255,255);
	color_edge				= new Color(0,255,255);
	color_edge_selected		= new Color(255,255,255); 
	color_edge_disabled		= new Color(255,192,255);
	color_vertex_selected	= new Color(255,255,0);
	color_vertex_text		= new Color(255,255,255);
	color_text				= new Color(0,255,0);
	color_edge_text	  		= new Color(255,255,0);
	color_background		= new Color(0,0,0);
	color_none 				= Color.darkGray;
	}
}

// clean up in preparation for the GC
protected void finalize() throws Throwable {
	// remove pointers to non-native composite objects
	aGraph = null;
	priGraph = null;
	auxGraph = null;
	aPath = null;
	selectedVertex = null;
	sound = null;
	color_vertex = null;
	color_edge = null;
	color_none = null;
	color_text = null;
	color_vertex_text = null;
	color_background = null;
	color_edge_text = null;
	color_vertex_selected = null;
	color_edge_disabled = null;
	color_edge_selected = null;
	ivBullsEye = null;
	outFile = null;
	super.finalize();
}

/** print the expected parameters to the console */
public static void usage() {
	/**
	-debug : turn console debugging output on, default=off
	 : select grid size
	*/
	System.out.println("\nCommand-Line Options are...\njava GraphAnimApplet " +
		"pixelWidth pixelHeight GridWidth GridHeight vertexRadius" +
		" MaxSimulationSteps" + 
		" [0/1 showStatistics][0/1 colorMode][-debug]\n");}
}
//}

