//console.log("load gaugesScreen");
angular.module('gaugesScreen', [])

  .controller('GaugesScreenController', function ($scope, $element, $window) {
    "use strict";
    var vm = this;

    var svg;

    var speedoDisplay = { };
    var tacho = {  };
    var infoDisplay = {};
    var electrics = {lights:{} };
    var gagues = {};

    var currentGear = '';
    var refreshAng = 0.25*Math.PI/180;

    var ready = false;

    var units = {uiUnitConsumptionRate: "metric",
    uiUnitDate: "ger",
    uiUnitEnergy: "metric",
    uiUnitLength: "metric",
    uiUnitPower: "hp",
    uiUnitPressure: "bar",
    uiUnitTemperature: "c",
    uiUnitTorque: "metric",
    uiUnitVolume: "l",
    uiUnitWeight: "kg"};
    var unitspeedConv = 2.23694;

    function getNodesArray(prefix,start, number, root){
      let arr= [];
      for(let i=start;i<number;i++){
        let node = hu(prefix+i, root)
        if(!node)
          console.error(prefix+i,"node not found")
        else
          arr.push(node)
      }
      return arr;
    }

    function getRndInteger(min, max) {
      return Math.floor(Math.random() * (max - min) ) + min;
    }

    // Make sure SVG is loaded
    $scope.onSVGLoaded = function () {
      svg = $element[0].children[0].children[0];

      // speedometer
      speedoDisplay.speedValue = hu('#speed_val', svg);
      speedoDisplay.speedUnit = hu('#text1212-89-4-3', svg);
      speedoDisplay.gears = hu('#gear_txt', svg);
      speedoDisplay.range = hu('#range_txt', svg);

      tacho.markers_root = hu('#layer_rpm_bar', svg);
      tacho.markers = getNodesArray("#rpm",1, 52,tacho.markers_root)

      electrics.lights_root = hu("#layer8", svg);
      electrics.lights.signal_L = hu("#signal_L", electrics.lights_root);
      electrics.lights.signal_R = hu("#signal_R", electrics.lights_root);
      electrics.lights.highbeam = hu("#highbeam", electrics.lights_root);
      electrics.lights.parkingbrake = hu("#parkingbrake", electrics.lights_root);
      electrics.lights.checkengine = hu("#checkengine", electrics.lights_root);
      electrics.lights_battery = hu("#battery", electrics.lights_root);
      electrics.odo_txt = hu("#odo_txt", svg);
      electrics.diff_F = hu("#diff_F", svg);
      electrics.diff_R = hu("#diff_R", svg);
      electrics.wheel_RR = hu("#wheel_RR", svg);
      electrics.wheel_RL = hu("#wheel_RL", svg);
      electrics.wheel_FL = hu("#wheel_FL", svg);
      electrics.wheel_FR = hu("#wheel_FR", svg);


      gagues.fuel = getNodesArray("#fuel",0,8,svg)
      gagues.water = getNodesArray("#temp",0,8,svg)
      gagues.time_h = hu("#clock-hour",svg)
      gagues.time_m = hu("#clock-min",svg)

      ready = true;
    }

    function updateGearIndicator(data) {
      // only update when gear is changed
      if (currentGear !== data.electrics.gear) {
        currentGear = data.electrics.gear;
        if(isNaN(data.electrics.gear)){//auto,DCT
            speedoDisplay.gears.text(data.electrics.gear);
        }else{//manuel
          switch(data.electrics.gear){
            case -1:
              speedoDisplay.gears.text("R");
              break;
            case 0:
              speedoDisplay.gears.text("N");
              break;
            default:
              speedoDisplay.gears.text(data.electrics.gear);
              break;
          }
        }
      }
    }

    function limitVal(min, val,max){
      return Math.min(Math.max(min,val), max);
    }
    function map_range(value, low1, high1, low2, high2) {
      return low2 + (high2 - low2) * (value - low1) / (high1 - low1);
    }
    const clamp = (num, min, max) => Math.min(Math.max(num, min), max);
    const clamp_remap = (val, min,max) => map_range(clamp(val,min,max), min,max,0,1);

    function updateTachoDisplays(data) {
      if (ready) {
        for(let i=0;i<tacho.markers.length;i++){
          tacho.markers[i].css({display: ((data["electrics"]["rpmTacho"]> i*177)?"inline":"none")})
        }
      }
    }

    function updateSpeedDisplays(data) {
      if (ready) {
        speedoDisplay.speedValue.text(Math.min(data.electrics.wheelspeed*unitspeedConv,199).toFixed(0))
      }
    }

    function updateGagues(data) {
      if (ready) {
        let remaped = clamp_remap(data.electrics.watertemp,60,120)
        for(let i=0;i<gagues.water.length;i++){
          let threadshold = (i+0.5)/gagues.water.length
          gagues.water[i].css({"display": (remaped>threadshold)?"inline":"none"})
        }

        for(let i=0;i<gagues.fuel.length;i++){
          let threadshold = (i+0.5)/gagues.fuel.length
          gagues.fuel[i].css({"display": (data.electrics.fuel>threadshold)?"inline":"none"})
        }
      }
    }

    // overwriting plain javascript function so we can access from within the controller
    $window.setup = (data) => {
      if(!ready){
        console.log("calling setup while svg not fully loaded");
        setTimeout(function(){ $window.setup(data) }, 100);
        return;
      }

      //console.log("setup",data);
      for(let dk in data){
        if(typeof dk == "string" && dk.startsWith("uiUnit")){
          units[dk] = data[dk];
        }
      }
      vueEventBus.emit('SettingsChanged', {values:units})

      console.log(units.uiUnitLength);
      if(units.uiUnitLength == "metric"){
        speedoDisplay.speedUnit.text("KMH");
        unitspeedConv = 3.6;
      }
    }

    function setElec(node, state, key){
      if( node === undefined || node === null){console.error("setElec: svg element not found", key); return;}
      if( state === undefined || state === null){console.error("setElec: state not found", key);node.n.style.display = "none"; return;}
      node.n.style.filter = (state===true || state>0.1)?"":"url(#off)";
      //node.n.setAttribute("opacity", (state || state>0.1)?1.0:0.3)
    }

    $window.updateElectrics = (data) => {
      for(var k in electrics.lights){
        setElec(electrics.lights[k], data.electrics[k], k);
      }

      electrics.lights_battery.n.style.filter = (data.electrics.engineRunning<0.1)?"":"url(#off)";

      if(data.electrics.odometer){
        let val = data.electrics.odometer
        val *= (units.uiUnitLength=="metric")?0.001:0.0006215;
        val = Math.min(999999,val);
        electrics.odo_txt.text( val.toFixed(0) )
      }
      if(data.electrics["front_lock"] !== undefined){
        electrics.diff_F.n.style.display = (data.electrics.front_lock===true || data.electrics.front_lock>0.1)?"block":"none";
      }
      if(data.electrics["rear_lock"] !== undefined){
        electrics.diff_R.n.style.display = (data.electrics.rear_lock===true || data.electrics.rear_lock>0.1)?"block":"none";
      }
      if(data.electrics["transfercase_lock"] !== undefined){
        electrics.wheel_FL.n.style.display = (data.electrics.transfercase_lock===true || data.electrics.transfercase_lock>0.1)?"block":"none";
        electrics.wheel_FR.n.style.display = (data.electrics.transfercase_lock===true || data.electrics.transfercase_lock>0.1)?"block":"none";
      }
      if(data.electrics["rangebox_state"] !== undefined){
        speedoDisplay.range.text( (data.electrics.rangebox_state>0.1)?"L":"H" );
      }
    }

    $window.updateMode = (data) => {}

    $window.updateData = (data) => {
      if (data) {
        if(!ready){console.log("not ready");return;}
         //console.log(data);

        // Update PRNDS display
        updateGearIndicator(data);
        // Update Speed displays
        updateSpeedDisplays(data);
        updateTachoDisplays(data);

        updateElectrics(data);
        updateGagues(data);

        gagues.time_h.text(data.customModules.environmentData.time.split(":")[0])
        gagues.time_m.text(data.customModules.environmentData.time.split(":")[1])
      }
    }

    function getRndFloat(min, max) {
      return Math.random() * (max - min) + min;
    }


    function demo(){
      updateData({electrics: {lowfuel: Math.random()>0.5, fuel: Math.random(), watertemp: getRndInteger(40,130), rpmTacho: getRndInteger(0,10000),oiltemp:getRndInteger(40,130), turboBoost:getRndFloat(0,5), engineRunning:Math.random()*0.2, odometer:Math.random()*50000000,
        signal_L:Math.random(), signal_R:Math.random(), lights:Math.random()*2, highbeam:Math.random(), lowpressure:Math.random(), parkingbrake:Math.random(), checkengine:Math.random(), gear:getRndInteger(-1,6), wheelspeed: getRndInteger(0,400)/3.6,
        front_lock:Math.random()*0.2, rear_lock:Math.random()*0.2, transfercase_lock:Math.random()*0.2 },
        customModules: {
          accelerationData: {xSmooth:getRndFloat(-20,20) ,ySmooth:getRndFloat(-20,20)},
          environmentData:{time:"dE:Mo", temperatureEnv:Math.random()*100-50},
          // combustionEngineData:{fuelDisplay:Math.random()*50,averageFuelConsumption:Math.random()*50,currentFuelConsumption:Math.random()*50,remainingRange:Math.random()*200}
        }});

      setTimeout(demo, 2000);
    }
    if(typeof beamng == 'undefined' || typeof beamng.sendActiveObjectLua == 'undefined') { //mode demo only in external browser
      console.log("Demo mode")
      setTimeout(()=>{
        demo()
      }, 500);
    }
    //ready = true;
  });
