package org.spview.filehandler;
/*
* Class of prediction file
*/

import java.awt.geom.Point2D;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;

import javax.swing.JOptionPane;

import org.spview.point.PredXPoint;

/**
 * This class defines prediction data.
 */
public class PredFile {

	private String name; // file name
	private String type; // type (TDS/HITRAN/PICKETT)
	private double[] x; // X
	private double[] y; // Y
	private String[] jsyn; // assignment string
	private int[] jinf; // jinf extracted from jsyn

	private int nbxy; // nb of points

	private String str; // to read file
	private BufferedReader br;
	private String lnsep; // line separator

////////////////////////////////////////////////////////////////////

	/**
	 * Construct a new PredFile. <br>
	 * (TDS, HITRAN or PICKETT type)
	 *
	 * @param cname name of the file
	 * @param ctype type of the file
	 */
	public PredFile(String cname, String ctype) {

		name = cname; // file name
		type = ctype; // type (TDS/HITRAN/PICKETT)

		lnsep = System.getProperty("line.separator");
		nbxy = 0; // nb of points
	}

////////////////////////////////////////////////////////////////////

	/**
	 * Read file. <br>
	 * validity is tested following FORMAT : 1022 of spect.f, 1000 of spech.f
	 */
	public boolean read() {

		// to keep points, unknown nb of points
		ArrayList<Double> alx = new ArrayList<Double>(); // frequency
		ArrayList<Double> aly = new ArrayList<Double>(); // intensity
		ArrayList<String> aljsyn = new ArrayList<String>(); // assignment
		ArrayList<String> alxjsyn = new ArrayList<String>(); // extended assignment
		String cjsyn = ""; // current assignment
		String cxjsyn = ""; // current extended assignment
		try {
			Point2D data = null;
			br = new BufferedReader(new FileReader(new File(name))); // open
			while ((str = br.readLine()) != null) { // line read
				if (type.equals("HITRAN")) {
					data = HITRANFile.extractXY(str);
					if (data != null) {
						cjsyn = HITRANFile.extractAssignment(str);
						cxjsyn = HITRANFile.extractExtendedAssignment(str);
					}
				} else if (type.equals("PICKETT")) {
					data = PickettFile.extractXY(str);
					if (data != null) {
						cjsyn = PickettFile.extractAssignment(str);
					}
				} else {
					data = TDSFile.extractXY(str);
					if (data != null) {
						cjsyn = TDSFile.extractAssignment(str);
					}
				}
				if (data != null) {
					alx.add(data.getX()); // keep data
					aly.add(data.getY());
					
					// test if jsyn is not empty
					if (cjsyn.length() == 0) {
						JOptionPane.showMessageDialog(null, str + lnsep + "Empty jsyn in file" + lnsep + name);
						return false;
					}

					// test if xjsyn (HITRAN) or jsyn (TDS) is uniq
					if (type.equals("HITRAN")) {
						// HITRAN
						if (alxjsyn.contains(cxjsyn)) {
							JOptionPane.showMessageDialog(null, cxjsyn + lnsep + "Duplicated in file" + lnsep + name);
							return false;
						}
						alxjsyn.add(cxjsyn); // keep data
					} else {		
						// TDS, PICKETT
						if (aljsyn.contains(cjsyn)) {
							JOptionPane.showMessageDialog(null, cjsyn + lnsep + "Duplicated in file" + lnsep + name);
							return false;
						}
					}
					aljsyn.add(cjsyn); // keep data
				}
			}
		} catch (IOException ioe) { // IO error
			JOptionPane.showMessageDialog(null, "IO error while reading file" + lnsep + name + lnsep + ioe);
			return false;
		} finally {
			// close
			if (br != null) {
				try {
					br.close();
				} catch (IOException ignored) {
				}
			}
		}
		// save data
		nbxy = alx.size(); // nb of points
		if (nbxy == 0) {
			// no point
			JOptionPane.showMessageDialog(null, "No valid data found in file" + lnsep + name);
			return false;
		}
		x = new double[nbxy];
		y = new double[nbxy];
		jsyn = new String[nbxy];
		jinf = new int[nbxy];
		// sort
		PredXPoint[] pxpt = new PredXPoint[nbxy]; // compare X
		for (int i = 0; i < nbxy; i++) {
			pxpt[i] = new PredXPoint(((Double) alx.get(i)).doubleValue(), ((Double) aly.get(i)).doubleValue(),
					(String) aljsyn.get(i));
		}
		Arrays.sort(pxpt); // sort
		// save data
		for (int i = 0; i < nbxy; i++) {
			x[i] = pxpt[i].getX();
			y[i] = pxpt[i].getY();
			jsyn[i] = pxpt[i].getJsyn();
			try {
				// extract jinf from jsyn
				// TDS, HITRAN
				jinf[i] = Integer.parseInt(jsyn[i].substring(0, 3).trim());
			} catch (NumberFormatException e) {
				// format error
				jinf[i] = -1;
			}
		}

		return true;
	}

	/**
	 * Get number of data points.
	 */
	public int getNbxy() {

		return nbxy;
	}

	/**
	 * Get X array.
	 */
	public double[] getX() {

		return x;
	}

	/**
	 * Get Y array.
	 */
	public double[] getY() {

		return y;
	}

	/**
	 * Get X value.
	 */
	public double getX(int id) {

		return x[id];
	}

	/**
	 * Get Y value.
	 */
	public double getY(int id) {

		return y[id];
	}

	/**
	 * Get Jinf array.
	 */
	public int[] getJinf() {

		return jinf;
	}

	/**
	 * Get Jsyn assignment array.
	 */
	public String[] getJsyn() {

		return jsyn;
	}

}
