//includy definic funkci
include("paramevent.js");
include("loadscene.js");
include("runmodule.js");
include("visibility.js");
include("commandevent.js");

function runSimulation(track, vehicle) {
    var sceneID = -1;
    var cameraID = -1;
    var worldNodeID = -1;
    var carNodeID = -1;

    var trackFile;
    var worldNodeName;
    var trackCFGFile;
    var vehicleFile;
    var vehicleCFGFile;
    var vehicleBodyNodeName;

		carPositions = [
		[30.0, 0.0, 1, 0.0]
	];

    switch (vehicle) {
        case 'E-car':
        	vehicleFile = "../data/Cars/FabiaRS/FabiaRS.fhs";
        	vehicleCFGFile = "../data/Cars/FabiaRS/FabiaRS.xml";
        	vehicleBodyNodeName = "body";
        	break;

        case 'Fabia 1.6 16V':
            vehicleFile = "../data/Cars/FabiaRS/FabiaRS.fhs";
            vehicleCFGFile = "../data/Cars/FabiaRS/Fabia16.xml";
            vehicleBodyNodeName = "body";
    		break;

		case 'OctaviaSK371':
			vehicleFile = "C:/data/cave/sk371_showcar/371_car_II-18.fhs";
			vehicleCFGFile = "C:/data/cave/sk371_showcar/sk371_VehicleSimulator.xml";
			vehicleBodyNodeName = "SK371_body";
			break;

    	default:
    	    vehicleFile = "../data/Cars/Octavia/octavia.fhs";
    	    vehicleCFGFile = "../data/Cars/Octavia/Octavia.xml";
    	    vehicleBodyNodeName = "body";
    }

    switch (track) {
    	case 'bal2_skoda_navigace':
//    	    trackFile = "../data/Tracks/bal2_skoda_navigace/bal2_skoda_navigace.fhs.gz";
    	    trackFile = "../data/Tracks/bal2_skoda_navigace/bal2_skoda_navigace.vrut";
    	    worldNodeName = "hlavni";
    	    trackCFGFile = "../data/Tracks/bal2_skoda_navigace/bal2_skoda_navigace.xml";
    	    updateParamValue("VehicleSimulator", "swapLanes", "1");
    	    updateParamValue("VehicleSimulator", "sceneUnits", "1000");
    	    updateParamValue("Navigation", "FOV", "75");
    	    updateParamValue("Navigation", "farPlane", "3000005");
    	    updateParamValue("Navigation", "nearPlane", "1000");
				carPositions = [
					[-2255.1, -2211.5, 1.0, -0.189]
						];

    	  break;

        
    	case 'Real_trat':
//    	    trackFile = "../data/Tracks/Real_trat/Real_trat2.fhs.gz";
    	    trackFile = "../data/Tracks/Real_trat/Real_trat2-1000.fhs.gz";
    	    worldNodeName = "hlavni";
    	    trackCFGFile = "../data/Tracks/Real_trat/Real_trat.xml";
    	    updateParamValue("VehicleSimulator", "swapLanes", "0");
    	    updateParamValue("VehicleSimulator", "sceneUnits", "1000");
    	    updateParamValue("Navigation", "FOV", "75");
    	    updateParamValue("Navigation", "nearPlane", "1000");
    	    updateParamValue("Navigation", "farPlane", "5000000");
    		break;

    	case 'dalnice':
    	    trackFile = "../data/Tracks/dalnice/dalnice.vrut";
    	    worldNodeName = "hlavni";
    	    trackCFGFile = "../data/Tracks/dalnice/dalnice.xml";
    	    updateParamValue("VehicleSimulator", "swapLanes", "1");
    	    updateParamValue("VehicleSimulator", "sceneUnits", "1000");
    	    updateParamValue("Navigation", "FOV", "75");
    	    updateParamValue("Navigation", "nearPlane", "1000");
    	    updateParamValue("Navigation", "farPlane", "5000000");
				carPositions = [
					[-8, -6, 1.5, -1.5]
						];

    		break;

    	case 'trat_navi':
//    	    trackFile = "../data/Tracks/bal2_skoda_navigace/bal2_skoda_navigace.fhs.gz";
    	    trackFile = "../data/Tracks/trat_navi/trasa-f15.vrut";
    	    worldNodeName = "trasa";
    	    trackCFGFile = "../data/Tracks/trat_navi/trasa.xml";
    	    updateParamValue("VehicleSimulator", "swapLanes", "1");
    	    updateParamValue("VehicleSimulator", "sceneUnits", "1000");
    	    updateParamValue("Navigation", "FOV", "75");
    	    updateParamValue("Navigation", "farPlane", "3000005");
    	    updateParamValue("Navigation", "nearPlane", "1000");
	
				carPositions = [
				    [-988.911, -1611.8, 10.0, -0.189] // was until 3/4
///				    [-988.911+282.500, -1611.8+2825.000, 10.0, -0.189]
//				    [3565.797, 2179.876, 5.0, -0.189]
						];

    	  break;
				
    	case 'simple':
    	    trackFile = "../data/Tracks/simple/simple.fhs.gz";
    	    trackCFGFile = "../data/Tracks/simple/simple.xml";
    	    updateParamValue("VehicleSimulator", "swapLanes", "1");
    	    updateParamValue("Navigation", "FOV", "75");
    	    updateParamValue("Navigation", "farPlane", "5000");
    		break;

        case 'alpine-1':
            trackFile = "../data/Tracks/alpine-1/alpine-1.fhs";
            worldNodeName = "alpine-1";
            trackCFGFile = "../data/Tracks/alpine-1/alpine-1.xml";
            updateParamValue("VehicleSimulator", "swapLanes", "0");
            updateParamValue("VehicleSimulator", "sceneUnits", "1000");
            updateParamValue("Navigation", "FOV", "75");
            updateParamValue("Navigation", "farPlane", "3000000");
            updateParamValue("Navigation", "nearPlane", "100");
            break;

        case 'krizovatka_TZV5_lidi':
            trackFile = "c:/data/cave/prostredi/krizovatka_TZV5_lidi/krizovatka_TZV5_lidi2.fhs.gz";
            worldNodeName = "krizovatka_TZV5_lidi";
            trackCFGFile = "c:/data/cave/prostredi/krizovatka_TZV5_lidi/krizovatka_TZV5_lidi2.xml";
            updateParamValue("VehicleSimulator", "swapLanes", "0");
            updateParamValue("VehicleSimulator", "sceneUnits", "1000");
            updateParamValue("Navigation", "FOV", "75");
            updateParamValue("Navigation", "farPlane", "3000000");
            updateParamValue("Navigation", "nearPlane", "100");
            break;

        case 'Ehra':
            trackFile = "c:/data/cave/prostredi/Ehra/Ehra.fhs.gz";
            worldNodeName = "Ehra";
            trackCFGFile = "c:/data/cave/prostredi/Ehra/Ehra.xml";
            updateParamValue("VehicleSimulator", "swapLanes", "0");
            updateParamValue("VehicleSimulator", "sceneUnits", "1000");
            updateParamValue("Navigation", "FOV", "75");
            updateParamValue("Navigation", "farPlane", "3000000");
            updateParamValue("Navigation", "nearPlane", "100");
            break;

        default:
    		trackFile = "../data/Tracks/Parkoviste/p2.fhs";
    		trackCFGFile = "../data/Tracks/bal2_skoda_navigace/bal2_skoda_navigace.xml";
    		break;
    }

	updateParamValue("VehicleSimulator", "sendLogToRenderer", "true");
	updateParamValue("VehicleSimulator", "odeTimeStep", "2");
	updateParamValue("VehicleSimulator", "odeIterations", "50");
	updateParamValue("VehicleSimulator", "sleepDuration", "0");
	//setting this value to at least 1 improves the simulation performance significantly
	updateParamValue("VehicleSimulator", "sceneUpdateDelay", "16");
	updateParamValue("VehicleSimulator", "eventsFPS", "1000");
	updateParamValue("VehicleSimulator", "vehicleFile", vehicleCFGFile);
    updateParamValue("VehicleSimulator", "recFile", "../data/Cars/testrec.txt");
    runModule("VehicleSimulator");

    //load world
    sceneID = loadScene(trackFile, 10000);
    var scene = Scene.GetScene(sceneID);
    var nodesw = scene.GetNodes(worldNodeName);
    if (nodesw != undefined) {
        if (nodesw.length == 0) {
            LOGWARNING("Cannot find world node");
        }
        else {
            worldNodeID = nodesw[0].GetID();
        }
    }
    else {
        LOGWARNING("Cannot find world node");
    }
    LOG("World nodeID " + worldNodeID);
    loadInto(vehicleFile, sceneID, scene.GetRootID(), 100000);
    var nodes = scene.GetNodes(vehicleFile);
    if (nodes != undefined) {
        if (nodes.length==0) {
            LOGWARNING("Cannot find car node");
        }
        else {
            carNodeID = nodes[nodes.length-1].GetID();
        }
    }
    else {
        LOGWARNING("Cannot find car node");
    }
    LOG("Car nodeID " + carNodeID);
    updateParamValue("VehicleSimulator", "sceneID", sceneID);
    cameraID = renderScene(sceneID, 10000);

    bodyNodes = scene.GetNodes(vehicleBodyNodeName);
    if ((bodyNodes != undefined) && (bodyNodes.length != 0)) {
        scene.Move(cameraID, bodyNodes[0].GetID());
    }
    else {
        LOGWARNING("Cannot find car body node");
    }

   	//load world configuration
    updateParamValue("VehicleSimulator", "worldFile", trackCFGFile);
    updateParamValue("VehicleSimulator", "worldID", worldNodeID);

		
	runModule("CarHW");
//	updateParamValue("CarHW", "HWtype", "3");
	updateParamValue("CarHW", "enabled", "1");

	updateParamValue("RenderGl", "useFBO", "0");
		updateParamValue("RenderGl", "showStats", "1");
		if (true) {
				updateParamValue("RenderGl", "lighting", "0");
				updateParamValue("RenderGl", "backFaceCull", "1");
				updateParamValue("RenderGl", "useVBO", "1");
				updateParamValue("RenderGl", "antiAliasingMethod", "Coverage sampling");
				} else {
	updateParamValue("RenderGl", "antiAliasingMethod", "Multi sampling");
						}
	updateParamValue("RenderGl", "sortGeometries", "1");
	updateParamValue("RenderGl", "antiAliasingColorSampleCount", "8");
	updateParamValue("RenderGl", "antiAliasingCoverageSampleCount", "8");
	updateParamValue("RenderGl", "alphaToCoverage", "1");

	updateParamValue("VehicleSimulator", "addVehicle", "1");

	//assign the first available camera to the vehicle
	updateParamValue("VehicleSimulator", "vehicles", "3,0," + carNodeID);
	updateParamValue("VehicleSimulator", "vehicles", "1,0,0"); //the controllerID value for first car is set to zero
	updateParamValue("VehicleSimulator", "vehicles", "2,0,2"); //the cameraPosition value for first car is set to 2
	updateParamValue("VehicleSimulator", "vehicleCameras", "0,0,0");

		
	updateParamValue("SoundRenderer", "sceneID", sceneID);
	updateParamValue("SoundRenderer", "listenerNodeID", cameraID);
	updateParamValue("VehicleSimulator", "enabled", "1");

	if (true) {
			ii=0;
				updateParamValue("VehicleSimulator", "vehicles", "9,"+ii+","+carPositions[ii][0]+","+carPositions[ii][1]+","+carPositions[ii][2]); // starting car position
				updateParamValue("VehicleSimulator", "vehicles", "10,"+ii+",0,0,"+carPositions[ii][3]); // starting car orientation
		}

    //solve the F1-F6 keys here instead of inside VehicleSimulator
	function inputKeyCallback() {

	    this.perform = function (evt) {
	        var cdata = evt.kevt;
//	        LOG("key id=" + cdata.id + " type=" + cdata.type + " keyCode=" + cdata.keyCode + " unicodeKey=" + cdata.unicodeKey + " modifiers=" + cdata.modifiers);
	        if (cdata.type == getWxEventID("wxEVT_KEY_UP")) {
	            if (cdata.keyCode == 340) //F1
	                updateParamValue("VehicleSimulator", "vehicles", "2,0,1");//set first vehicle camera type to 1
	            if (cdata.keyCode == 341) //F2
	                updateParamValue("VehicleSimulator", "vehicles", "2,0,2");//set first vehicle camera type to 2
	            if (cdata.keyCode == 342) //F3
	                updateParamValue("VehicleSimulator", "vehicles", "2,0,3");//set first vehicle camera type to 3
	            if (cdata.keyCode == 343) //F4
	                updateParamValue("VehicleSimulator", "vehicles", "4,0,Reset");//reset first vehicle
	            if (cdata.keyCode == 344) //F5
	                updateParamValue("VehicleSimulator", "vehicles", "8,0,ResetPartial");//resetPartial first vehicle
	            if (cdata.keyCode == 345) //F6
	                updateParamValue("VehicleSimulator", "vehicles", "7,0,Reverse");//reverse first vehicle
            }
	    }
	}
	REGISTER_LISTENER(Event.EVT_INPUT_KEY, new inputKeyCallback());

		
	sleep(500);	
	runModule("SoundRenderer");

		if (false) {
		// Setup basic parameters of RenderGL3 module
	updateParamValue("rendergl3", "Use Offscreen FBO", "1");
	updateParamValue("rendergl3", "FBO Internal Format", "RGBA 16-bit Integer");
	updateParamValue("rendergl3", "FBO Multisampling Method", "Multi sampling");
	updateParamValue("rendergl3", "Enable lighting", "1");
			
	updateParamValue("rendergl3", "Render with VBO", "1");
	updateParamValue("rendergl3", "Show profiling", "0");
	updateParamValue("rendergl3", "Enable headlight", "0");

	updateParamValue("rendergl3", "Global ambient light", "0.4, 0.4, 0.4");

	sleep(3000);
	updateParamValue("rendergl3", "Show profiling", "1");
	updateParamValue("rendergl3", "Color Samples Count", "8");
				}
		
//  command("fullscreen 0 true");
}

//build GUI and wait for the RUN button
function actionOnComboBox(paramID, initialVal) {
	this.paramID = paramID;
    this.val = initialVal;

    this.perform = function (evt) {
        if (evt.paramIdentifier == this.paramID) {
            this.val = evt.value;
        }
    }

    this.getValue = function () {
        return this.val;
    }
}

var paramComboBoxID = REGISTER_PARAM_GUI_COMBOBOX("environment", "bal2_skoda_navigace", ["bal2_skoda_navigace", "dalnice", "Real_trat",  "trat_navi", "simple", "alpine-1", "krizovatka_TZV5_lidi", "Ehra"], "Environment used for the simulation");
var environmentCB = new actionOnComboBox(paramComboBoxID, "bal2_skoda_navigace");
REGISTER_LISTENER(Event.EVT_PARAM_SET, environmentCB);


var paramButtonID = REGISTER_PARAM_GUI_BUTTON("RunSimulation", "Run vehicle simulation with given environment.");

var paramVehicleComboBoxID = REGISTER_PARAM_GUI_COMBOBOX("vehicle", "E-car", ["E-car", "Fabia 1.6 16V", "Octavia 1.6MPI/75kW", "OctaviaSK371"], "Vehicle used for simulation");
var vehicleCB = new actionOnComboBox(paramVehicleComboBoxID, "E-car");


//var paramVehicleComboBoxID = REGISTER_PARAM_GUI_COMBOBOX("vehicle", "Octavia 1.6MPI/75kW", ["E-car", "Fabia 1.6 16V", "Octavia 1.6MPI/75kW"], "Vehicle used for simulation");
//var vehicleCB = new actionOnComboBox(paramVehicleComboBoxID, "Octavia 1.6MPI/75kW");

REGISTER_LISTENER(Event.EVT_PARAM_SET, vehicleCB);

function actionOnButton(paramID, envComboBox, vehicleComboBox) {
    this.paramID = paramID;
    this.val = 1;

    this.perform = function (evt) {
        if (this.val && (evt.paramIdentifier == this.paramID)) {
            this.val = 0;
            runSimulation(envComboBox.getValue(), vehicleComboBox.getValue());
        }
    }
}


REGISTER_LISTENER(Event.EVT_PARAM_SET, new actionOnButton(paramButtonID, environmentCB, vehicleCB));

//runSimulation(environmentCB.getValue(),vehicleCB.getValue());


/*
function inputTrackingCallback() {
    this.perform = function (evt) {
        var cdata = evt.deviceData;
        if (cdata.id == 0) {
            LOG("CarHW button=" + cdata.buttons);
        }
    };
}
REGISTER_LISTENER(Event.EVT_INPUT_TRACKING, new inputTrackingCallback());
*/
