//includy definic funkci
include("paramevent.js");
include("loadscene.js");
include("runmodule.js");
include("visibility.js");
include("collisioncallback.js");
include("counters.js");
include("anim.js");
include("inputcallback.js");

var flystick = 1; //bodyID flysticku
var seatBody = 12; //bodyID sedadla
var glassesBody = 4; //bodyID bryli
var rightHandBody = 5; //bodyID prave ruky
var carHW = 20; //bodyID carHW

var sceneDir = "C:/data/cave/";

//nacteme synchronne korenovou assembly
var sceneID = loadScene(sceneDir + "BaseCAVEAssembly1.fhs", 5000);

//ziskame referenci na pracovni scenu
var scene = Scene.GetScene(sceneID);

//spustime rendering
updateParamValue("RenderGl", "antiAliasingMethod", "Multi sampling");
updateParamValue("RenderGl", "antiAliasingColorSampleCount", "16");
updateParamValue("RenderGl", "alphaToCoverage", "1");
updateParamValue("RenderGl", "sortGeometries", "1");
//nastavime near a far
updateParamValue("Navigation", "nearPlane", "100");
updateParamValue("Navigation", "farPlane", "10000000");
var cameraID = renderScene(sceneID, 5000);

//ziskame ID uzlu, pod ktery budeme navesovat vse ostatni
var EnvironmentsID = getFirstNameNodeID(scene, "Environments");
var CarsID = getFirstNameNodeID(scene, "Cars");
var SwitchPositionsID = getFirstNameNodeID(scene, "SwitchPositions");
var SeatTrackingID = getFirstNameNodeID(scene, "SeatTracking");

//posuneme kameru do nuly, spravnou pozici zajisti tracking
scene.TranslateAbs(cameraID, new Vector3(0, 0, 0));
scene.Move(cameraID, SeatTrackingID);

//spustime import
loadIntoAsync(sceneDir + "sk316_showcar/sk316_Geneva2009_Marketing_090211/sk316_Geneva2009_Marketing_090211_11.fhs", sceneID, CarsID);
loadIntoAsync(sceneDir + "prostredi/krizovatka_TZV5_lidi/krizovatka_TZV5_lidi.vrut", sceneID, EnvironmentsID);
loadIntoAsync(sceneDir + "prostredi/hory/hory.fhs.gz", sceneID, EnvironmentsID);
loadIntoAsync(sceneDir + "prostredi/poust/poust.fhs.gz", sceneID, EnvironmentsID);

//nacteme do sceny ruku, tentokrat ale pod kameru (to bude nas letajici koberec)
loadIntoAsync(sceneDir + "R_Hand.fhs", sceneID, cameraID);

//nyni udelame vse co muzeme bez nactene geometrie
//zviditelnime auto
scene.SetSwitchActiveChild(CarsID, 0);
//zviditelnime první prostředí
scene.SetSwitchActiveChild(EnvironmentsID, 0);

//spustime dalsi potrebne moduly
runModule("TrackingManipulator");
runModule("collision_detection");
runModule("tracking");
runModule("carHW");
if (computerName() == "SKDATVWG1248") {
    //use spacemouse
    runModule("C3Dconnexion");
    flystick = 0;
    updateParamValue("CarHW", "HWtype", "3");
}
else {
    updateParamValue("CarHW", "HWtype", "1");
    updateParamValue("CarHW", "comPortWheelBaudRate", "115200");
}
updateParamValue("CarHW", "deviceID", "20");
updateParamValue("CarHW", "enabled", "1");

//nastavime kamere bodyID pro tracking
updateParamValue("Cluster", "carpetsTable", "4,0," + glassesBody);
//nastavime kameru jako trackovanou
updateParamValue("Cluster", "carpetsTable", "3,0,1");

//nastavime antialiasing
updateParamValue("Cluster", "clientCommand", "setparam RenderGl.antiAliasingMethod \"Multi sampling\"");

//nastavení IDoffsets
updateParamValue("Tracking", "IDoffsets", "0,0,2,4,14,15");

//filtrovani sedacky
SetTableRow("Tracking", "filterTable", 0, [seatBody, 3, 10]);

//svazani sestavy s kreslem
SetTableRow("TrackingManipulator", "mappingTable", 0, [sceneID, SeatTrackingID, seatBody, 15]);

//pockame na nacteni scen krome auta (auto je nejvetsi tak by melo byt posledni)
waitUntilLoaded(4, 100000);

//opet udelame co muzeme
//ulozime si ID nekterych uzlu pro ucely animace
var nodeHand = getFirstNameNodeID(scene, "root_of_hand");
var nodeHandBody = getFirstNameNodeID(scene, "Handruecken");
var nodeHandFinger = getFirstNameNodeID(scene, "Zeigefinger3");

//svazani prave ruky s rukou
if (computerName() == "SKDATVWG1248") {
    //use spacemouse
    SetTableRow("TrackingManipulator", "mappingTable", 1, [sceneID, nodeHand, 0, 13, undefined, cameraID]);
}
else {
    SetTableRow("TrackingManipulator", "mappingTable", 1, [sceneID, nodeHand, rightHandBody, 1]);
}

//najdeme uzly ovladani osvetleni den/noc
var nodeKrizovatkaLighting = getFirstNameNodeID(scene, "krizovatka_TZV5_lidi_lighting");
var nodeHoryLighting = getFirstNameNodeID(scene, "hory_lighting");
var nodePoustLighting = getFirstNameNodeID(scene, "poust_lighting");

//pockame na nacteni scen
waitUntilLoaded(1, 100000);
LOG("All scenes loaded");

var nodeDoor = getFirstNameNodeID(scene, "DV_P_L_anim");
var nodeDoorCol = getFirstNameNodeID(scene, "DV_P_L_anim_col1");
var nodeLeftShade = getFirstNameNodeID(scene, "clona_leva_pohyb");
var nodeLeftShadeCol = getFirstNameNodeID(scene, "clona_leva_pohyb_col");
var nodeHiddenGeometry = getFirstNameNodeID(scene, "hidden_geometry");
var nodeKastlik = getFirstNameNodeID(scene, "kapsa_pristrdesky_rotace");
var nodeKastlikCol = getFirstNameNodeID(scene, "kapsa_pristrdesky_rotace_tlac");

//schovame nedulezite casti auta
hideNode(sceneID, nodeHiddenGeometry);


updateParamValue("Collision_detection", "sceneID", sceneID);

//register door for collisions with hand
SetTableRow("Collision_detection", "Pairs", 0, [nodeHand, nodeDoorCol, 2, undefined, 1]);
SetTableRow("Collision_detection", "Pairs", 1, [nodeHand, nodeLeftShadeCol, 2, undefined, 1]);
SetTableRow("Collision_detection", "Pairs", 2, [nodeHand, nodeKastlikCol, 2, undefined, 1]);

//activate collisions
updateParamValue("Collision_detection", "Enabled", "1");

var lighting = 0;
//tvorba a registrace callbacku prepinace volantu
volant = new Array(-1, getFirstNameNodeID(scene, "SK316_volant"));
volantCtr = new NodesSwitch(0, scene, volant);


function inputTrackingCallback() {
    environmentCtr = new HandleSwitchNode(scene, EnvironmentsID, 0);
    mirror = new Array(getFirstNameNodeID(scene, "zrcatko_off"), getFirstNameNodeID(scene, "zrcatko_on"));
    mirrorCtr = new NodesSwitch(0, scene, mirror);
    handCtr = new NodesSwitch(0, scene, new Array(-1, nodeHand));
    //sedackyCtr = new HandleSwitchNode(scene, getFirstNameNodeID(scene, "sk371_SedackyPredni"), 1);

    //setup center mirror rotation
    mirrorRotAxes = new Array(new Vector3(0, 21.6, 0), new Vector3(-7, 0, -20));
    mirrorRotctr = new SwitchRotations(getFirstNameNodeID(scene, "zrcatko_pohyb"), scene, new Vector3(838.2, 0, 1073), mirrorRotAxes, new Array(30, 20), new Array(-1, -13));

    //set the camera positions switch
    vectors = new Array();
    vectors[0] = new Vector3(496, -350, -1);
    vectors[1] = new Vector3(496, 350, -1);
    vectors[2] = new Vector3(1315, 380, 20);
    vectors[3] = new Vector3(1315, -380, 20);
    /*vectors[0] = new Vector3(-268.5, 201.3, -137.5);//stara kalibrace
    vectors[1] = new Vector3(-268.5, -498.7, -137.5);
    vectors[2] = new Vector3(-1087.5, -528.7, -158.5);
    vectors[3] = new Vector3(-1087.5, 231.3, -158.5);*/
    switchPositionsCtr = new TranslateSwitch(0, scene, vectors, SwitchPositionsID);

    /*this.ShowSeats = function (value) {
        if (value == 0) {
            sedackyCtr.set(1);
            volantCtr.set(0);
        }
        else if (value == 1) {
            sedackyCtr.set(0);
            volantCtr.set(1);
        }
        else {
            sedackyCtr.set(-2);
            volantCtr.set(1);
        }
    }*/

    this.perform = function (evt) {
        var cdata = evt.deviceData;
        if (cdata.id == flystick) {
            if (cdata.buttons & (1 << 0))
                mirrorCtr.inc();//switch on/off mirror
            if (cdata.buttons & (1 << 1)) {
                switchPositionsCtr.inc();//switch position 1
                //this.ShowSeats(switchPositionsCtr.value);
            }
            if (cdata.buttons & (1 << 2))
                environmentCtr.inc();//switch environment
            if (cdata.buttons & (1 << 3)) {
                switchPositionsCtr.dec();//switch position 3
                //this.ShowSeats(switchPositionsCtr.value);
            }
            /*//SpaceMouse mirror rotations
            if (cdata.buttons & (1 << 4))
                mirrorRotctr.update(0, -0.12);//rotate mirror
            if (cdata.buttons & (1 << 5))
                mirrorRotctr.update(1, -0.5);//rotate mirror
            if (cdata.buttons & (1 << 6))
                mirrorRotctr.update(0, 0.12);//rotate mirror
            if (cdata.buttons & (1 << 7))
                mirrorRotctr.update(1, 0.5);//rotate mirror*/
            //flystick mirror rotations
            if (cdata.controls.length >= 2) {
                if (cdata.controls[0] != 0)
                    mirrorRotctr.update(1, cdata.controls[0] * 0.5);
                if (cdata.controls[1] != 0)
                    mirrorRotctr.update(0, cdata.controls[1] * 0.25);
            }
        }
        if (cdata.id == carHW) {
            if (cdata.buttons == 73)
                mirrorCtr.inc();//switch on/off mirror
            if (cdata.buttons == 129) {
                switchPositionsCtr.inc();//switch position 1
                this.ShowSeats(switchPositionsCtr.value);
            }
            if (cdata.buttons == 81)
                environmentCtr.inc();//switch environment
            if (cdata.buttons == 137) {
                switchPositionsCtr.dec();//switch position 3
                this.ShowSeats(switchPositionsCtr.value);
            }
            //mirror rotations
            if (cdata.buttons == 68)
                mirrorRotctr.update(0, -0.12);//rotate mirror
            if (cdata.buttons == 92)
                mirrorRotctr.update(1, -0.5);//rotate mirror
            if (cdata.buttons == 64)
                mirrorRotctr.update(0, 0.12);//rotate mirror
            if (cdata.buttons == 88)
                mirrorRotctr.update(1, 0.5);//rotate mirror
            if (cdata.buttons == 105)
                handCtr.inc();//zapinani ruky
        }
    };
}
REGISTER_LISTENER(Event.EVT_INPUT_TRACKING, new inputTrackingCallback());

function inputKeyCallback() {
    //zapinani/vypinani trackovani sedacky
    sedackaTracking = 1;
    updateParamValue("TrackingManipulator", "mappingTable", "6,0," + sedackaTracking);
    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 == 76) {
                lighting = 1 - lighting;
                scene.SetSwitchActiveChild(nodeKrizovatkaLighting, lighting);
                scene.SetSwitchActiveChild(nodeHoryLighting, lighting);
                scene.SetSwitchActiveChild(nodePoustLighting, lighting);
                //updateParamValue("RenderGl", "headlight", 1 - lighting);
            }
            if (cdata.keyCode == 83) {//s
                if (sedackaTracking == 1)
                    sedackaTracking = -1;
                else
                    sedackaTracking = 1;
                updateParamValue("TrackingManipulator", "mappingTable", "6,0," + sedackaTracking);
            }
            if (cdata.keyCode == 87) {
                volantCtr.dec();//show hide steering wheel
            }
        }
    }
}
REGISTER_LISTENER(Event.EVT_INPUT_KEY, new inputKeyCallback());

function sceneCollisionCallback() {
    //tvorba a registrace callbacku pro interakci ruky s dvermi
    var rot = new colAxisRot(scene, nodeHand, nodeDoorCol, nodeDoor, new Vector3(432.3, -823.1, 555.5), new Vector3(-14.5, 10.8, 311.6), 0, 70);

    //tvorba a registrace callbacku pro interakci ruky s levou clonou
    var rotShade = new colAxisRot(scene, nodeHand, nodeLeftShadeCol, nodeLeftShade, new Vector3(942.1, -391.7, 1144.9), new Vector3(40.5, -216.5, -1.1), 0, 150);

    //tvorba a registrace sestavy callbacku pro animaci kastliku
    kastlikAnim = new reversibleRotateAnim(nodeKastlik, new Vector3(367.29998, -60, 762.29998), new Vector3(0, 120, 0), 0, 40, 2, 50, scene);
    kastlikTrig = new colTrigger(sceneID, nodeHand, nodeHandFinger, nodeKastlikCol, -1, kastlikAnim);
    RegisterTimer(kastlikAnim, 1000);

    this.perform = function (evt) {
        rot.perform(evt);
        rotShade.perform(evt);
        kastlikTrig.perform(evt);
    }
}
REGISTER_LISTENER(Event.EVT_SCENE_COLLISION, new sceneCollisionCallback());

//zapneme filtrovani trackingu
//updateParamValue("Tracking", "filterTable", "3,0,1");

//run scenegraph for testing
runModule("SceneGraph");
updateParamValue("SceneGraph", "sceneID", sceneID);
