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


var sceneID = -1;
var cameraID = -1;
var bodyNodes;

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

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

	var templatePrefixes = [ "../data/Cars/Misc/Saab_93",
							 "../data/Cars/Misc/Toyota_RAV4",
							 "../data/Cars/Misc/Audi_Q7"];
							// ../data/Cars/FabiaRS/FabiaRS",
	var templates = [];
	var templateCounts = [];

	var vehicleConfigs = [];
	var vehicleIDs = [];


if (1) {
	// Setup basic parameters of RenderGL3 module
	if (1) {
			// core profile setup
			updateParamValue("rendergl3", "Core profile", "1");
			updateParamValue("rendergl3", "Major Version Number", "4");
			updateParamValue("rendergl3", "Minor Version Number", "5");
			}
	updateParamValue("rendergl3", "Use Offscreen FBO", "1");
	// updateParamValue("rendergl3", "FBO Internal Format", "RGBA 16-bit Integer");
	updateParamValue("rendergl3", "FBO Multisampling Method", "Multi sampling");
	updateParamValue("rendergl3", "Color Samples Count", "8");

	updateParamValue("rendergl3", "Render with VBO", "1");
	updateParamValue("rendergl3", "Show profiling", "1");
	updateParamValue("rendergl3", "Enable headlight", "0");
	updateParamValue("rendergl3", "Enable lighting", "1");
	updateParamValue("rendergl3", "Sorting", "Group by Effect State, than by Effect Data");
	updateParamValue("rendergl3", "Back-face culling", "1");

	// Set ambient light
	updateParamValue("rendergl3", "Global ambient light", "0.4, 0.4, 0.4");
}

if (1) {
	updateParamValue("RenderGl", "useFBO", "0");
	updateParamValue("RenderGl", "showStats", "1");
	if (true) {
		updateParamValue("RenderGl", "lighting", "1");
		updateParamValue("RenderGl", "headlight", "0");

		updateParamValue("RenderGl", "backFaceCull", "1");
		// disable backface culling - for the new cars the interior dissappears with BFC
		// updateParamValue("RenderGl", "backFaceCull", "0");
		updateParamValue("RenderGl", "useVBO", "1");
		updateParamValue("RenderGl", "antiAliasingMethod", "Coverage sampling");
	}
	else {
		updateParamValue("RenderGl", "antiAliasingMethod", "Multi sampling");
	}
	// updateParamValue("RenderGl", "sortGeometries", "1");
	updateParamValue("RenderGl", "sortGeometries", "2");
	updateParamValue("RenderGl", "antiAliasingColorSampleCount", "8");
	updateParamValue("RenderGl", "antiAliasingCoverageSampleCount", "8");
	updateParamValue("RenderGl", "alphaToCoverage", "1");
}

	switch (vehicle) {

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

		case 'Toyota RAV4':
			vehicleFile = "../data/Cars/Misc/Toyota_RAV4.vrut";
			vehicleCFGFile = "../data/Cars/Misc/Toyota_RAV4.xml";
			vehicleBodyNodeName = "body";
			break;

		case 'Audi Q7':
			vehicleFile = "../data/Cars/Misc/Audi_Q7.vrut";
			vehicleCFGFile = "../data/Cars/Misc/Audi_Q7.xml";
			vehicleBodyNodeName = "body";
			break;

		case 'Saab 93':
			vehicleFile = "../data/Cars/Misc/Saab_93.vrut";
			vehicleCFGFile = "../data/Cars/Misc/Saab_93.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";
	}

	trafficGraphFile = "";
	carPositions = [
		[30.0, 0.0, 1, 0.0],
		[20.0, 0.0, 1, 0.0],
		[10.0, 0.0, 1, 0.0],
		[0.0, 0.0, 1, 0.0],
	]

	var CAR_COUNT = 1;
	var EXTERNALLY_DRIVEN_VEHICLE = -1;
	var EXTERNALLY_DRIVEN_VEHICLE_SPEED = 20.0; // m/s

	switch (track) {
		case 'bal2_skoda_navigace':
			CAR_COUNT = 5;
			EXTERNALLY_DRIVEN_VEHICLE = 4; // index
			worldNodeName = "hlavni";
			trackFile = "../data/Tracks/bal2_skoda_navigace/bal2_skoda_navigace.vrut";
			trackCFGFile = "../data/Tracks/bal2_skoda_navigace/bal2_skoda_navigace.xml";
			worldNodeName = "hlavni";
			trafficGraphFile = "../data/Tracks/bal2_skoda_navigace/bal2_skoda_navigace-traffic.xml"
			carPositions = [
					// usual starting pos
					[-2253.68, -2211.40, 1.0, -0.189],   // 16.13 3.08
					[-2269.81, -2214.48, 1.0, -0.180],   // 19.67 3.58
					[-2289.48, -2218.06, 1.0, -0.185],   // 19.66 3.68
					[-2234.04, -2207.59, 1.0, -0.192],   // 19.64 3.81
					[-2214.48, -2203.40, 1.0, -0.211]    // 19.56 4.19
				]
			// before tunnel starting pos
			carPositions[0] = [-2500, 103.5, 1.0, 1.7];   // 16.13 3.08
			// crossroads starting pos - waiting vehicle
			if (EXTERNALLY_DRIVEN_VEHICLE != -1) {
				carPositions[0] = [-328.0, 557.6, 1.0, 4.15];                 		  // pos -328.0, 557.6, 1.0 ori 0.46 -0.88
				carPositions[EXTERNALLY_DRIVEN_VEHICLE] = [-250.05, 376.10, 1.0, -3.5]; // pos -250.05, 376.10, 0.78 ori 0.941 0.339 0.00
			}
			updateParamValue("VehicleSimulator", "swapLanes", "1");
			updateParamValue("VehicleSimulator", "sceneUnits", "1000");
			updateParamValue("Navigation", "FOV", "75");
			updateParamValue("Navigation", "farPlane", "3000005");
			updateParamValue("Navigation", "nearPlane", "300");
			break;

		case 'bal2_new':
			CAR_COUNT = 5;
			worldNodeName = "hlavni";
			trackFile = "../data/Tracks/bal2_new/bal2_skoda_navigace.vrut";
			trackCFGFile = "../data/Tracks/bal2_new/bal2_skoda_navigace.xml";
			worldNodeName = "hlavni";
			trafficGraphFile = "../data/Tracks/bal2_new/bal2_skoda_navigace-traffic.xml"
			carPositions = [
					[-2253.68, -2211.40, 1.0, -0.189],   // 16.13 3.08
					[-2269.81, -2214.48, 1.0, -0.180],   // 19.67 3.58
					[-2289.48, -2218.06, 1.0, -0.185],   // 19.66 3.68
					[-2234.04, -2207.59, 1.0, -0.192],   // 19.64 3.81
					[-2214.48, -2203.40, 1.0, -0.211]    // 19.56 4.19
				]

			updateParamValue("VehicleSimulator", "swapLanes", "1");
			updateParamValue("VehicleSimulator", "sceneUnits", "1000");
			updateParamValue("Navigation", "FOV", "75");
			updateParamValue("Navigation", "farPlane", "3000005");
			updateParamValue("Navigation", "nearPlane", "300");
			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':
			CAR_COUNT = 10;
			// temporary tests with just one car
			CAR_COUNT = 6;
			trackFile = "../data/Tracks/dalnice/dalnice.vrut";
			carPositions = [
				[-8, -6, 1.5, -1.5],
				[-11.1, -7.4, 1.5, -1.5],
				[-11.1, -37.4, 1.5, -1.5],
				[-11.1, -67.4, 1.5, -1.5],
				[-7.66261, -21.0486, 1.5, -1.5],
				[-7.66261, -52.0486, 1.5, -1.5],
				[-7.66261, -82.0486, 1.5, -1.5],
				[-3.87186, -21.014, 1.5, -1.5],
				[-3.86275, -46.0168, 1.5, -1.5],
				[-3.85366, -71.0196, 1.5, -1.5]
			]
			worldNodeName = "hlavni";
			trackCFGFile = "../data/Tracks/dalnice/dalnice.xml";
			trafficGraphFile = "../data/Tracks/dalnice/dalnice-traffic.xml"
			updateParamValue("VehicleSimulator", "swapLanes", "1");
			updateParamValue("VehicleSimulator", "sceneUnits", "1000");
			updateParamValue("Navigation", "FOV", "75");
			updateParamValue("Navigation", "nearPlane", "200");
			updateParamValue("Navigation", "farPlane", "5000000");
			break;

		case 'dalnice_new':
			CAR_COUNT = 5;
//			CAR_COUNT = 2;
			trackFile = "../data/Tracks/dalnice_new/dalnice.vrut";
			carPositions = [
//				[-8, -6, 1.5, -1.5],
//				[6484.16, -16343.5, 1.5, 0.7],
//				[6793, -18764.9, 1.5, 0.7],
//              [4193.14, -8459.2, 1.5, -1.5],
				[4193.14, -8459.2, 1.5, -1.2],
				[-11.1, -7.4, 1.5, -1.5],
				[-11.1, -37.4, 1.5, -1.5],
				[-11.1, -67.4, 1.5, -1.5],
				[-7.66261, -21.0486, 1.5, -1.5],
				[-7.66261, -52.0486, 1.5, -1.5],
				[-7.66261, -82.0486, 1.5, -1.5],
				[-3.87186, -21.014, 1.5, -1.5],
				[-3.86275, -46.0168, 1.5, -1.5],
				[-3.85366, -71.0196, 1.5, -1.5]
			]
//			carPositions[0] = [7955.1, -20446.1, 1.5, 1.0]; // dalnice -> cca 32 km - problem s presnosti
			worldNodeName = "hlavni";
			trackCFGFile = "../data/Tracks/dalnice_new/dalnice.xml";
			trafficGraphFile = "../data/Tracks/dalnice_new/dalnice-traffic.xml"
			updateParamValue("VehicleSimulator", "swapLanes", "1");
			updateParamValue("VehicleSimulator", "sceneUnits", "1000");
			updateParamValue("Navigation", "FOV", "75");
			updateParamValue("Navigation", "nearPlane", "500");
			updateParamValue("Navigation", "farPlane", "5000000");
			updateParamValue("RenderGl", "backFaceCull", "1");
			updateParamValue("RenderGl", "lighting", "0");
			break;

    	case 'trat_navi_f10':
			CAR_COUNT = 5;
    	    trackFile = "../data/Tracks/trat_navi/trasa-f10.vrut";
    	    worldNodeName = "trasa";
    	    trackCFGFile = "../data/Tracks/trat_navi/trasa.xml";
  	trafficGraphFile = "../data/Tracks/trat_navi/trasa-f10-traffic.xml";
    	    updateParamValue("VehicleSimulator", "swapLanes", "1");
    	    updateParamValue("VehicleSimulator", "sceneUnits", "1000");
    	    updateParamValue("Navigation", "FOV", "75");
    	    updateParamValue("Navigation", "farPlane", "2000000");
    	    updateParamValue("Navigation", "nearPlane", "500");
			updateParamValue("RenderGl", "lighting", "0");

	     carPositions = [
						[3565, 2180, 1, -0.189],
						[3575, 2180, 1, -0.189],
						[3585, 2180, 1, -0.189],
						[3595, 2180, 1, -0.189],
						[3605, 2180, 1, -0.189]
				];
    	  break;

    	case 'trat_navi_f15':
			CAR_COUNT = 5;
    	    trackFile = "../data/Tracks/trat_navi/trasa-f15.vrut";
    	    worldNodeName = "trasa";
    	    trackCFGFile = "../data/Tracks/trat_navi/trasa.xml";
  	trafficGraphFile = "../data/Tracks/trat_navi/trasa-f15-traffic.xml";
    	    updateParamValue("VehicleSimulator", "swapLanes", "1");
    	    updateParamValue("VehicleSimulator", "sceneUnits", "1000");
    	    updateParamValue("Navigation", "FOV", "75");
    	    updateParamValue("Navigation", "farPlane", "2000000");
    	    updateParamValue("Navigation", "nearPlane", "500");
			updateParamValue("RenderGl", "lighting", "0");

	     carPositions = [
						[3565, 2180, 1, -0.189],
						[3575, 2180, 1, -0.189],
						[3585, 2180, 1, -0.189],
						[3595, 2180, 1, -0.189],
						[3605, 2180, 1, -0.189]
				];
    	  break;
	    
    	case 'trat_navi_1m':
			CAR_COUNT = 5;
			//    	    trackFile = "../data/Tracks/bal2_skoda_navigace/bal2_skoda_navigace.fhs.gz";
    	    trackFile = "../data/Tracks/trat_navi/trasa.vrut";
    	    worldNodeName = "trasa";
    	    trackCFGFile = "../data/Tracks/trat_navi/trasa.xml";
			trafficGraphFile = "../data/Tracks/trat_navi/trasa-traffic.xml";
    	    updateParamValue("VehicleSimulator", "swapLanes", "1");
    	    updateParamValue("VehicleSimulator", "sceneUnits", "1000");
    	    updateParamValue("Navigation", "FOV", "75");
    	    updateParamValue("Navigation", "farPlane", "2000000");
    	    updateParamValue("Navigation", "nearPlane", "500");
			updateParamValue("RenderGl", "lighting", "0");
						carPositions = [
						[3565, 2180, 1, -0.189],
						[3575, 2180, 1, -0.189],
						[3585, 2180, 1, -0.189],
						[3595, 2180, 1, -0.189],
						[3605, 2180, 1, -0.189]
						    
	    // carPositions = [
						// [-989, -1612, 1, -0.189],
						// [-979, -1612, 1, -0.189],
						// [-969, -1612, 1, -0.189],
						// [-959, -1612, 1, -0.189],
						// [-949, -1612, 1, -0.189]
					// 			[0,0, 1.0, -0.189],   // 16.13 3.08
					// [-10, 0, 1.0, -0.180],   // 19.67 3.58
					// [-20, 10, 1.0, -0.180],
					// [-30, 10, 1.0, -0.180],
					// [-40, 10, 1.0, -0.180]
				];

    	  break;
    	case 'trat_navi_04m':
			CAR_COUNT = 5;
			//    	    trackFile = "../data/Tracks/bal2_skoda_navigace/bal2_skoda_navigace.fhs.gz";
    	    trackFile = "../data/Tracks/trat_navi/trasa04.vrut";
    	    worldNodeName = "trasa";
    	    trackCFGFile = "../data/Tracks/trat_navi/trasa.xml";
   	trafficGraphFile = "../data/Tracks/trat_navi/trasa-traffic04.xml";
    	    updateParamValue("VehicleSimulator", "swapLanes", "1");
    	    updateParamValue("VehicleSimulator", "sceneUnits", "1000");
    	    updateParamValue("Navigation", "FOV", "75");
    	    updateParamValue("Navigation", "farPlane", "2000000");
    	    updateParamValue("Navigation", "nearPlane", "500");
			updateParamValue("RenderGl", "lighting", "0");
	     carPositions = [
		  [-989, -1612, 1, -0.189],
		 [-979, -1612, 1, -0.189],
		  [-969, -1612, 1, -0.189],
		 [-959, -1612, 1, -0.189],
		 [-949, -1612, 1, -0.189]
					// 			[0,0, 1.0, -0.189],   // 16.13 3.08
					// [-10, 0, 1.0, -0.180],   // 19.67 3.58
					// [-20, 10, 1.0, -0.180],
					// [-30, 10, 1.0, -0.180],
					// [-40, 10, 1.0, -0.180]
				];

    	  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";
			trafficGraphFile = "../data/Tracks/alpine-1/trafficGraph.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 = "../data/Tracks/krizovatka/krizovatka_TZV5_lidi2.fhs.gz";
			worldNodeName = "krizovatka_TZV5_lidi";
			trackCFGFile = "../data/Tracks/krizovatka/krizovatka_TZV5_lidi2.xml";
			trafficGraphFile = "../data/Tracks/krizovatka/trafficGraph.xml"
			updateParamValue("VehicleSimulator", "swapLanes", "0");
			updateParamValue("VehicleSimulator", "sceneUnits", "1000");
			updateParamValue("Navigation", "FOV", "75");
			updateParamValue("Navigation", "farPlane", "3000000");
			updateParamValue("Navigation", "nearPlane", "100");
			break;

		case 'krizovatka-simple':
			trackFile = "../data/Tracks/krizovatka-simple/krizovatka-simple.fhs";
			worldNodeName = "krizovatka-simple";
			trackCFGFile = "../data/Tracks/krizovatka-simple/krizovatka-simple.xml";
			trafficGraphFile = "../data/Tracks/krizovatka-simple/krizovatka-simple-traffic.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.083333333333");
	updateParamValue("VehicleSimulator", "odeTimeStep", "2");
//	updateParamValue("VehicleSimulator", "odeTimeStep", "-500");
	updateParamValue("VehicleSimulator", "odeIterations", "50");
	updateParamValue("VehicleSimulator", "sleepDuration", "0");
	//setting this value to at least 1 improves the simulation performance significantly
	updateParamValue("VehicleSimulator", "sceneUpdateDelay", "1");
	updateParamValue("VehicleSimulator", "eventsFPS", "1000");
	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);

	// load vehicle file	
	loadInto(vehicleFile, sceneID, scene.GetRootID(), 100000);
	var nodes = scene.GetNodes(vehicleFile);

	// get the node id of the root of the scene subgraph corresponding to the vehicle	
	for (var i = 0; i < CAR_COUNT; i++) 
		vehicleIDs[i] = -1;
		
	if (nodes != undefined) {
		if (nodes.length == 0) {
			LOGWARNING("Cannot find car node");
		}
		else {
			vehicleIDs[0] = nodes[nodes.length - 1].GetID();
		}
	}
	else {
		LOGWARNING("Cannot find car node");
	}

	if (CAR_COUNT > 1) {	
		// load AI cars(!)
//		var aiVehicleFile = "../data/Cars/FabiaAI/FabiaAI.fhs";	
//		var aiVehicleFile = "../data/Cars/Misc/Audi_Q7.vrut";	

		for (var i=0; i < templatePrefixes.length && i < (CAR_COUNT-1); i++)	{
			var aiVehicleFile = templatePrefixes[i]+".vrut";
			loadInto(aiVehicleFile, sceneID, scene.GetRootID(), 100000);
			var nodes = scene.GetNodes(aiVehicleFile);

			// get the node id of the root of the scene subgraph corresponding to the vehicle	
			if (nodes != undefined) {
				if (nodes.length == 0) {
					LOGWARNING("Cannot find car node");
				}
				else {
					templates[i] = nodes[nodes.length - 1].GetID();
					templateCounts[i] = 0;
//			        scene.SetActive(vehicleIDs[1], false);
				}
			}
			else {
				LOGWARNING("Cannot find car node");
			}
		}
	
		// copy the scene graph nodes for the first vehicle also to other vehicles
		for (var i = 1; i < CAR_COUNT; i++) {
			var template = (i-1)%templatePrefixes.length;
			if (vehicleIDs[i] == -1) {
				if (templateCounts[template] == 0)
					vehicleIDs[i] = templates[template];
				else
					vehicleIDs[i] = scene.Copy(sceneID, templates[template], scene.GetRootID());
				templateCounts[template]++;
			}
			vehicleConfigs[i] = templatePrefixes[template]+".xml";
			LOG("Car nodeID " + vehicleIDs[i]);
		}
	}

	carNodeID = vehicleIDs[0];
		
	updateParamValue("VehicleSimulator", "sceneID", sceneID);
	cameraID = renderScene(sceneID, 10000);
	command("usemodule rendergl"); // enforce rendegl module rendering
	
	bodyNodes = scene.GetNodes(vehicleBodyNodeName);
	if ((bodyNodes != undefined) && (bodyNodes.length != 0)) {
		scene.Move(cameraID, bodyNodes[0].GetID());
	}
	else {
		LOGWARNING("Cannot find car body node");
	}
		
	runModule("Traffic");

	// traffic module params
	updateParamValue("Traffic", "trafficGraphFile", trafficGraphFile);
	updateParamValue("Traffic", "worldFile", trackCFGFile);
	updateParamValue("Traffic", "sceneID", sceneID);
	updateParamValue("Traffic", "maxActiveCars", 10);
	updateParamValue("Traffic", "controlledVehicle", 0);
	//updateParamValue("Traffic", "wheelTurnDumpFactor", "0.50");
	//updateParamValue("Traffic", "throttleStep", "0.1");
	//updateParamValue("Traffic", "steeringPointTimeDistance", "0.10");
	//updateParamValue("Traffic", "navigationPointTimeDistance", "1.0");
	//updateParamValue("Traffic", "localSpaceForwardDistance", 100);
	//updateParamValue("Traffic", "localSpaceBackwardDistance", 50);
	updateParamValue("Traffic", "enableLocalSpace", "1");
	updateParamValue("Traffic", "displayGraph", "0");
	updateParamValue("Traffic", "useSplineInterpolation", "1");
	updateParamValue("Traffic", "trafficDensity", "2");

	var TRAFFIC_CAR_COUNT = CAR_COUNT-1;
		
	// assign starting positions
	//		CAR_COUNT
	for(var i = 0; i < CAR_COUNT; i++) {
		if (i == 0)
			updateParamValue("VehicleSimulator", "vehicleFile", vehicleCFGFile);
		else {
			//	updateParamValue("VehicleSimulator", "vehicleFile", "../data/Cars/FabiaAI/FabiaAI.xml");
			//	updateParamValue("VehicleSimulator", "vehicleFile", "../data/Cars/Misc/Audi_Q7.xml");
			//	updateParamValue("VehicleSimulator", "vehicleFile", "../data/Cars/Misc/Toyota_RAV4.xml");
			//	updateParamValue("VehicleSimulator", "vehicleFile", "../data/Cars/Octavia/Octavia.xml");
			updateParamValue("VehicleSimulator", "vehicleFile", vehicleConfigs[i]);
		}
				
		updateParamValue("VehicleSimulator", "addVehicle", "1");
		updateParamValue("VehicleSimulator", "vehicles", "3,"+i+"," + vehicleIDs[i]); // vehicleID
		updateParamValue("VehicleSimulator", "vehicles", "1,"+i+","+i); // the controllerID
		updateParamValue("VehicleSimulator", "vehicles", "2,"+i+",2"); // the cameraPosition value for first car is set to 2
		if (1) {
			updateParamValue("VehicleSimulator", "vehicles", "9,"+i+","+carPositions[i][0]+","+carPositions[i][1]+","+carPositions[i][2]); // starting car position
			updateParamValue("VehicleSimulator", "vehicles", "10,"+i+",0,0,"+carPositions[i][3]); // starting car orientation
		}
				
		updateParamValue("VehicleSimulator", "vehicleCameras", "0,0,0");
		updateParamValue("VehicleSimulator", "vehicleCameras", "1,0,0");
		if (i <= TRAFFIC_CAR_COUNT) {
			updateParamValue("Traffic", "addVehicle", "1");
			// update controller id for the traffic module
			updateParamValue("Traffic", "TrafficVehicles", "0," + i + "," + i); //the controllerID

			if (EXTERNALLY_DRIVEN_VEHICLE != -1) {
				if ((track == 'bal2_skoda_navigace') && (i == EXTERNALLY_DRIVEN_VEHICLE))
					updateParamValue("Traffic", "TrafficVehicles", "5,0" + i + ",0"); //drivenByTraffic
			}
		}
	}

	var willingness = [ 1.0, 1.2, 0.8, 1.0, 0.9, 1.1, 0.85, 1.05, 1.1, 0.95 ];
		
	// willingness setting for vehicles to overtake each other
	for (var i = 0; i <= TRAFFIC_CAR_COUNT; i++) {
		if(willingness.length > i)
			updateParamValue("Traffic", "TrafficVehicles", "1," + i + "," + willingness[i]);
		else
			updateParamValue("Traffic", "TrafficVehicles", "1," + i + "," + 0.85);
	}
		
	//load world configuration
	updateParamValue("VehicleSimulator", "worldFile", trackCFGFile);
	updateParamValue("VehicleSimulator", "worldID", worldNodeID);

	if (0) {	
		// Set the number of color samples (must be set after "FBO Multisampling Method" is set to "Multi sampling")
		sleep(1000);
		updateParamValue("rendergl3", "Color Samples Count", "16");
	}
		
	// //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);

	// wait until the vehicle poistions have been transformed
	// sleep(5000);
	updateParamValue("VehicleSimulator", "enabled", "1");
	
	//solve the F1-F6 keys here instead of inside VehicleSimulator
	function inputKeyCallback(evt) {

		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

				if ((track == 'bal2_skoda_navigace') && (EXTERNALLY_DRIVEN_VEHICLE != -1)) {
				    if (cdata.keyCode == 347) { //F8
				        updateParamValue("VehicleSimulator", "vehicles", "12," + EXTERNALLY_DRIVEN_VEHICLE + "," + EXTERNALLY_DRIVEN_VEHICLE_SPEED); // start waiting vehicle
						updateParamValue("VehicleSimulator", "vehicles", "4," + EXTERNALLY_DRIVEN_VEHICLE + ",Reset");    // reset waiting vehicle

						// instead of reset the following sequence could be used to make vehicle accelerate
				        //var dd = DeviceData(); // dd.type = DeviceData::DEVICE_3DoF;
						//dd.id = EXTERNALLY_DRIVEN_VEHICLE;
						//dd.buttons = 0;
						//dd.controls.length = 4;
						//dd.controls[0] = 0.0;  // wheelState*543.0
						//dd.controls[1] = 0.0;  // throttle
						//dd.controls[2] = 0.0;  // brakeState
						//dd.controls[3] = 10.0; // acceleration 	// ms^-2
						//Event.GET_EVT_INPUT_TRACKING(dd).PostToKernel();
					}
				}
			}
		}
	}
	REGISTER_LISTENER(Event.EVT_INPUT_KEY, new inputKeyCallback());

	SetupHud(sceneID, track);
		
	sleep(2000);
	// runModule("SoundRenderer");
	// run traffic simulation
	updateParamValue("Traffic", "enabled", "1");
	runModule("CarHW");
	// updateParamValue("CarHW", "HWtype", "3");
	updateParamValue("CarHW", "enabled", "1");
	
	// command("fullscreen 0 true");		
}


var tickInterval = 50;
var cameraHudID = -1;
function
SetupHud(sceneID, track)
{
	var scene = Scene.GetScene(sceneID);
		
	runModule("ArHud");
	updateParamValue("ArHud", "sceneID", sceneID);
	var resolutionX = 0;
	var resolutionY = 0;
	var aspectRatio = 1;
	var res = ClipHudResolutionCB.getValue();
	switch (res) {
		case '512x256':
			resolutionX = 512;
			resolutionY = 256;
			aspectRatio = 2;
			break;
		case '1024x512':
			resolutionX = 1024;
			resolutionY = 512;
			aspectRatio = 2;
			break;
		case '2048x1024':
			resolutionX = 2048;
			resolutionY = 1024;
			aspectRatio = 2;
			break;
		case '256x256':
			resolutionX = 256;
			resolutionY = 256;
			break;
		case '512x512':
			resolutionX = 512;
			resolutionY = 512;
			break;
		case '1024x1024':
			resolutionX = 1024;
			resolutionY = 1024;
			break;
	}
	updateParamValue("RenderGl", "hudSupport", true);
		
	if (resolutionX != 0) {
		//kamera pro HUD
		var hudRootID = -1;
		var nodes;
		for(var i = 0; (i < 100000) && (hudRootID == -1); i++) {
			nodes = scene.GetNodes("AR_HUD");
			if (nodes != undefined) 
				if (nodes.length > 0)
					hudRootID = nodes[0].GetID();
			sleep(100);	
		}
			
		updateInstParamValue("RenderGl", "renderingRootID", "predef", hudRootID);
//	    updateInstParamValue("Navigation", "FOV", "predef", "40");
		if (aspectRatio > 1)		
			updateInstParamValue("Navigation", "FOV", "predef", "30");
		else
			updateInstParamValue("Navigation", "FOV", "predef", "60");

		command("usemodule rendergl"); // enforce rendegl module rendering
		cameraHudID = renderScene(sceneID, 20000);
		scene.SetTransformation(cameraHudID, new Matrix(1, 0, 0, 0,
						 0, 1, 0, 0,
						 0, 0, 1, 0,
						 0, 0, 0, 1));
		scene.Move(cameraHudID, bodyNodes[0].GetID());
//	    scene.Move(cameraHudID, cameraID);
		scene.SetName(cameraHudID, "hudCamera");

		updateParamValue("ArHud", "clipHud", true);
		updateParamValue("ArHud", "clipHudAspectRatio", aspectRatio);
	
		Event.GET_EVT_RENDER_FULLSCREEN_SET(1, 1, 0, 0, resolutionX, resolutionY, 0).PostToKernel();
	}
	else {
//		updateParamValue("ArHud", "clipHud", false);
		updateParamValue("ArHud", "clipHud", true);
	}
//	RegisterTimer(new Tick(), tickInterval);
//	updateParamValue("ArHud", "showMirror", false);
	updateParamValue("ArHud", "showMirror", true);
	if (track=='dalnice')	
		updateParamValue("ArHud", "leftLaneShift", "0.73");
	if (track=='dalnice_new')	
		updateParamValue("ArHud", "leftLaneShift", "0.15");
}




function Tick() {
	this.perform = function () {
//		LOG("Tick " + tickInterval);		
		Event.GET_EVT_RENDER_IMAGE(sceneID, cameraHudID, -1, -1, "../data/Cars/arhud-glass.png", false, true).PostToKernel();
		return tickInterval;
	}
}


//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", "dalnice_new", ["bal2_new", "bal2_skoda_navigace", "dalnice", "dalnice_new", "trat_navi_f10", "trat_navi_f15", "trat_navi_1m", "trat_navi_04m", "Real_trat",  "simple", "alpine-1", "krizovatka_TZV5_lidi", "krizovatka-simple", "Ehra"], "Environment used for the simulation");
//var environmentCB = new actionOnComboBox(paramComboBoxID, "bal2_skoda_navigace");
var environmentCB = new actionOnComboBox(paramComboBoxID, "dalnice_new");
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", "Toyota RAV4", "Audi Q7", "Saab 93"], "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));



var ClipHudResolutionComboBoxID = REGISTER_PARAM_GUI_COMBOBOX("ClipHudResolution", "NONE", ["NONE", "256x256", "512x512", "1024x1024", "512x256", "1024x512", "2048x1024"], "Resolution of the window used to render clip hud");
//var environmentCB = new actionOnComboBox(paramComboBoxID, "bal2_skoda_navigace");
var ClipHudResolutionCB = new actionOnComboBox(ClipHudResolutionComboBoxID, "NONE");
REGISTER_LISTENER(Event.EVT_PARAM_SET, ClipHudResolutionCB);


//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());
*/
