import java.awt.Point;
import java.util.Vector;
import java.io.*;

/**
* This class works out the Irregularity index.
*/

public class Boundary {
	public static double borderIrregularity(Vector boundaryData) {
		int x1,y1,x2,y2 ;
		double c1 ;
		Point p1,p2;
		long lengthSum2 = 0;
        
		for (int i = 0; i < boundaryData.size()-5; i+=5) {
			p1 = (Point)boundaryData.elementAt(i) ;
			p2 = (Point)boundaryData.elementAt(i+5) ;

			x1 = p1.x;
			y1 = p1.y;
			x2 = p2.x;
			y2 = p2.y;

			c1 = java.lang.Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) ;
			lengthSum2 += c1;
		}
		p1 = (Point)boundaryData.elementAt(boundaryData.size()-1);
		p2 = (Point)boundaryData.elementAt(0);
		x1 = p1.x;
		y1 = p1.y;
		x2 = p2.x;
		y2 = p2.y;

		c1 = java.lang.Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) ;
		lengthSum2 += c1;

		double area = calculateArea(boundaryData);
		return ((double)lengthSum2*(double)lengthSum2)/(4*java.lang.Math.PI*area);
	}



	static float calculateArea(Vector v) {
		long xt,yt,at ;
		float a ;
		Point p1,p2;
		int numPts;
		
		a = 0 ;
		xt = 0 ;
		yt = 0 ;
		numPts = v.size() ;

		int j = 0;
		for (int i=0;i<numPts;i++) {
		      j = (i + 1) % numPts;
			p1 = (Point)v.elementAt(i) ;
			p2 = (Point)v.elementAt(j) ;

		      a += p1.x * p2.y;
		      a -= p1.y * p2.x;
		}
		a /= 2;
		return(a < 0 ? -a : a);
	}


	/** 
	* Main method. This method can take 1 or 3 arguments.
	* If Argument 1 = iterate
	* 	argument 2 = script file
	* 	argument 3 = output file
	* ELSE
	* 	argument 1 = boundary file
	*/  
	public static void main(String []args) {
		if (args[0].equals("iterate") == true) {
			Vector v = new Vector() ;
			FileReader fr = null;
			StreamTokenizer st = null;
			int file = 0, numberOfFiles = 0;
			String dir1=null, dir2=null;
		
			try {
				fr = new FileReader(args[1]) ;
				st = new StreamTokenizer(fr) ;

				st.nextToken() ;
				numberOfFiles = (int)st.nval;

	  	  		st.nextToken() ;
				dir1 = (String)st.sval;
				st.nextToken() ;
				dir2 = (String)st.sval;

				for (int i = 0; i < numberOfFiles; i++) {
					st.nextToken() ;
					file = (int)st.nval;
					v.addElement(new Integer(file)) ;
				}
			} catch (IOException e) {
System.out.println("Read Error in Specification File: ACTION: EXIT") ;
System.exit(1);
	    		}

			// Create log stream
			FileWriter fw = null;
			PrintWriter log = null;
			try {
				fw = new FileWriter(args[2]) ;
				log = new PrintWriter(fw, true);
			} catch (IOException e) {
System.out.println("Error opening Log File: ACTION: Use System.out") ;
				// true turns automatic flushing on, so every println causes something to print
				log = new PrintWriter(System.out, true) ;
			}

			Vector boundaryPoints = null;
			for (int i = 0; i < numberOfFiles; i++) {
				boundaryPoints = new Vector() ;
				int x=0,y = 0;
				fr = null;
				st = null;

				try {
					fr = new FileReader(dir1+((Integer)v.elementAt(i)).toString()+".bnd");
					st = new StreamTokenizer(fr) ;

					st.nextToken() ;
					int numberOfPoints = (int)st.nval ;

					for (int j = 0; j < numberOfPoints; j++) {
						st.nextToken() ;
						x = (int)st.nval;
						st.nextToken() ;
						y = (int)st.nval;
						boundaryPoints.addElement(new Point(x,y)) ;
					}
				} catch (IOException e) {
System.out.println("Read Error in Specification File:" + fr + " ACTION: continuing") ;
log.println("Read Error in Specification File:" + fr + " ACTION: continuing") ;
					continue;
				}

				log.print(((Integer)v.elementAt(i)).toString()+".bnd");
				log.println("\t\t\t\t\t\t\t"+borderIrregularity(boundaryPoints)+" " + calculateArea(boundaryPoints) + " " +boundaryPoints.size());
			} // END FOR
		} // END IF

		else { // ONLY DO ONE ITERATION AND PRINT TO SYSTEM.out
			Vector boundaryPoints = new Vector() ;
			int x=0,y = 0;
			FileReader fr = null;
			StreamTokenizer st = null;

			try {
				fr = new FileReader(args[0]) ;
				st = new StreamTokenizer(fr) ;

				st.nextToken() ;
				int numberOfPoints = (int)st.nval ;

				for (int i = 0; i < numberOfPoints; i++) {
					st.nextToken() ;
					x = (int)st.nval;
					st.nextToken() ;
					y = (int)st.nval;
					boundaryPoints.addElement(new Point(x,y)) ;
				}
			} catch (IOException e) {
System.out.println("Read Error in Specification File" + args[0]) ;
			}

System.out.println("P2/4PIA " +	borderIrregularity(boundaryPoints));
System.out.println("AVERAGE TURN " + averageTurn(boundaryPoints));
		}
	}
}

