// BertBoard2.java

import java.awt.*;

public class BertBoard1 extends java.awt.Canvas {

	Float xCoords[];						// x coordinates
	Float yCoords[];						// y coordinates
	
	int w, h;								// width and height of this component
	
	float scaleX;							// Number of pixels per data unit x
	float scaleY;							// ... and for y
	
	Point chordStarts[];					// Points that contain rescaled data points
	Point chordEnds[];
	
	float minX, maxX, minY, maxY;		// Range variables for graph
	int num;						// Number of data points
	
	int insetX, insetY;						// Inset around edge of component
	
	// Set up a DartBoard
	public BertBoard1() {
		super();
		minX = -1;
		maxX = 1;
		minY = -1;
		maxY = 1;
		num = 0;
		xCoords = new Float[1];
		xCoords[0] = new Float(0);
		yCoords = new Float[1];
		yCoords[0] = new Float(0);
	}
	
	// Set up a DartBoard with points
	public BertBoard1(Float[] x, Float[] y) {
		super();								// Set up as we would for a canvas
		minX = -1;
		maxX = 1;
		minY = -1;
		maxY = 1;
		num = y.length;						// get the number of data points
		yCoords = new Float[num];
		xCoords = new Float[num];
		for(int i = 0; i < num; i++)		// Copy arrays, and store range variables
		{
			xCoords[i] = x[i];
			yCoords[i] = y[i];
		}
	}
	
	public int adjX(Float oldX) {
		return adjX(oldX.floatValue());
	}
	
	public int adjY(Float oldY) {
		return adjY(oldY.floatValue());
	}
	
	public int adjX(float oldX) {
		return (int) ((float) (oldX - minX) * scaleX) + insetX;
	}
	
	public int adjY(float oldY) {
		return (int) ((float) (maxY - oldY) * scaleY) + insetY;
	}
	
	// Determines size of this object, and scales the coordinates accordingly.
	public float setPoints() {
		Dimension d = size();  //getSize() in 1.1.1
		w = (int) Math.min((double) d.width, (double) d.height);				
		h = (int) Math.min((double) d.width, (double) d.height);
		insetX = (int) ((float) (d.width - w) / 2f);
		insetY = (int) ((float) (d.height - h) / 2f);
		
		chordStarts = new Point[num];			// Initialize array for actual points to be graphed
		chordEnds = new Point[num];
		
		if (maxX - minX != 0)
			scaleX = (float) w / (maxX - minX);	// Total width / range
													// = number of pixels for each point
		if (maxY - minY != 0)						// Simalarly for y scale
			scaleY = (float) h / (maxY - minY);
			
		int x1, x2, y1, y2;									// current x and y coordinates
		int count = 0;
		float slope;
		float halfLength;
		float xIncr, yIncr;
		for (int i = 0; i < num; i++) {
			slope =  - 1 / (yCoords[i].floatValue() / xCoords[i].floatValue());
			halfLength = (float) Math.pow(1 - (Math.pow(xCoords[i].floatValue(), 2) 
				+ Math.pow(yCoords[i].floatValue(), 2)), .5);
			xIncr = (float) Math.cos(Math.atan(slope)) * halfLength;
			yIncr = (float) Math.sin(Math.atan(slope)) * halfLength;
			// Calculate what the coordinates of each data point should be, then add a Point object to the array
			x1 = adjX(xCoords[i].floatValue() + xIncr);
			x2 = adjX(xCoords[i].floatValue() - xIncr);			
			y1 = adjY(yCoords[i].floatValue() + yIncr);
			y2 = adjY(yCoords[i].floatValue() - yIncr);
			chordStarts[i] = new Point(x1, y1);
			chordEnds[i] = new Point(x2, y2);
			if (halfLength * 2 >= Math.pow(3, .5))
				count++;
		}
		return Math.round(10000f * (float) count / (float) num) / 10000f;
	}
	
	
	/* public Point coordsOf(Point start, float angle, float distance) {
		int x, y;
		x = start.x + (int) (Math.cos(angle) * distance);
		y = start.y - (int) (Math.sin(angle) * distance);
		return new Point(x, y);
	} */
	
	// Paint method, which should be redefined by subclasses to actually show the data points
	public void paint(Graphics g) {
		if (num > 0) { 					// Make sure we have at least one point
			g.setColor(new Color(0, 0, 100));
			drawRing(g);
			g.setColor(new Color(0, 0, 0));
			drawChords(g);
			g.setColor(new Color(100, 0, 0));
			drawBoundary(g);
		}
	}
	
	public void drawRing(Graphics g) {
		for (int i = 1; i <= 10; i++) {
			g.drawOval(adjX(-1), adjY(1), adjX(1) - adjX(-1),
				adjY(-1) - adjY(1));
		}
	}
	
	public void drawChords(Graphics g) {
		for (int i = 0; i < chordStarts.length; i++) {
			g.drawLine(chordStarts[i].x, chordStarts[i].y, chordEnds[i].x, chordEnds[i].y);
		}
	}
	
	public void drawBoundary(Graphics g) {
		g.drawOval(adjX(-.5f), adjY(.5f), adjX(.5f) - adjX(-.5f), adjY(-.5f) - adjY(.5f));
	}
}