package ipp.imse.fusionOptics.mse;
import java.util.ArrayList;
import java.util.LinkedList;

import fusionOptics.interfaces.Absorber;
import fusionOptics.interfaces.IsoIsoInterface;
import fusionOptics.interfaces.IsoIsoStdFresnel;
import fusionOptics.materials.SchottSFL6;
import fusionOptics.materials.Vacuum;
import fusionOptics.surfaces.Cylinder;
import fusionOptics.surfaces.Disc;
import fusionOptics.surfaces.Dish;
import fusionOptics.surfaces.Iris;
import fusionOptics.surfaces.Square;
import fusionOptics.types.Element;
import fusionOptics.types.Interface;
import fusionOptics.types.Medium;
import fusionOptics.types.Optic;
import fusionOptics.types.Surface;


/** The main tube optics of the original MSE system - ~Jan1997 Data.
 *
 * Tube optics as per CAD diagram (with curvature radii calc'ed from old ray tracing report)
 * 
 * This is wrong. The actual system design was different. See TubeOptics2
 *  	
 * @author oliford
 *
 */
public class TubeOptics1 extends Optic {
	
	public Medium windowGlass = new Medium(new SchottSFL6());
	public Interface windowIFace = IsoIsoInterface.ideal(); //IsoIsoStdFresnel.ideal();

	public Medium lensGlass = new Medium(new SchottSFL6());
	//IsotropicFixedIndexGlass lensGlass = new IsotropicFixedIndexGlass(1.805);
	public Interface lensIFace = IsoIsoInterface.ideal();
	//public Interface lensIFace = IsoIsoStdFresnel.ideal();
	
	/** Half wave plate - which apparently was never installed [ Robert Wolf ]*/
	public Medium hwpGlass = new Medium(new Vacuum());	
	public Interface hwpIFace = IsoIsoInterface.ideal();
	//public Interface hwpIFace = IsoIsoStdFresnel.ideal();
	
	public Medium pemsGlass = new Medium(new Vacuum());
	public Interface pemsIFace = IsoIsoInterface.ideal();
	//public Interface pemsIFace = IsoIsoStdFresnel.ideal();
	
	
	public Iris window1Iris = new Iris("window1Iris", new double[]{ 0.196, 0, 0 }, new double[]{ -1, 0, 0 }, 0.059, 0.050, Absorber.ideal());
	public Disc window1Front = new Disc("window1Front", new double[]{ 0.196, 0, 0 }, new double[]{ -1, 0, 0 }, 0.050, null, windowGlass, windowIFace);
	public Disc window1Back = new Disc("window1Back", new double[]{ 0.204, 0, 0 }, new double[]{ 1, 0, 0 }, 0.050, null, windowGlass, windowIFace);
	public Cylinder window1InnerTube = new Cylinder("window1InnerTube", new double[]{ 0.214, 0, 0}, new double[]{ 1, 0, 0}, 0.059, 0.058, Absorber.ideal());		
	
	public Iris lens1Iris = new Iris("lens1Iris", new double[]{ 0.2595, 0,0 }, new double[]{ -1, 0, 0 }, 0.062, 0.025, Absorber.ideal());
	public Dish lens1Front = new Dish("lens1Front", new double[]{ 0.2595, 0,0 }, new double[]{ 1, 0, 0 }, 0.311, 0.025,  lensGlass, null, lensIFace);
	public Disc lens1Back = new Disc("lens1Back", new double[]{ 0.264, 0,0 }, new double[]{ 1, 0, 0}, 0.025, null, lensGlass, lensIFace);
					
	public Iris hwpIris = new Iris("hwpIris", new double[]{ 0.500, 0, 0 }, new double[]{ -1, 0, 0 }, 0.062, 0.030, Absorber.ideal());
	public Disc hwpFront = new Disc("hwpFront", new double[]{ 0.500, 0, 0 }, new double[]{ -1, 0, 0 }, 0.030, null, hwpGlass, hwpIFace);
	public Disc hwpBack = new Disc("hwpBack", new double[]{ 0.5067, 0, 0 }, new double[]{ 1, 0, 0 }, 0.030, null, hwpGlass, hwpIFace);
	
	public Iris lens2Iris = new Iris("lens2Iris", new double[]{ 0.761, 0,0 }, new double[]{ -1, 0, 0 }, 0.062, 0.058, Absorber.ideal());
	public Disc lens2Front = new Disc("lens2Front", new double[]{ 0.761, 0,0 }, new double[]{ -1, 0, 0}, 0.058, null, lensGlass, lensIFace);
	public Dish lens2Back = new Dish("lens2Back", new double[]{ 0.773, 0,0 }, new double[]{ -1, 0, 0 }, 0.243, 0.058, lensGlass, null, lensIFace);
	
	public Iris lens3AIris = new Iris("lens3AIris", new double[]{ 1.535, 0,0 }, new double[]{ -1, 0, 0 }, 0.062, 0.040, Absorber.ideal());
	public Dish lens3AFront = new Dish("lens3AFront", new double[]{ 1.52774, 0,0 }, new double[]{ 1, 0, 0 }, 0.128, 0.040, lensGlass, null, lensIFace);
	public Disc lens3ABack = new Disc("lens3ABack", new double[]{ 1.535, 0,0 }, new double[]{ 1, 0, 0}, 0.040, null, lensGlass, lensIFace);
	
	public Iris lens3BIris = new Iris("lens3BIris", new double[]{ 1.54779, 0,0 }, new double[]{ -1, 0, 0 }, 0.064, 0.037, Absorber.ideal());
	public Dish lens3BFront = new Dish("lens3BFront", new double[]{ 1.53596, 0,0 }, new double[]{ 1, 0, 0 }, 0.064, 0.037, lensGlass, null, lensIFace);
	public Dish lens3BBack = new Dish("lens3BBack", new double[]{ 1.54318, 0,0 }, new double[]{ 1, 0, 0 }, 0.128, 0.037, null, lensGlass, lensIFace);
	
	//actually a slight shift of the final plate to focus
	public Square fibreEnds = new Square("fibreEnds", new double[]{ 1.625 - 0.003983, 0,0 }, new double[]{ -1, 0, 0}, new double[]{ 0,0,1 }, 0.100, 0.100, Absorber.ideal());
	//without lens3B, that needs to be 105mm futher back
	//for the 22/8/11 mirror position: -0.003964
	//for the 7/12/11 mirror position: -0.003983
	
	public Cylinder innerTube = new Cylinder("innerTube", new double[]{ 0.692, 0, 0}, new double[]{ 1, 0, 0}, 0.062, 0.937, Absorber.ideal());
	
	public Square PEMsFront = new Square("PEMSFront", 
			new double[]{ 1.420, -0.120, -0.120 },
			new double[]{ 1.420, -0.120, +0.120 },
			new double[]{ 1.420, +0.216, +0.120 }, 
			null, pemsGlass, pemsIFace);
							
	public Square PEMsBack = new Square("PEMsBack", 
			new double[]{ 1.455, +0.216, +0.120 }, 
			new double[]{ 1.455, -0.120, +0.120 },
			new double[]{ 1.455, -0.120, -0.120 },
			null, pemsGlass, pemsIFace);
	
	public TubeOptics1() {
		super("tube");
		
		for(Surface s : new Surface[]{
				window1Iris, window1Front, window1Back, window1InnerTube,
				lens1Iris, lens1Front, lens1Back,
				hwpIris,hwpFront, hwpBack,
				lens2Iris, lens2Front, lens2Back,
				PEMsFront, PEMsBack, 
				lens3AIris, lens3AFront, lens3ABack,
				lens3BFront, lens3BBack, lens3BIris,
				fibreEnds, innerTube }){
			addElement(s);
		}
	}
}
