package seed.minerva.aug.mse;
import java.util.ArrayList;
import java.util.LinkedList;

import seed.minerva.MinervaOpticsSettings;
import seed.minerva.optics.drawing.SVGRayDrawing;
import seed.minerva.optics.drawing.VRMLDrawer;
import seed.minerva.optics.interfaces.Absorber;
import seed.minerva.optics.interfaces.IsoIsoInterface;
import seed.minerva.optics.interfaces.IsoIsoStdFresnel;
import seed.minerva.optics.materials.SchottSFL6;
import seed.minerva.optics.materials.Vacuum;
import seed.minerva.optics.optics.SimpleDoubleConvexLens;
import seed.minerva.optics.surfaces.Cylinder;
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.Element;
import seed.minerva.optics.types.Medium;
import seed.minerva.optics.types.Optic;
import seed.minerva.optics.types.Surface;
import seed.minerva.optics.types.Interface;
import svg.SVGSplitView3D;

/** The main tube optics of the MSE system - Apr1997 Data.
 *
 * Tube optics as per the newer CAD diagrams
 * Radii of curvature given.
 * 
 * @author oliford
 *
 */
public class TubeOptics2 extends Optic {
	
	public Medium windowGlass = new Medium(new SchottSFL6());
	public Interface windowIFace = IsoIsoInterface.ideal();
	//public Interface windowIFace = 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();
	
	public Medium pemsGlass = new Medium(new Vacuum());
	public Interface pemsIFace = IsoIsoInterface.ideal();
	//public Interface pemsIFace = IsoIsoStdFresnel.ideal();
	
	/** Lens4 curvature radii and focal length disagree [T.Löbhard]
	 * true to use focal length and false to trust curvature radii. */
	boolean trustL4FocalLength = false;
			
	public Iris window1Iris = new Iris("window1Iris", new double[]{ 0.198, 0, 0 }, new double[]{ -1, 0, 0 }, 0.120/2, 0.105/2, Absorber.ideal());
	public Disc window1Front = new Disc("window1Front", new double[]{ 0.193, 0, 0 }, new double[]{ -1, 0, 0 }, 0.105/2, null, windowGlass, windowIFace);
	public Disc window1Back = new Disc("window1Back", new double[]{ 0.203, 0, 0 }, new double[]{ 1, 0, 0 }, 0.105/2, null, windowGlass, windowIFace);
	public Cylinder window1InnerTube = new Cylinder("window1InnerTube", new double[]{ 0.2235, 0, 0}, new double[]{ 1, 0, 0}, 0.120/2, 0.085, Absorber.ideal());		
	
	/** Not sure what this is, but it's probably the limiting aperture */
	public Cylinder block14 = new Cylinder("block14", new double[]{ 0.2335, 0, 0}, new double[]{ 1, 0, 0}, 0.070/2, 0.045, Absorber.ideal());		
	public Iris block14Iris = new Iris("block14Iris", new double[]{ 0.2335, 0, 0}, new double[]{ -1, 0, 0 }, 0.120/2, 0.070/2, Absorber.ideal());
	
	public Iris lens1Iris = new Iris("lens1Iris", new double[]{ 0.469, 0,0 }, new double[]{ -1, 0, 0 }, 0.1397/2, 0.116/2, Absorber.ideal());
	public Dish lens1Front = new Dish("lens1Front", new double[]{ 0.469, 0,0 }, new double[]{ 1, 0, 0 }, 0.61098, 0.125/2,  lensGlass, null, lensIFace);
	public Dish lens1Back = new Dish("lens1Back", new double[]{ 0.484, 0,0 }, new double[]{ -1, 0, 0}, 0.61098, 0.125/2, lensGlass, null, lensIFace);
	
	//public Iris hwpIris = new Iris("hwpIris", new double[]{ 0.757, 0,0 }, new double[]{ -1, 0, 0 }, 0.1397/2, 0.095/2, Absorber.ideal());
	public Iris hwpIris = new Iris("hwpIris", new double[]{ 0.757, 0,0 }, new double[]{ -1, 0, 0 }, 0.1397/2, 0.095/2, Absorber.ideal());
	//public Iris hwpIris = new Iris("hwpIris", new double[]{ 0.857, 0,0 }, new double[]{ -1, 0, 0 }, 0.1397/2, 0.095/2, Absorber.ideal());
	
	public Iris lens2Iris = new Iris("lens2Iris", new double[]{ 1.1005 - 5e-3, 0,0 }, new double[]{ -1, 0, 0 }, 0.1397/2,
			//0.105/2, // artificial to make ray tracing of this edge match observed image edge
			0.116/2, //original as per Apr97 lens data sheets (written in in pen) 
			Absorber.ideal());
	public Disc lens2Front = new Disc("lens2Front", new double[]{ 1.1005, 0,0 }, new double[]{ -1, 0, 0}, 0.125/2, null, lensGlass, lensIFace);
	public Dish lens2Back = new Dish("lens2Back", new double[]{ 1.1155, 0,0 }, new double[]{ -1, 0, 0 }, 0.28375, 0.125/2, lensGlass, null, lensIFace);

	public Iris lens3Iris = new Iris("lens3Iris", new double[]{ 1.5661 + 5e-3, 0,0 }, new double[]{ -1, 0, 0 }, 0.080, 0.060/2, Absorber.ideal());
	public Dish lens3Front = new Dish("lens3Front", new double[]{ 1.5661, 0,0 }, new double[]{ 1, 0, 0 }, 0.111134, 0.066/2, lensGlass, null, lensIFace);
	public Disc lens3Back = new Disc("lens3Back", new double[]{ 1.5811, 0,0 }, new double[]{ -1, 0, 0}, 0.066/2, lensGlass, null, lensIFace);
	
	public Iris lens4FrontIris = new Iris("lens4FrontIris", new double[]{ 1.6629 + 2.6e-3, 0,0 }, new double[]{ -1, 0, 0 }, 0.100/2, 0.047/2, Absorber.ideal());
	public Dish lens4Front = trustL4FocalLength ?
			new Dish("lens4Front", new double[]{ 1.6629, 0,0 }, new double[]{ 1, 0, 0 }, 0.133563, 0.052/2, lensGlass, null, lensIFace)  // assume focal length correct
			: new Dish("lens4Front", new double[]{ 1.6629, 0,0 }, new double[]{ 1, 0, 0 }, 0.042322, 0.052/2, lensGlass, null, lensIFace); //assume radius of curv. is correct
 
	public Dish lens4BackDish = new Dish("lens4BackDish", new double[]{ 1.6879, 0,0 }, new double[]{ 1, 0, 0 }, 0.102408, 0.0401/2, null, lensGlass, lensIFace);
	public Iris lens4BackFlat = new Iris("lens4BackFlat", new double[]{ 1.6879 + 2.0e-3, 0,0 }, new double[]{ 1, 0, 0 }, 0.052/2, 0.0399/2, null, lensGlass, lensIFace);
	public Iris lens4BackIris = new Iris("lens4BackIris", new double[]{ 1.6879 + 2.0e-3, 0,0 }, new double[]{ -1, 0, 0 }, 0.100/2, 0.051/2, Absorber.ideal());
	
	public Square fibreEnds = trustL4FocalLength ?  
				new Square("fibreEnds", new double[]{ 1.745254, 0,0 }, new double[]{ 1, 0, 0}, new double[]{ 0,0,1 }, 0.100, 0.100, Absorber.ideal()) //with L4.s2 focal length correct
				: new Square("fibreEnds", new double[]{ 1.70827 -0.000064, 0,0 }, new double[]{ 1, 0, 0}, new double[]{ 0,0,1 }, 0.100, 0.100, Absorber.ideal());  //with L4.s2 radius correct

	public Cylinder tube = new Cylinder("tube", new double[]{ 0.7935, 0, 0}, new double[]{ 1, 0, 0}, 0.1397/2, 1.145, Absorber.ideal());
	 
	public Square PEMsFront = new Square("PEMSFront", 
			new double[]{ 1.4861, -0.120, -0.120 },
			new double[]{ 1.4861, -0.120, +0.120 },
			new double[]{ 1.4861, +0.216, +0.120 }, 
			null, pemsGlass, pemsIFace);
							
	public Square PEMsBack = new Square("PEMsBack", 
			new double[]{ 1.5191, +0.216, +0.120 }, 
			new double[]{ 1.5191, -0.120, +0.120 },
			new double[]{ 1.5191, -0.120, -0.120 },
			null, pemsGlass, pemsIFace);
	
	public TubeOptics2() {
		super("tube");
		
		for(Surface s : new Surface[]{
				window1Iris, window1Front, window1Back, window1InnerTube,
				block14, block14Iris, 
				lens1Iris, lens1Front, lens1Back,
				hwpIris,
				lens2Iris, lens2Front, lens2Back,
				PEMsFront, PEMsBack, 
				lens3Iris, lens3Front, lens3Back,
				lens4FrontIris, lens4Front, lens4BackDish, lens4BackFlat, lens4BackIris,
				fibreEnds, 
				tube
				 }){
			addElement(s);
		}
	}
	
	public static void main(String[] args) {
		String outPath = MinervaOpticsSettings.getAppsOutputPath() + "/rayTracing/augImse";
		TubeOptics2 tubeOptics = new TubeOptics2();
		
		double w = 0.3;
		SVGRayDrawing svgOut = new SVGRayDrawing(outPath + "/tubeOptics", new double[]{ 0, -w, -w, 2, w, w }, true);
		
		svgOut.drawElement(tubeOptics);
		svgOut.destroy();
		
	}
	
	
}
