package seed.minerva.permIMSE;

import jafama.FastMath;
import oneLiners.OneLiners;
import seed.minerva.optics.Util;
import seed.minerva.optics.interfaces.Absorber;
import seed.minerva.optics.interfaces.IsoIsoInterface;
import seed.minerva.optics.interfaces.NullInterface;
import seed.minerva.optics.interfaces.Reflector;
import seed.minerva.optics.materials.SchottSFL6;
import seed.minerva.optics.optics.DoubleGaussLens;
import seed.minerva.optics.optics.SimpleDoubleConvexLens;
import seed.minerva.optics.surfaces.Disc;
import seed.minerva.optics.surfaces.Dish;
import seed.minerva.optics.surfaces.Iris;
import seed.minerva.optics.surfaces.Square;
import seed.minerva.optics.types.Medium;
import seed.minerva.optics.types.Optic;

/** Basic optics mock-up for permenant IMSE */
public class PermIMSECurvedMirror extends Optic {
	

	/** NBI Geometry, auto generated by 
	 * 		minerva-aug/seed.minerva.neutralBeams.aug.AugHeatingBeams.main()
	 */

	public static final double nbiStartAll[][] = { 
		{ -1.9022743, -1.3847706, 0.0000000 }, //SE Q1 NORM LOW
		{ -1.8792922, -1.4524737, 0.0000000 }, //SE Q2 TANG LOW
		{ -1.8792922, -1.4524737, 0.0000000 }, //SE Q3 TANG HIGH (MSE)
		{ -1.9022743, -1.3847706, 0.0000000 }, //SE Q4 NORM HIGH
		{ 2.3980239, 1.4752788, 0.0000000 },
		{ 3.3800075, 1.6501967, 0.0000000 },
		{ 3.3800075, 1.6501967, 0.0000000 },
		{ 2.3980239, 1.4752788, 0.0000000 },
	};
	
	public static final double nbiUnitAll[][] = {
		{ 0.9181567, 0.3869007, -0.0854169 }, //SE Q1 NORM LOW
		{ 0.9639529, 0.2519894, -0.0854169 }, //SE Q2 TANG LOW
		{ 0.9639529, 0.2519894, 0.0854169 }, //SE Q3 TANG HIGH (MSE)
		{ 0.9181567, 0.3869007, 0.0854169 }, //SE Q4 NORM HIGH
		{ -0.9659023, -0.2444109, -0.0854169 },
		{ -0.9878308, -0.1038252, -0.1158040 },
		{ -0.9878308, -0.1038252, 0.1158040 },
		{ -0.9659023, -0.2444109, 0.0854169 },
	};

	/** The beam indecies actually match the AUG naming convention (except for the 1-based indexing)
	 * I think Q means 'Quelle' ('source' in German) */  
	public static final int BEAM_Q1 = 0;
	public static final int BEAM_Q2 = 1;
	public static final int BEAM_Q3 = 2;	
	public static final int BEAM_Q4 = 3;
	public static final int BEAM_Q5 = 4;
	public static final int BEAM_Q6 = 5;
	public static final int BEAM_Q7 = 6;
	public static final int BEAM_Q8 = 7;
	
	public double globalUp[] = new double[]{ 0, 0, 1 };
	
	public double portCentre[] = new double[]{ 0.990,  3.401,  0 };
	public double mirrorCentre[] = new double[]{ 0.225,  2.418,    0.159   };
	public double pointOnBeam[] = Util.plus(nbiStartAll[BEAM_Q8], Util.mul(nbiUnitAll[BEAM_Q8], 1.1));
	
	// mirrorNorm = (port/2 + beam/2 - mirror
	
	public double mirrorNormal[] = Util.reNorm(Util.plus(
							Util.reNorm(Util.minus(pointOnBeam, mirrorCentre)),
							Util.reNorm(Util.minus(portCentre, mirrorCentre))
						));
	
	double portNormal[] =  Util.reNorm(Util.minus(portCentre, mirrorCentre));
	
	//since out mirror is partly the primary lens, we call the first glass one L2
	double l2Centre[] = Util.plus(portCentre, Util.mul(portNormal, -0.100)); //L2 out on inside of port
	double imgPlaneCentre[] = Util.plus(portCentre, Util.mul(portNormal, 0.232));
	double systemUp[] = Util.reNorm(Util.cross(portNormal, Util.cross(globalUp, portNormal))); 
			
	public double mirrorRadiusOfCurv = 0.5;
	
	public double portRadius = 0.040;
	
	public double wavelen = 653e-9;
	
	public Dish mirror = new Dish("mirror", mirrorCentre, mirrorNormal, mirrorRadiusOfCurv, 0.050, null, null, Reflector.ideal());
	public Disc portA11 = new Disc("portA11", portCentre, portNormal, portRadius, NullInterface.ideal());
	
	Medium l2Medium = new Medium(new SchottSFL6());
	public SimpleDoubleConvexLens portLens = new SimpleDoubleConvexLens("portLens", l2Centre, portNormal, 0.045, l2Medium, IsoIsoInterface.ideal(), 0.250, wavelen);
	
	public Iris portCatch = new Iris("portCatch", portCentre, portNormal, 0.200, portRadius*1.05, null, null, Absorber.ideal());

	public Square imagePlane = new Square("imagePlane", imgPlaneCentre, portNormal, systemUp, 0.030, 0.030, null, null, Absorber.ideal());

	public PermIMSECurvedMirror() {
		super("permIMSE");
		
		OneLiners.dumpArray(pointOnBeam);
		System.out.println(FastMath.sqrt(pointOnBeam[0]*pointOnBeam[0]+pointOnBeam[1]*pointOnBeam[1]));
	 
		
		addElement(mirror);
		addElement(portLens);
		addElement(portA11);
		//addElement(portCatch);
		addElement(imagePlane);
	}
}
