package seed.minerva.permIMSE;

import jafama.FastMath;

import java.util.LinkedList;
import java.util.List;

import binaryMatrixFile.AsciiMatrixFile;

import otherSupport.StatusOutput;

import seed.minerva.MinervaOpticsSettings;
import seed.minerva.aug.mse.AugMSESystem;
import seed.minerva.optics.Util;
import seed.minerva.optics.drawing.VRMLDrawer;
import seed.minerva.optics.interfaces.NullInterface;
import seed.minerva.optics.optics.Box;
import seed.minerva.optics.surfaces.Cylinder;
import seed.minerva.optics.types.Element;
import seed.minerva.optics.types.Optic;
import algorithmrepository.Algorithms;

/** Lines of sight for the ECEI system, via Andreas B */
public class AugECEILoses {
	
	private double data[][];
	
	private int nChans;
	
	/** point A on LOS [chan][fibre][x/y/z] */
	private double A[][];
	/** point B on LOS [chan][fibre][x/y/z] */
	private double B[][];
	/** unit vec of LOS [chan][fibre][x/y/z] */
	private double u[][];
	
	public AugECEILoses() {
		data = AsciiMatrixFile.mustLoad(MinervaOpticsSettings.getMinervaSourcePath() + "/minerva-aug/data/ecei-los.txt", false);
		
		nChans = data.length;
		
		A = new double[nChans][];
		B = new double[nChans][];
		u = new double[nChans][];
		
		for(int i=0; i < nChans; i++){
			double R0 = data[i][0] / 1000;
			double Z0 = data[i][1] / 1000;
			double phi0 = (-data[i][2] + 9.0 * 360.0 / 16) * Math.PI / 180;
			
			double R1 = data[i][3] / 1000;
			double Z1 = data[i][4] / 1000;
			double phi1 = (-data[i][5] + 9.0 * 360.0 / 16) * Math.PI / 180;
			
			A[i] = new double[]{ R0 * FastMath.sin(phi0), R0 * FastMath.cos(phi0), Z0 };
			B[i] = new double[]{ R1 * FastMath.sin(phi1), R1 * FastMath.cos(phi1), Z1 };
			u[i] = Util.reNorm(Util.minus(B[i], A[i]));
		}
		
	}
	
	public Optic makeCylds() { return makeCylds(1.0); }
		
	/** Make cylinders representing the FARO measured MSE LOSs */
	public Optic makeCylds(double length) {
		double diameter = 0.001; 
		
		LinkedList<Element> cylds = new LinkedList<Element>();
		
		for(int i=0; i < nChans; i++){
			double u[] = Util.minus(B[i], A[i]);
			double l = length*Util.dot(u,u);
			u = Util.reNorm(u);
				
			Cylinder cyld = new Cylinder(
					"ch"+i,
					Util.mul(Util.plus(A[i], B[i]), 0.5),
					u,
					diameter/2,
					l,
					NullInterface.ideal());

			cyld.setDrawingDetails(6, 5);
			cylds.add(cyld);
		}
		
		return new Optic("eceiCylds", cylds);
	}
	

	/** unit vec of LOS [chan][x/y/z] */
	public double[][] getUnitVecs(){ return this.u; }
	/** first point of FARO measurement [chan][x/y/z] */
	public double[][] getPosA(){ return this.A; }
	/** first point of FARO measurement [chan][x/y/z] */
	public double[][] getPosB(){ return this.B; }
	
	public static void main(String[] args) {
		AugECEILoses ecei = new AugECEILoses();
		
		VRMLDrawer vrmlOut = new VRMLDrawer(MinervaOpticsSettings.getAppsOutputPath() + "/rayTracing/permImse/ecei.vrml", 0.005);
		vrmlOut.addVRML(AugMSESystem.vrmlScaleToAUGDDD);
		
		vrmlOut.drawOptic(ecei.makeCylds());

		vrmlOut.addVRML("}"); //end of rotate/transform
		vrmlOut.destroy();
	}
	
}
