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

import fusionOptics.Util;
import fusionOptics.interfaces.Absorber;
import fusionOptics.interfaces.IsoIsoInterface;
import fusionOptics.interfaces.IsoIsoStdFresnel;
import fusionOptics.interfaces.NullInterface;
import fusionOptics.materials.FusedSilica;
import fusionOptics.materials.IsotropicFixedIndexGlass;
import fusionOptics.materials.SchottSFL6;
import fusionOptics.materials.Vacuum;
import fusionOptics.surfaces.Disc;
import fusionOptics.surfaces.Iris;
import fusionOptics.surfaces.Square;
import fusionOptics.surfaces.Triangle;
import fusionOptics.types.Element;
import fusionOptics.types.Interface;
import fusionOptics.types.Medium;
import fusionOptics.types.Optic;
import fusionOptics.types.Surface;



public class MirrorBox  extends Optic {
	
	/** Box Width */
	private double w = 0.238;
	/** Box Height */
	private double h = 0.233;
	/** Box Length */
	private double l = 0.300;
	/** Depth of chamfer */
	private double a = 0.067;
	/** Height of chamfer */
	private double b = 0.158;
	/** Protective cover glass thickness.
	 * 3.5mm Fused Silica [Tobias Löbhard, email] 
	 *  */
	public double protectionCoverThickness = 0.0035;
	
	public Square lowerSqSide1 = new Square("lowerSqSide1", new double[]{ 0,0,0   }, new double[]{ w,0,0   }, new double[]{ w,0,h-b }, Absorber.ideal());
	//Square upperSqSide1 = new Square("upperSqSide1", new double[]{ a,0,h-b }, new double[]{ w,0,h-b }, new double[]{ w,0,h   }, Absorber.ideal());
	//Triangle triagSide1 = new Triangle("triagSide1", new double[]{ 0,0,h-b }, new double[]{ a,0,h-b }, new double[]{ a,0,h   }, Absorber.ideal());
	
	public Square lowerSqSide2 = new Square("lowerSqSide2", new double[]{ w,l,h-b }, new double[]{ w,l,0   }, new double[]{ 0,l,0 }, Absorber.ideal());
	public Square upperSqSide2 = new Square("upperSqSide2", new double[]{ w,l,h   }, new double[]{ w,l,h-b }, new double[]{ a,l,h-b }, Absorber.ideal());
	public Triangle triagSide2 = new Triangle("triagSide2", new double[]{ a,l,h   }, new double[]{ a,l,h-b }, new double[]{ 0,l,h-b }, Absorber.ideal());
	
	public Square top = new Square("top", new double[]{ a,l,h }, new double[]{ a,0,h }, new double[]{ w,0,h }, Absorber.ideal());
	public Square bottom = new Square("bottom", new double[]{ w,0,0 }, new double[]{ 0,0,0 }, new double[]{ 0,l,0 }, Absorber.ideal());
	
	public Square back = new Square("back", new double[]{ w,l,h }, new double[]{ w,0,h }, new double[]{ w,0,0 }, Absorber.ideal());
	
	public Square frontLower = new Square("lowerSqSide2", new double[]{ 0,l,0 }, new double[]{ 0,0,0 }, new double[]{ 0,0,h-b }, Absorber.ideal());
	public Square frontUpper = new Square("frontUpper", new double[]{ 0,l/2,h-b }, new double[]{ 0,0,h-b }, new double[]{ a,0,h }, Absorber.ideal());

	/** Material and interface for the protective cover of the box */
	//public Medium protectionCoverGlass = new Medium(new Vacuum());
	public Medium protectionCoverGlass = new Medium(new FusedSilica());	
	//public Interface protectionCoverIFace = NullInterface.ideal();
	//public Interface protectionCoverIFace = IsoIsoInterface.ideal(); 
	public Interface protectionCoverIFace = IsoIsoStdFresnel.ideal();

	public double protectionCoverCentre[] = new double[]{ a/2, 3*l/4, h-b/2 };
	public double protectionCoverNormal[] = frontUpper.getNormal();
	public double protectionCoverBackShift = 0.02;
	public double entraceRadius = 0.070;
	public double entraceIrisPos[] = Util.minus(protectionCoverCentre, Util.mul(protectionCoverNormal, protectionCoverThickness * 1.1));
	
	/** Iris used to model to circular hole in the box */
	public Iris holeIris = new Iris("holeIris", entraceIrisPos, protectionCoverNormal, 0.114, entraceRadius, Absorber.ideal());
	
	/** Glass disc in the mirror box hole, jused as a target/test and also to model the protective screen */
	public Disc protectionCoverFront = new Disc("holeGlassFront",
			new double[]{ 
					protectionCoverCentre[0] + (protectionCoverThickness/2 - protectionCoverBackShift) * protectionCoverNormal[0],
					protectionCoverCentre[1] + (protectionCoverThickness/2 - protectionCoverBackShift) * protectionCoverNormal[1],
					protectionCoverCentre[2] + (protectionCoverThickness/2 - protectionCoverBackShift) * protectionCoverNormal[2],
				}, protectionCoverNormal, 0.090, null, protectionCoverGlass, protectionCoverIFace);
	
	public Disc protectionCoverBack = new Disc("holeGlassBack", 
			new double[]{ 
				protectionCoverCentre[0] + (-protectionCoverThickness/2 - protectionCoverBackShift) * protectionCoverNormal[0],
				protectionCoverCentre[1] + (-protectionCoverThickness/2 - protectionCoverBackShift) * protectionCoverNormal[1],
				protectionCoverCentre[2] + (-protectionCoverThickness/2 - protectionCoverBackShift) * protectionCoverNormal[2],
			}, protectionCoverNormal, 0.090, protectionCoverGlass, null, protectionCoverIFace);
	
	public MirrorBox() {
		super("MirrorBox");
		
		for(Surface s : new Surface[] {
				lowerSqSide1, //upperSqSide1, triagSide1,
				lowerSqSide2, upperSqSide2, triagSide2,
				top, bottom, back,
				frontLower, frontUpper, 
				holeIris, protectionCoverFront, protectionCoverBack
			}) {
			addElement(s);
		}
	}
	
}
