//includy definic funkci
var _DIR = "B:/dip/vrut/trunk/bin/";
//var _DIR = "C:/data/Tonda/vrut/trunk/bin/";

include(_DIR+"paramevent.js");
include(_DIR+"loadscene.js");
include(_DIR+"runmodule.js");
include(_DIR+"visibility.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;

  	vehicleFile = _DIR+"../data/Cars/FabiaRS/FabiaRS.fhs";
  	vehicleCFGFile = _DIR+"../data/Cars/FabiaRS/FabiaRS.xml";
  	vehicleBodyNodeName = "body";


    trackFile = _DIR+"../data/Tracks/krizovatka/krizovatka_TZV5_lidi2.fhs";
    worldNodeName = "krizovatka_TZV5_lidi";
    trackCFGFile = _DIR+"../data/Tracks/krizovatka/krizovatka_TZV5_lidi2.xml";
    trafficGraphFile = _DIR+"../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");


  	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", "1");
  	updateParamValue("VehicleSimulator", "eventsFPS", "1000");
  	updateParamValue("VehicleSimulator", "vehicleFile", vehicleCFGFile);
    updateParamValue("VehicleSimulator", "recFile", _DIR+"../data/Cars/testrec.txt");
    runModule("VehicleSimulator");

    runModule("Traffic");


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

    var CAR_COUNT = 30;
    var vehicleIDs = [];
    loadInto(vehicleFile, sceneID, scene.GetRootID(), 100000);
    var nodes = scene.GetNodes(vehicleFile);
    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");
    }
    for (var i = 1; i < CAR_COUNT; i++) {
        vehicleIDs[i] = scene.Copy(sceneID, vehicleIDs[0], scene.GetRootID());
        LOG("Car nodeID " + vehicleIDs[i]);
    }


    updateParamValue("VehicleSimulator", "sceneID", sceneID);


    updateParamValue("Traffic", "WHEEL_TURN_STEP", "0.1");
    updateParamValue("Traffic", "THROTTLE_STEP", "0.1");
    updateParamValue("Traffic", "WAYPOINT_DISTANCE_THRESHOLD", "3");
    updateParamValue("Traffic", "WAYPOINT_ANGLE_THRESHOLD", "0.8");
    updateParamValue("Traffic", "CAR_WIDTH", "2");
    updateParamValue("Traffic", "CAR_SIGHT", "20");
    updateParamValue("Traffic", "CAR_BREAK_SIGHT", "10");
    updateParamValue("Traffic", "CAR_ANGLE_AWARENESS", "15");
    updateParamValue("Traffic", "OVERTAKING_DISTANCE", "3.5");
    updateParamValue("Traffic", "trafficGraphFile", trafficGraphFile);
    updateParamValue("Traffic", "worldFile", trackCFGFile);
    updateParamValue("Traffic", "sceneID", sceneID);
    updateParamValue("Traffic", "maxActiveCars", 10);
    updateParamValue("Traffic", "controlledVehicle", 0);
    updateParamValue("Traffic", "spawnDistance", 10000);
    updateParamValue("Traffic", "localSpaceInnerRadius", 10000);
    updateParamValue("Traffic", "localSpaceOuterRadius", 200000);
    updateParamValue("Traffic", "displayGraph", "0");

    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");
  	//updateParamValue("RenderGl", "lighting", "0");
  	//updateParamValue("RenderGl", "backFaceCull", "1");
  	updateParamValue("RenderGl", "sortGeometries", "1");
  //	updateParamValue("RenderGl", "useVBO", "1");
  	updateParamValue("RenderGl", "antiAliasingMethod", "Multi sampling");
  //	updateParamValue("RenderGl", "antiAliasingMethod", "Coverage sampling");
  	updateParamValue("RenderGl", "antiAliasingColorSampleCount", "8");
  	updateParamValue("RenderGl", "antiAliasingCoverageSampleCount", "8");
  	updateParamValue("RenderGl", "alphaToCoverage", "1");



    for(var i = 0; i < CAR_COUNT; i++) {
    	updateParamValue("VehicleSimulator", "addVehicle", "1");
        updateParamValue("Traffic", "addVehicle", "1");
    	updateParamValue("VehicleSimulator", "vehicles", "3,"+i+"," + vehicleIDs[i]); // vehicleID
    	updateParamValue("VehicleSimulator", "vehicles", "1,"+i+","+i); //the controllerID
        updateParamValue("Traffic", "TrafficVehicles", "0,"+i+","+ i); //the controllerID
        updateParamValue("VehicleSimulator", "vehicles", "9,"+i+","+10*i+","+0+","+(-10)); // starting car position
        updateParamValue("VehicleSimulator", "vehicles", "10,"+i+",0,0,0"); // starting car orientation
    }
    updateParamValue("VehicleSimulator", "vehicles", "9,"+0+","+0+","+0+","+1); // starting car position
    // set path to vehicle 0
    updateParamValue("VehicleSimulator", "vehicleCameras", "0,0,0");
    updateParamValue("VehicleSimulator", "vehicles", "2,0,2"); //the cameraPosition value for first car is set to 2


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

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

	    this.perform = function (evt) {
	        var cdata = evt.clientData;
	        //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,1");//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());
}

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

    this.perform = function (evt) {
        if (evt.clientData.substr(0, this.paramID.length) == this.paramID) {
            this.val = evt.clientData.substr(this.paramID.length + 1);
        }
    }

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


var paramComboBoxID = REGISTER_PARAM_GUI_COMBOBOX("environment", "krizovatka_TZV5_lidi", ["bal2_skoda_navigace", "Real_trat", "simple", "alpine-1", "krizovatka_TZV5_lidi", "Ehra"], "Environment used for the simulation");
var environmentCB = new actionOnComboBox(paramComboBoxID, "krizovatka_TZV5_lidi");
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.clientData.substr(0, this.paramID.length) == 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());