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

import java.io.*;
import java.util.*;
import java.text.*;

public class ArrayView extends SkyMap {

	LabocaPixel[] pixel;

	public static void main(String[] args) {
		ArrayView view = new ArrayView();
		try { 
			//view.gain(args[0]);
			view.nefd(args[0]);
			//view.cables(args[0]);
		}
		catch(Exception e) { e.printStackTrace(); }

	}

	public void nefd(String pixelFileName) throws Exception {
		BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(pixelFileName)));
		String line;


		while((line = in.readLine()) != null) if(line.length() > 0) if(line.charAt(0) != '#') {
			StringTokenizer tokens = new StringTokenizer(line);
			int c = Integer.parseInt(tokens.nextToken()) - 1;
			double gain = Double.parseDouble(tokens.nextToken());
			Double.parseDouble(tokens.nextToken());
			double weight = Double.parseDouble(tokens.nextToken());
			// Noise excess is around 1.25...
			// 5.27 Jy/uV
			double nefd = 5.3e6 * Math.sqrt(0.04/weight)/gain;

			if(weight > 0.0 && gain > 0.0) {
				System.out.print((c+1) + "\t");
				System.out.print(Util.f3.format(gain) + "\t");
				System.out.println(Util.f3.format(nefd));

				drawCircle(pixel[c].position.x, pixel[c].position.y, 9.0*Unit.arcsec, nefd);
			}
		}

		fitsUnit = new Unit("Jy sqrt(s)", 1.0);

		normalize();
		sourceName = "nefd";

		write();
	}

	public void gain(String pixelFileName) throws Exception {
		BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(pixelFileName)));
		String line;

		DecimalFormat df = new DecimalFormat("000.0");
		DecimalFormat ef = new DecimalFormat("0.00E0");

		while((line = in.readLine()) != null) if(line.length() > 0) if(line.charAt(0) != '#') {
			StringTokenizer tokens = new StringTokenizer(line);
			int c = Integer.parseInt(tokens.nextToken()) - 1;
			double gain = Double.parseDouble(tokens.nextToken());
			Double.parseDouble(tokens.nextToken());
			double weight = Double.parseDouble(tokens.nextToken());	    
			double sensitivity = 1.3 * 2.0 * 5.27e6 * Math.sqrt(0.04/weight)/gain;

			if(weight > 0.0) {
				System.out.print((c+1) + "\t");
				System.out.print(df.format(pixel[c].position.x/Unit.arcsec) + "\t");
				System.out.print(df.format(pixel[c].position.y/Unit.arcsec) + "\t");
				System.out.println(ef.format(sensitivity));

				drawCircle(pixel[c].position.x, pixel[c].position.y, 9.0*Unit.arcsec, gain);
			}
		}

		fitsUnit = new Unit("1.0", 1.0);

		normalize();
		sourceName = "gains";

		write();
	}
	
	public void cables(String pixelFileName) throws Exception {
		BufferedReader in = new BufferedReader(new InputStreamReader(new FileInputStream(pixelFileName)));
		String line;
	
		LabocaPixel.readWiring("laboca/laboca-wiring.dat");
		LabocaPixel.fillWiringInfo(pixel);
	

		while((line = in.readLine()) != null) if(line.length() > 0) if(line.charAt(0) != '#') {
			StringTokenizer tokens = new StringTokenizer(line);
			int c = Integer.parseInt(tokens.nextToken()) - 1;
			Double.parseDouble(tokens.nextToken());
			Double.parseDouble(tokens.nextToken());
			double weight = Double.parseDouble(tokens.nextToken());	
			
			if(weight > 0.0) {
				int color = pixel[c].cable % 2 == 0 ? pixel[c].cable/2 : pixel[c].cable/2 + 6;
				drawCircle(pixel[c].position.x, pixel[c].position.y, 9.0*Unit.arcsec, color);
			}
		}

		fitsUnit = new Unit("1.0", 1.0);

		normalize();
		sourceName = "cables";

		write();
	}

	public ArrayView() { 
		super(1000,1000); 
		i0 = 500.0;
		j0 = 500.0;
		equatorial = new EquatorialCoordinates(0.0, 0.0, "J2000");
		horizontal = new HorizontalCoordinates(0.0, 0.0);
		
		delta = 1000.0*Unit.arcsec/sizeX;
		isHorizontal = true;
		LabocaScan scan = new LabocaScan();
		scan.horizontal = new HorizontalCoordinates(0.0, 0.0);
		scans.add(scan);
		init();
		clear();
		projection = new Gnomonic();
		projection.setReference(horizontal);

		pixel = new LabocaPixel[320];
		for(int i=0; i<pixel.length; i++) pixel[i] = new LabocaPixel(i);
		
		try { LabocaPixel.readPixelRCP(pixel, "laboca/master.rcp", pixel[317]); }
		catch(IOException e) { e.printStackTrace(); }
	}


	public void drawCircle(double dX, double dY, double r, double value) {
		if(Math.abs(dX) > 900.0 * Unit.arcsec) return;
		if(Math.abs(dY) > 900.0 * Unit.arcsec) return;
		
		double ic = fracIndexOfdX(dX);
		double jc = fracIndexOfdY(dY);

		double d = r/delta;

		int fromi = (int)Math.floor(ic - r/delta);
		int toi = (int)Math.ceil(ic + r/delta);
		int fromj = (int)Math.floor(jc - r/delta);
		int toj = (int)Math.ceil(jc + r/delta);

		Vector2D offset = new Vector2D();
		
		for(int i=fromi; i<=toi; i++) for(int j=fromj; j<=toj; j++) {
			offset.x = i-ic;
			offset.y = j-jc;			
			if(offset.length() < d) addPointAt(i, j, value, 1.0, 1.0, 1.0);
		}
	} 

}