package seed.minerva.apps.mse;

import otherSupport.ColorMaps;
import oneLiners.OneLiners;
import algorithmrepository.Algorithms;
import seed.minerva.MinervaOpticsSettings;
import seed.minerva.aug.mse.AugMSESystem;
import seed.minerva.aug.mse.AugMseFaroData;
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.surfaces.Triangle;
import seed.minerva.optics.types.Intersection;
import seed.minerva.optics.types.RaySegment;

public class MakeFAROVRML {
	public static void main(String[] args) {
		AugMseFaroData faro = new AugMseFaroData();
		
		double A[][][] = faro.getPosA();
		double B[][][] = faro.getPosB();
		double cam[] = faro.getCameraPos();
		double lampRadius[] = new double[]{ 2.23, 2.31, 2.31 }; // few cm further back than upper tiles (which lamps are tucked in underneath)
		
		int lampIdx[][] = new int[][]{
				{ 1, 4 }, //Lamp1 = ch2, fib5 
				{ 5, 2 }, //Lamp2 = ch6 fib3/4
				{ 7, 0 }  //Lamp3 = ch7 fib1 - nov2013 by photo of patch panel
			};
		double lampSize = 0.02;
		
		//compared to photos and CAD data:
		//lamp 1 looks good
		//lamp 2 looks ok, but only just makes it past the port opening rim
		//lamp 3 is bad, it should be the other side of the 'lump' which
		//is in the cad data, images, and also the photos
		
		//one point from lump near lamp1:
		// [-2.2895, -0.1638, 0.5175]
		
		//taking lsat point fropm CAD model of limiter
		// - 4th tile down, top edge, far side of front face is visible as RHS edge:
		// [-2.1052, -0.7007, 0.2026]
		
		
		//VRMLDrawer vrmlOut = new VRMLDrawer(MinervaOpticsSettings.getAppsOutputPath() + "/faroMSE.vrml", 0.005);
		VRMLDrawer vrmlOut = new VRMLDrawer("/work/ipp/augddd-models/faroMSE.vrml", 0.005);
		vrmlOut.addVRML(AugMSESystem.vrmlScaleToAUGDDD);
		vrmlOut.setDrawPolarisationFrames(false);
		
		double cmap[][] = ColorMaps.alternating2D2x2(A.length, A[0].length);
				
		
		vrmlOut.startGroup("faroData");
		for(int i=0; i < A.length; i++){
			vrmlOut.startGroup("chan_" + i);
			for(int j=0; j < A[i].length; j++){
					double traceBack = 2;
				
					double u[] = Util.minus(B[i][j], A[i][j]);
					double l = Util.length(u);
					u = Util.reNorm(u);
					
					RaySegment ray = new RaySegment();
					ray.startPos = A[i][j];
					ray.dir = u;
					ray.length = l + traceBack;
					ray.wavelength = 1;
					ray.endHit = new Intersection();
					//ray.endHit.pos = B[i][j];
					ray.endHit.pos = Util.plus(A[i][j], Util.mul(u, l + traceBack));
					ray.E0 = new double[][]{ { 1,0,0,0 } };
					ray.E1 = new double[][]{ { 1,0,0,0 } };
					ray.up = Util.createPerp(ray.dir);
					
					vrmlOut.drawRay(ray, cmap[j*A.length+i]);			
			}
			vrmlOut.endGroup();
		}
		vrmlOut.endGroup();
		
		vrmlOut.startGroup("lampLines");
		for(int i=0; i < lampIdx.length; i++){			
			int ch = lampIdx[i][0];
			int fb = lampIdx[i][1];
			
			double traceBack = 2;
			
			double u[] = Util.minus(A[ch][fb], B[ch][fb]);
			double l = Util.length(u) + 1;
			u = Util.reNorm(u);
			double x0[] = Util.minus(B[ch][fb], Util.mul(u, traceBack));
			
			
			double ts[] = Algorithms.cylinderLineIntersection(x0, u, new double[]{ 0,0,0 }, new double[]{ 0,0,1 }, lampRadius[i]*lampRadius[i]);
			double t = ts.length > 1 ? Math.max(ts[0], ts[1]) : ts[0];
			
			double lampPos[] = Util.plus(x0, Util.mul(u, t));
			Box box = new Box("cameraPos", lampPos, lampSize,lampSize,lampSize, null, NullInterface.ideal());
			vrmlOut.drawOptic(box);
			
			OneLiners.dumpArray(lampPos);
			
			double c[] = Util.plus(x0, Util.mul(u, (t+1)/2));
			Cylinder cyld = new Cylinder("line_" + i, c, u, 0.01, (t+1), null, null, NullInterface.ideal());			
			
			vrmlOut.drawSurface(cyld);		
			
		}
		vrmlOut.endGroup();
		
		vrmlOut.startGroup("tiles");
		for(int i=0; i < 4; i++){
			double c1[] = AugMSESystem.pslTilePos[i];
			double c2[] = AugMSESystem.pslTilePos[i+1];
			double top[] = AugMSESystem.pslTilePos[5+1+i];
			
			Triangle tile = new Triangle("pslTile" + i, c1, top, c2, NullInterface.ideal());
			vrmlOut.drawSurface(tile);			
		}		
		vrmlOut.endGroup();
		
		vrmlOut.startGroup("mirrorBoxStuff");
		double stuffSize = 0.01;
		for(Object[] thing : AugMSESystem.faroMirrorBoxStuff){
			String name = (String)thing[1];
			double pos[] = (double[])thing[0];			
			Box thingBox = new Box(name, pos, stuffSize,stuffSize,stuffSize, null, NullInterface.ideal());
			vrmlOut.drawOptic(thingBox);
		}
		vrmlOut.endGroup();
		
		double camSize = 0.05;
		Box box = new Box("cameraPos", cam, camSize,camSize,camSize, null, NullInterface.ideal());
		vrmlOut.drawOptic(box);
		
		vrmlOut.addVRML("}");
		vrmlOut.destroy();
	}
}
