// (C)2007 Attila Kovacs <attila@submm.caltech.edu>


import java.text.*;

//Add parsing

public class CoordinatePair implements Cloneable {
	public double x = Double.NaN, y = Double.NaN;

	public CoordinatePair() { }

	public CoordinatePair(String text) { parse(text); }

	public CoordinatePair(double X, double Y) { set(X,Y); }

	public CoordinatePair(CoordinatePair template) { x = template.x; y = template.y; }

	public void set(double X, double Y) { x = X; y = Y; }

	public void copy(CoordinatePair template) { x = template.x; y = template.y; }

	public boolean equals(Object o) {
		if(o instanceof CoordinatePair) return equals((CoordinatePair) o);
		else return false;
	}

	public boolean equals(CoordinatePair c) {
		if(c.x == x && c.y == y) return true;
		else return c.isNaN() && isNaN();
	}

	public Object clone() {
		try { return super.clone(); }
		catch(CloneNotSupportedException e) { return null; }
	}

	public void zero() { x = 0.0; y = 0.0; }

	public boolean isNull() { return x == 0.0 && y == 0.0; }	

	public void NaN() { x = Double.NaN; y = Double.NaN; }

	public final boolean isNaN() { return Double.isNaN(x) || Double.isNaN(y); }

	public final void weightedAverageWith(double w1, CoordinatePair coord, double w2) {
		double sumw = w1 + w2;
		w1 /= sumw; w2 /= sumw;
		x = w1 * x + w2 * coord.x;
		y = w1 * y + w2 * coord.y;
	}

	public void parse(String text) throws NumberFormatException, IllegalArgumentException {
		String components = text.substring(text.indexOf('(')+1, text.lastIndexOf(')'));	
		int i = 0, open = 0;
		char c;
		while(((c = components.charAt(i)) != ',' || open > 0) && i < components.length()) {
			if(c == '(') open++;
			else if(c == ')') open--;
			i++;
		}
		if(i>0 && i<components.length()) {
			x = Double.parseDouble(components.substring(0, i));
			y = Double.parseDouble(components.substring(i+1, components.length()));
		}
	}

	public String toString(NumberFormat nf) {
		return "(" + nf.format(x) + "," + nf.format(y) + ")";
	}

	public String toString() { 
		return "(" + x + "," + y + ")";
	}
	
	public final void createFromDoubles(Object array) throws IllegalArgumentException {
		if(!(array instanceof double[])) throw new IllegalArgumentException("argument is not a double[].");
		double[] components = (double[]) array;
		if(components.length != 2) throw new IllegalArgumentException("argument double[] array is to small.");
		x = components[0];
		y = components[1];
	}

	public final void viewAsDoubles(Object view) throws IllegalArgumentException {
		if(!(view instanceof double[])) throw new IllegalArgumentException("argument is not a double[].");
		double[] components = (double[]) view;
		if(components.length != 2) throw new IllegalArgumentException("argument double[] array is to small.");
		components[0] = x;
		components[1] = y;
	}
	
	public final Object viewAsDoubles() {
		return new double[] { x, y };		
	}
	
	
	public double getValue(int field) throws NoSuchFieldException {
		switch(field) {
		case X: return x;
		case Y: return y;
		default: throw new NoSuchFieldException(getClass().getSimpleName() + " has no field for " + field);
		}
	}
	
	public void setValue(int field, double value) throws NoSuchFieldException {
		switch(field) {
		case X: x = value; break;
		case Y: y = value; break; 
		default: throw new NoSuchFieldException(getClass().getSimpleName() + " has no field for " + field);
		}
	}

	public static final int X = 0;
	public static final int Y = 1;
}
