var filtersConfig = {
  // instruct TableFilter location to import ressources from
  base_path: 'https://unpkg.com/tablefilter@0.6.102/dist/tablefilter/',
  highlight_keywords: true,
  alternate_rows: true,
  rows_counter: true,
  btn_reset: true,
  status_bar: true,
  popup_filters: true,
  enable_empty_option: true,
  enable_non_empty_option: true,
  auto_filter: {
    delay: 1100 //milliseconds
  },
  cell_parser: {
    cols: [2],
    parse: function (o, cell, colIndex) {
      if (colIndex === 2) {
        let value = cell.innerHTML.split(" ");
        if (value.length > 1) {
          let unity = value[1];
          value = parseInt(value[0]);

          if (unity == "m")
            return value;

          if (unity == "h")
            if (value > 0)
              return value * 60;
            else
              return 1 * 60;

          if (unity == "d")
            if (value > 0)
              return value * 60 * 24;
            else
              return 60 * 24;
        }
        return 9999;
      }
    }
  },
  // theme
  themes: [{name: 'default'}],
  extensions: [{name: 'sort'}]
};

function updateAllDevices() {
  $(".loading-image").css("visibility", "visible");
  $.ajax({
    url: URL_SERVER_TRACKING + "/api/devices",
    data: {},
    dataType: 'json',
    xhrFields: {
      withCredentials: true
    },
    success: function (data) {
      $(".loading-image").css("visibility", "hidden");
      for (let key in data) {
        let device = data[key];
        updateDevice(device);
      }
    }
  });
}

function updateAllPositions(ignoreInterval) {
  $(".loading-image").css("visibility", "visible");
  $.ajax({
    url: URL_SERVER_TRACKING + "/api/positions",
    data: {},
    dataType: 'json',
    xhrFields: {
      withCredentials: true
    },
    success: function (data) {
      $(".loading-image").css("visibility", "hidden");
      let markers = [];
      for (let key in data) {
        let position = data[key];
        let attributes = position.attributes;
        global_positions[position.deviceId] = position;
        let elm = $("#device_id_" + position.deviceId).find(".last_update");
        //elm.html(getElapsedTime(new Date(position.fixTime)));


        let course = position.course - 45;
        $("#device_id_" + position.deviceId).find(".img-vehicle-direction").attr("style", "width: 24px;height:24px;transform: rotate(" + course + "deg);-ms-transform: rotate(" + course + "deg);-moz-transform: rotate(" + course + "deg);-webkit-transform: rotate(" + course + "deg);-o-transform: rotate(" + course + "deg);");
        $("#device_id_" + position.deviceId).find(".name_vehicle_event > a").attr("onclick", "goToMap([" + position.longitude + ", " + position.latitude + "]);");
        let temperature = (attributes.temp1 != null) ? " - " + attributes.temp1.toFixed(2) + "°" : '';
        $("#device_id_" + position.deviceId).find(".name_vehicle_event .temperature").html(temperature);

        let marker_url = elm.parent().attr("data-marker");
        let marker = new ol.Feature({
          geometry: new ol.geom.Point(
            ol.proj.fromLonLat([position.longitude, position.latitude])
          ),
        });

        marker.setStyle(new ol.style.Style({
          image: new ol.style.Icon(({
            crossOrigin: 'anonymous',
            //color: 'red',
            src: '/assets/' + 'images/' + getMarkerByDeviceId(position.deviceId)
          })),
          text: new ol.style.Text({
            text: global_vehicles_by_device_id[position.deviceId].replace(/-.*/, "") + temperature,
            overflow: true,
            fill: new ol.style.Fill({
              color: Traccar.Style.mapGeofenceTextColor
            }),
            stroke: new ol.style.Stroke({
              color: Traccar.Style.mapTextStrokeColor,
              width: Traccar.Style.mapTextStrokeWidth
            }),
            font: Traccar.Style.mapTextFont
          })

        }));
        removeMarker(position.deviceId);
        marker.device_id = position.deviceId;
        markerVectorLayer.getSource().addFeature(marker);
      }


      updateAllDevices();
      if (!ignoreInterval) {
      }
      setInterval("updateAllDevices()", 1000 * 60);

    }
  });
}

function getMarkerByDeviceId(id) {
  for (let i in global_vehicles) {
    if (global_vehicles[i].tc_device_id == id)
      return global_vehicles[i].marker_url
  }
  return "poi2.png";
}

function getFeatureMarker(device_id) {
  let features = markerVectorLayer.getSource().getFeatures();
  for (let i in features) {
    let feature = features[i];
    if (feature.device_id == device_id)
      return feature;
  }
  return null;
}

function removeMarker(device_id) {
  let feature = getFeatureMarker(device_id);
  if (feature)
    markerVectorLayer.getSource().removeFeature(feature);
}

function getColorMarker(device_id) {
  let feature = getFeatureMarker(device_id);
  if (feature)
    return feature.color;
  else
    return "";
}
var zoomToMap = true;
function updatePosition(position) {
  global_positions[position.deviceId] = position;
  let course = position.course - 45;
  let attributes = position.attributes;
  let elm = $("#device_id_" + position.deviceId).find(".last_update");
  elm.html(getElapsedTime(position.serverTime));

  $("#device_id_" + position.deviceId).find(".name_vehicle_event > a").attr("onclick", "goToMap([" + position.longitude + ", " + position.latitude + "]);");
  let temperature = (attributes.temp1 != null) ? " - " + attributes.temp1.toFixed(2) + "°" : '';
  $("#device_id_" + position.deviceId).find(".name_vehicle_event .temperature").html(temperature);
  $("#device_id_" + position.deviceId).find(".img-vehicle-direction").attr("style", "width: 24px;height:24px;transform: rotate(" + course + "deg);-ms-transform: rotate(" + course + "deg);-moz-transform: rotate(" + course + "deg);-webkit-transform: rotate(" + course + "deg);-o-transform: rotate(" + course + "deg);");

  if (parseFloat(position.speed.toFixed(0)) > 3) {
    $("#device_id_" + position.deviceId).find(".move-indicator").css("background-color", 'green');
    $("#device_id_" + position.deviceId).find(".move-indicator").attr("title", 'moving');
  } else if (attributes.ignition) {
    $("#device_id_" + position.deviceId).find(".move-indicator").css("background-color", 'blue');
    $("#device_id_" + position.deviceId).find(".move-indicator").attr("title", 'ignition_on');
  } else {
    $("#device_id_" + position.deviceId).find(".move-indicator").css("background-color", 'red');
    $("#device_id_" + position.deviceId).find(".move-indicator").attr("title", 'stopped');
  }
  let marker_url = elm.parent().attr("data-marker");
  let marker = new ol.Feature({
    geometry: new ol.geom.Point(
      ol.proj.fromLonLat([position.longitude, position.latitude])
    ),
  });
  let color_marker = getColorMarker(position.deviceId);
  marker.setStyle(new ol.style.Style({
    image: new ol.style.Icon({
      crossOrigin: 'anonymous',
      //color: color_marker,
      src: '/assets/' + 'images/' + getMarkerByDeviceId(position.deviceId),
      //size : [20,20],
    }),
    text: new ol.style.Text({
      text: global_vehicles_by_device_id[position.deviceId].replace(/-.*/, "") + temperature,
      overflow: true,
      fill: new ol.style.Fill({
        color: Traccar.Style.mapGeofenceTextColor
      }),
      stroke: new ol.style.Stroke({
        color: Traccar.Style.mapTextStrokeColor,
        width: Traccar.Style.mapTextStrokeWidth
      }),
      font: Traccar.Style.mapTextFont
    })
  }));
  marker.device_id = position.deviceId;
  //marker.color = color_marker;

  removeMarker(position.deviceId);
  markerVectorLayer.getSource().addFeature(marker);
  if(zoomToMap){
    map.getView().fit(markerVectorLayer.getSource().getExtent());
    zoomToMap = false;
  }

}

function updateDevice(device) {
  let elm = $("#device_id_" + device.id).find(".name_vehicle");
  elm.removeClass("offline");
  elm.removeClass("online");
  elm.removeClass("unknown");
  elm.addClass(device.status);
  elm.attr("title", device.status);
  if (global_positions[device.id]) {
    //$("#device_id_" + device.id).find(".last_update").html(getElapsedTime(new Date(device.lastUpdate)));
    let marker_url = elm.parent().attr("data-marker");
    let marker = new ol.Feature({
      geometry: new ol.geom.Point(
        ol.proj.fromLonLat([global_positions[device.id].longitude, global_positions[device.id].latitude])
      ),
    });
    let color_marker = getColorMarker(device.id);
    marker.setStyle(new ol.style.Style({
      image: new ol.style.Icon({
        crossOrigin: 'anonymous',
        //color: global_colors[device.status],
        src: '/assets/' + 'images/' + getMarkerByDeviceId(device.id)
      }),
      text: new ol.style.Text({
        text: global_vehicles_by_device_id[device.id],
        overflow: true,
        fill: new ol.style.Fill({
          color: Traccar.Style.mapGeofenceTextColor
        }),
        stroke: new ol.style.Stroke({
          color: Traccar.Style.mapTextStrokeColor,
          width: Traccar.Style.mapTextStrokeWidth
        }),
        font: Traccar.Style.mapTextFont
      })
    }));
    marker.device_id = device.id;
    //marker.color = global_colors[device.status];

    removeMarker(device.id);
    markerVectorLayer.getSource().addFeature(marker);
  }
}

function goToMap(position) {
  map.getView().animate({
    center: ol.proj.transform(position, 'EPSG:4326', 'EPSG:3857'),
    duration: 1000,
    zoom: 20
  });
}

function getElapsedTime(start) {

  // Opera 8.0+
  var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;

  // Firefox 1.0+
  var isFirefox = typeof InstallTrigger !== 'undefined';

  // Safari 3.0+ "[object HTMLElementConstructor]"
  var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) {
    return p.toString() === "[object SafariRemoteNotification]";
  })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));

  // Internet Explorer 6-11
  var isIE = /*@cc_on!@*/false || !!document.documentMode;

  // Edge 20+
  var isEdge = !isIE && !!window.StyleMedia;

  // Chrome 1 - 79
  var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);

  // Edge (based on chromium) detection
  var isEdgeChromium = isChrome && (navigator.userAgent.indexOf("Edg") != -1);

  // Blink engine detection
  var isBlink = (isChrome || isOpera) && !!window.CSS;

  if (isSafari || window.navigator.userAgent.match(/iPad/i) || window.navigator.userAgent.match(/iPhone/i)) {
    start = start.replace("+0000", "");
  }

  let elapsed = new Date().getTime() - new Date(start);
  let unity = "m";
  elapsed = elapsed / (1000 * 60);
  if (elapsed > 59) {
    elapsed = elapsed / 60;
    unity = "h";
    if (elapsed > 23) {
      elapsed = elapsed / 24;
      unity = "d";
    }
  }
  return Math.abs(Math.floor(elapsed)) + " " + unity;
}

function centerMap() {
  map.getView().fit(markerVectorLayer.getSource().getExtent(), {duration: 1000});
}

function loadModalWithDeviceId(device_id, tab) {
  $(".loading-image").css("visibility", "visible");
  $.get("<%= Rails.application.routes.url_helpers.get_device_path %>", {
    device_id: device_id,
    tab: tab
  }, function (data) {
    $(".loading-image").css("visibility", "hidden");
    loadModalData(data);
  });
}
function loadModalWithVechicleId(vehicle_id, tab) {
  $(".loading-image").css("visibility", "visible");
  $.get("<%= Rails.application.routes.url_helpers.get_vehicle_path %>", {id: vehicle_id, tab: tab}, function (data) {
    $(".loading-image").css("visibility", "hidden");
    loadModalData(data);
  });
}

function loadDataCommandsVehicleTab(only_historical) {
  $(".loading-image").css("visibility", "visible");
  $.get("<%= Rails.application.routes.url_helpers.get_commands_path %>", {device_id: global_actual_vehicle.device.id}, function (data) {
    $(".loading-image").css("visibility", "hidden");
    let html = getCommandsTabContent(only_historical, data.commands, data.positions, data.commands_sends);
    if (only_historical) {
      $("#vehicle_detail_modal .modal-body .content_table_commands").html(html);
    } else {
      $("#vehicle_detail_modal .modal-body #commands_vehicle").html(html);
    }

    $('#table_commands').DataTable({
      responsive: true,
      order: [[0, "desc"]],
      dom: 'rtl<"dataTables_footer"ip>',
      "language": {
        "url": "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Spanish.json"
      }
    });

    $(".refresh_commands_table").unbind("click");
    $(".refresh_commands_table").click(function () {
      loadDataCommandsVehicleTab(true);
    });
  });
}

function loadDataLocationsVehicleTab(only_historical, date_ini = null, date_end = null) {
  $(".loading-image").css("visibility", "visible");
  $.get("<%= Rails.application.routes.url_helpers.get_positions_path %>", {
    device_id: global_actual_vehicle.device.id,
    date_ini: date_ini,
    date_end: date_end
  }, function (data) {
    $(".loading-image").css("visibility", "hidden");
    let html = getLocationsTabContent(only_historical, data.positions);
    if (only_historical) {
      $("#vehicle_detail_modal .modal-body .content_table_positions").html(html);
    } else {
      $("#vehicle_detail_modal .modal-body #locations_vehicle").html(html);
    }

    $('#table_positions').DataTable({
      responsive: true,
      order: [[0, "desc"]],
      dom: 'rtl<"dataTables_footer"ip>',
      "language": {
        "url": "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Spanish.json"
      }
    });

    $(".refresh_locations_table").unbind("click");
    $(".refresh_locations_table").click(function () {
      loadDataLocationsVehicleTab(true);
    });

    $(".refresh_locations_table_with_date").unbind("click");
    $(".refresh_locations_table_with_date").click(function () {
      let date1 = $("#location_date_ini").val();
      let date2 = $("#location_date_end").val();
      if (date1 != null || date2 != null) {
        loadDataLocationsVehicleTab(true, date1, date2);
      }
    });
  });
}

function loadDataLocationsOverMapVehicleTab(only_historical, date_ini = null, date_end = null) {
  $(".loading-image").css("visibility", "visible");
  $.get("<%= Rails.application.routes.url_helpers.get_positions_path %>", {
    device_id: global_actual_vehicle.device.id,
    date_ini: date_ini,
    date_end: date_end
  }, function (data) {
    $(".loading-image").css("visibility", "hidden");
    $("#map_content_locations").html('<div id="popup"></div>');

    var element = document.getElementById('popup');
    var overlay = getOverlay(element);

    var map2 = getMapInstance('map_content_locations', overlay);

    let markers = [];
    let markersLayers = [];
    let length = data.positions.length;
    let points = [];
    for (let i in data.positions) {
      let position = data.positions[i];
      let attributes = JSON.parse(position.attributes.attributes);

      let batteryLevel = (attributes.batteryLevel != null) ? attributes.batteryLevel : 0;
      let ignition = (attributes.ignition != null && attributes.ignition == true) ? '<%= _("Yes") %>' : '<%= _("No") %>';
      let power = (attributes.power != null) ? attributes.power : '--';
      let speed = position.speed.toFixed(0);

      points.push([position.longitude, position.latitude]);
      let marker = new ol.Feature({
        type: 'marker',
        text: position.fixtime.replace(/\..*/, "").replace("T", " ") + '<br><b><%= _("Speed") %></b>: ' + speed + '<br><b><%= _("% Battery") %></b>: ' + batteryLevel + '<br><b><%= _("Battery Voltage") %></b>: ' + power + '<br><b><%= _("Ignition") %></b>: ' + ignition,
        geometry: new ol.geom.Point(
          ol.proj.fromLonLat([position.longitude, position.latitude])
        ),
      });
      marker.setStyle(new ol.style.Style({
        image: new ol.style.Icon({
          crossOrigin: 'anonymous',
          //color: color_marker,
          src: '/assets/' + 'images/marker/marker_default.png',
          //size : [20,20],
        }),
        text: new ol.style.Text({
          text: parseInt(length - parseInt(i)).toString(),
          overflow: true,
          fill: new ol.style.Fill({
            color: Traccar.Style.mapGeofenceTextColor
          }),
          stroke: new ol.style.Stroke({
            color: Traccar.Style.mapTextStrokeColor,
            width: Traccar.Style.mapTextStrokeWidth
          }),
          font: Traccar.Style.mapTextFont
        })
      }));

      let vectorSourceM = new ol.source.Vector({
        features: [marker]
      });

      let markerVectorLayerMap2M = new ol.layer.Vector({
        source: vectorSourceM,
        type: 'marker',
        text: position.fixtime.replace(/\..*/, "").replace("T", " ") + '<br><b><%= _("Speed") %></b>: ' + speed + '<br><b><%= _("% Battery") %></b>: ' + batteryLevel + '<br><b><%= _("Battery Voltage") %></b>: ' + power + '<br><b><%= _("Ignition") %></b>: ' + ignition,
      });
      map2.addLayer(markerVectorLayerMap2M);

      markers.push(marker);
      markersLayers.push(markerVectorLayerMap2M);
      markerVectorLayerMap2M.setVisible(false);
      markerVectorLayerMap2M.setZIndex(2);
    }
    if (markers.length > 0) {
      let vectorSource2 = new ol.source.Vector({
        features: markers
      });
      let markerVectorLayerMap2Details = new ol.layer.Vector({
        source: vectorSource2,
      });
      map2.addLayer(markerVectorLayerMap2Details);
      markerVectorLayerMap2Details.setVisible(false);
      map2.getView().fit(markerVectorLayerMap2Details.getSource().getExtent());
      map2.removeLayer(markerVectorLayerMap2Details);
      map2.on('singleclick', function (evt) {
        var feature = map2.forEachFeatureAtPixel(evt.pixel,
          function (feature) {
            return feature;
          });
        if (feature && feature.get("type") == "marker") {
          var coordinates = feature.getGeometry().getCoordinates();
          try {
            $(element).popover('dispose');
          } catch (e) {
          }
          overlay.setPosition(coordinates);
          $(element).popover({
            placement: 'top',
            html: true,
            content: feature.get('text')
          });
          $(".popover-body").html(feature.get('text'));
          $(element).popover('show');
        } else {
          $(element).popover('dispose');
        }
      });
      map2.on('pointermove', function (evt) {
        if (evt.dragging) {
          return;
        }
        var feature = map2.forEachFeatureAtPixel(evt.pixel,
          function (feature) {
            return feature;
          });
        if (feature && feature.get("type") == "marker") {
          var coordinates = feature.getGeometry().getCoordinates();
          try {
            $(element).popover('dispose');
          } catch (e) {
          }
          overlay.setPosition(coordinates);
          $(element).popover({
            placement: 'top',
            html: true,
            content: feature.get('text')
          });
          $(".popover-body").html(feature.get('text'));
          $(element).popover('show');
        } else {
          $(element).popover('dispose');
        }
      });


      startEventsAnimation(map2, points, markersLayers);
    }

    $(".refresh_locations_over_map_table").unbind("click");
    $(".refresh_locations_over_map_table").click(function () {
      loadDataLocationsOverMapVehicleTab(true);
    });

    $(".refresh_locations_over_map_table_with_date").unbind("click");
    $(".refresh_locations_over_map_table_with_date").click(function () {
      let date1 = $("#location_over_map_date_ini").val();
      let date2 = $("#location_over_map_date_end").val();
      if (date1 != null || date2 != null) {
        loadDataLocationsOverMapVehicleTab(true, date1, date2);
      }
    });
  });
}

function loadDataEventsVehicleTab(only_historical) {
  $(".loading-image").css("visibility", "visible");
  $.get("<%= Rails.application.routes.url_helpers.get_events_path %>", {device_id: global_actual_vehicle.device.id}, function (data) {
    $(".loading-image").css("visibility", "hidden");
    let html = getEventsTabContent(only_historical, data.events);
    if (only_historical) {
      $("#vehicle_detail_modal .modal-body .content_table_events").html(html);
    } else {
      $("#vehicle_detail_modal .modal-body #events_vehicle").html(html);
    }

    $('#table_events').DataTable({
      responsive: true,
      order: [[0, "desc"]],
      dom: 'rtl<"dataTables_footer"ip>',
      "language": {
        "url": "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Spanish.json"
      },
    });

    $(".refresh_events_table").unbind("click");
    $(".refresh_events_table").click(function () {
      loadDataEventsVehicleTab(true);
    });
  });
}

function loadDataSharedLocationTab() {
  $(".loading-image").css("visibility", "visible");
  $.get("<%= Rails.application.routes.url_helpers.get_shared_location_path %>", {vehicle_id: global_actual_vehicle.vehicle.id}, function (data) {
    $("#shared_location").html(data);
    $(".loading-image").css("visibility", "hidden");
  });
}

function loadDataAlertsVehicleTab(only_historical) {
  $(".loading-image").css("visibility", "visible");
  $.get("<%= Rails.application.routes.url_helpers.get_alerts_path %>", {device_id: global_actual_vehicle.device.id}, function (data) {
    $(".loading-image").css("visibility", "hidden");
    let html = getAlertsTabContent(only_historical, data.device, data.alerts);
    if (only_historical) {
      $("#vehicle_detail_modal .modal-body .content_table_alerts").html(html);
    } else {
      $("#vehicle_detail_modal .modal-body #alerts_vehicle").html(html);
    }

    $('#table_alerts').DataTable({
      responsive: true,
      order: [[0, "desc"]],
      dom: 'rtl<"dataTables_footer"ip>',
      "language": {
        "url": "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Spanish.json"
      }
    });

    $(".refresh_alerts_table").unbind("click");
    $(".refresh_alerts_table").click(function () {
      loadDataAlertsVehicleTab(true);
    });
  });
}

function loadDataGeofencesVehicleTab(only_historical) {
  $(".loading-image").css("visibility", "visible");
  $.get("<%= Rails.application.routes.url_helpers.get_geofences_path %>", {device_id: global_actual_vehicle.device.id}, function (data) {
    $(".loading-image").css("visibility", "hidden");
    let html = getGeofencesTabContent(only_historical, data.geofences);
    if (only_historical) {
      $("#vehicle_detail_modal .modal-body .content_table_geofences").html(html);
    } else {
      $("#vehicle_detail_modal .modal-body #geofences_vehicle").html(html);
    }

    $('#table_geofences').DataTable({
      responsive: true,
      order: [[0, "desc"]],
      dom: 'rtl<"dataTables_footer"ip>',
      "language": {
        "url": "//cdn.datatables.net/plug-ins/9dcbecd42ad/i18n/Spanish.json"
      }
    });

    $(".refresh_geofences_table").click(function () {
      loadDataGeofencesVehicleTab(true);
    });
  });
}

function loadModalData(data) {
  global_actual_vehicle = data;
  let vehicle = data.vehicle;
  let device = data.device;
  let last_position = data.last_position;
  let group = data.group;
  let tab = data.tab;

  $('#vehicle_detail_modal').modal('show');
  $("#vehicle_detail_title").html("Vehicle: " + vehicle.name);

  $("#vehicle_detail_modal .modal-body #home_vehicle").html(getHomeTabContent(vehicle, device, last_position, group));
  $("#vehicle_detail_modal .modal-body #session_vehicle").html(getSessionTabContent(vehicle, device, last_position, group));
  let map_detail = getMapInstance('vehicle-detail-map', null);

  let marker = getFeatureMarker(device.id);
  let vectorSource = new ol.source.Vector({
    features: [marker]
  });
  let markerVectorLayerMapDetails = new ol.layer.Vector({
    source: vectorSource,
  });

  map_detail.addLayer(markerVectorLayerMapDetails);
  map_detail.getView().fit(markerVectorLayerMapDetails.getSource().getExtent());
  if (tab == "home") {
    $("#session_vehicle-tab").click();
    setTimeout('$("#home_vehicle-tab").click();', 500);
  } else if (tab == "commands") {
    $("#session_vehicle-tab").click();
    setTimeout('$("#commands_vehicle-tab").click();', 500);
  } else if (tab == "alerts") {
    $("#session_vehicle-tab").click();
    setTimeout('$("#alerts_vehicle-tab").click();', 500);
  } else {
    $("#" + tab + "_vehicle-tab").click();
  }

}
var prev_styles = {};
function visibilityMarkerChange(elm, device_id) {
  marker = getFeatureMarker(device_id);
  if ($(elm).is(':checked')) {
    marker.setStyle(prev_styles[device_id]);
    prev_styles.delete(device_id);
  } else {
    prev_styles[device_id] = marker.getStyle();
    marker.setStyle(null);
  }
}

function destroySesionServerTracking(callback) {
  $.ajax({
    url: URL_SERVER_TRACKING + "/api/session",
    data: {},
    type: 'DELETE',
    dataType: 'json',
    xhrFields: {
      withCredentials: true
    },
    success: function (data) {
      callback();
    },
    error: function (error) {

    }
  });
}

function startSessionServerTracking() {
  $.ajax({
    url: URL_SERVER_TRACKING + "/api/session?token=" + SERVER_TRACKING_TOKEN,
    data: {},
    dataType: 'json',
    xhrFields: {
      withCredentials: true
    },
    success: function (data) {
      $(".loading-image").css("visibility", "hidden");
      startSocketWithServerTracking();
      updateAllPositions(false);
    }
  });
}
var infoDevices;
function stopTraccar() {
  infoDevices.close();
}

function startServerTraccar() {
  $.ajax({
    url: URL_SERVER_TRACKING + "/api/session",
    data: {},
    dataType: 'json',
    xhrFields: {
      withCredentials: true
    },
    success: function (data) {
      $(".loading-image").css("visibility", "hidden");
      destroySesionServerTracking(startSessionServerTracking)
    },
    error: function (error) {
      startSessionServerTracking();
    }
  });
}


function startSocketWithServerTracking() {

  infoDevices = new WebSocket("<%= ENV["TRACCAR_SERVER_SOCKET_URI"] %>");
  infoDevices.onmessage = function (msg) {
    let data = JSON.parse(msg.data);
    if (data.positions) {
      for (let key in data.positions) {
        let position = data.positions[key];
        updatePosition(position);
      }
    }

    if (data.devices) {
      for (let key in data.devices) {
        let device = data.devices[key];
        updateDevice(device);
      }
    }

    if (data.events) {
      for (let key in data.events) {
        let audio = document.createElement("audio");
        if (data.events[key].sound) {
          audio.src = "/assets/sounds/" + data.events[key].sound + ".mp3";
        }
        let title = 'Nueva notificación!';
        let name_alert = data.events[key].name_alert;
        let name_geofence = getNameGeofenceById(data.events[key].geofenceId);
        name_alert = name_alert + (name_geofence ? "-----> Geocerca: " + name_geofence : "");
        let text = "Alerta de tipo: " + name_alert + " para el dispositivo: " + global_vehicles_by_device_id[data.events[key].deviceId];
        showStackBarAlert(data.events[key].color_alert, title, text, audio);
      }

    }
  }
}

function getNameGeofenceById(id) {
  for (let i in global_geofences) {
    if (global_geofences[i].id == id)
      return global_geofences[i].name;
  }
  return "";
}

function initSizeMap() {
  let height_calc = $(window).height() - $("main").position().top;
  $("main").height(height_calc);
  $("#wrapper").height(height_calc);
  $("#wrapper .content-wrapper").height(height_calc);
  $("#wrapper > .content-wrapper > .content").height(height_calc);
  $("#wrapper > .content-wrapper > .content > #contacts").height(height_calc);

  height_calc = height_calc - $(".page-content-wrapper").position().top;
  $(".page-content-wrapper").height(height_calc);

  let height_calc_map = height_calc - $(".map-content-row").position().top;
  $(".map-content-row").height(height_calc_map);
  $(".map-content-row > div").height(height_calc_map);
  $(".map-content-row > div > #map").height(height_calc_map);
}

function initEvents(){
  $("#geofences_vehicle-tab").unbind( "click" );
  $("#geofences_vehicle-tab").click(function () {
    if (!$(this).hasClass("active")) {
      loadDataGeofencesVehicleTab();
    }
  });

  $("#events_vehicle-tab").unbind( "click" );
  $("#events_vehicle-tab").click(function () {
    if (!$(this).hasClass("active")) {
      loadDataEventsVehicleTab();
    }
  });
  $("#locations_vehicle-tab").unbind( "click" );
  $("#locations_vehicle-tab").click(function () {
    if (!$(this).hasClass("active")) {
      loadDataLocationsVehicleTab();
    }
  });
  $("#locations_vehicle_over_map-tab").unbind( "click" );
  $("#locations_vehicle_over_map-tab").click(function () {
    if (!$(this).hasClass("active")) {
      loadDataLocationsOverMapVehicleTab();
    }
  });

  $("#commands_vehicle-tab").unbind( "click" );
  $("#commands_vehicle-tab").click(function () {
    if (!$(this).hasClass("active")) {
      loadDataCommandsVehicleTab();
    }
  });

  $("#alerts_vehicle-tab").unbind( "click" );
  $("#alerts_vehicle-tab").click(function () {
    if (!$(this).hasClass("active")) {
      loadDataAlertsVehicleTab();
    }
  });

  $("#shared_location-tab").unbind( "click" );
  $("#shared_location-tab").click(function () {
    if (!$(this).hasClass("active")) {
      loadDataSharedLocationTab();
    }

    $('#vehicle_detail_modal').on('hidden.bs.modal', function () {
      global_actual_vehicle = null;
      $("#home_vehicle").html("");
      $("#session_vehicle").html("");
      $("#alerts_vehicle").html("");
      $("#commands_vehicle").html("");
    });
  });

  $(window).on("blur focus", function (e) {
    var prevType = $(this).data("prevType");
    if (prevType != e.type) {   //  reduce double fire issues
      switch (e.type) {
        case "blur":
          stopTraccar();
          startSocketWithServerTracking();
          break;
        case "focus":
          updateAllPositions(true);
          break;
      }
    }

    $(this).data("prevType", e.type);
  });
}

function init() {
  initEvents();
  initSizeMap();
  setInterval('updateAllPositions()',30000);

  map = getMapInstance('map');
  markerVectorLayer = new ol.layer.Vector({
    source: new ol.source.Vector({
      features: []
    }),
  });
  map.addLayer(markerVectorLayer);

  map.on("click", function (e) {
    let coord = ol.proj.transform(e.coordinate, map.getView().getProjection(), 'EPSG:4326');
    //console.log("long: " + coord[0].toFixed(6) + " lat: " + coord[1].toFixed(6));

    map.forEachFeatureAtPixel(e.pixel, function (feature, layer) {
      if (feature.device_id) {
        loadModalWithDeviceId(feature.device_id, 'home');
      }
    })
  });

  for (i in global_geofences) {
    let geofence = global_geofences[i];
    let wkt = geofence.area;
    let feature = new ol.Feature(wktToGeometry(map.getView(), wkt));
    let attributes = JSON.parse(geofence.attributes.attributes);
    feature.setStyle(geofenceStyle(geofence.name, attributes ? attributes : null));
    feature.geofence_id = geofence.id;
    //markerVectorLayer.getSource().addFeature(feature);
  }

  startServerTraccar();
  setTimeout("$('aside').click();", 500);
  window.addEventListener('resize', initSizeMap);
}

function startEventsAnimation(map2, points, markers) {
  var polyline = (new ol.format.Polyline({
    factor: 1e6
  }).writeGeometry(new ol.geom.MultiLineString([points])));

  var route = (new ol.format.Polyline({
    factor: 1e6
  }).readGeometry(polyline, {
    dataProjection: 'EPSG:4326',
    featureProjection: 'EPSG:3857'
  }));

  var routeCoords = route.getCoordinates();
  var routeLength = routeCoords.length;

  var routeFeature = new ol.Feature({
    type: 'route',
    geometry: route
  });
  var geoMarker = new ol.Feature({
    type: 'geoMarker',
    geometry: new ol.geom.Point(routeCoords[0])
  });
  var startMarker = new ol.Feature({
    type: 'icon',
    geometry: new ol.geom.Point(routeCoords[0])
  });
  var endMarker = new ol.Feature({
    type: 'icon',
    geometry: new ol.geom.Point(routeCoords[routeLength - 1])
  });

  var styles = {
    'route': new ol.style.Style({
      stroke: new ol.style.Stroke({
        width: 6, color: [237, 212, 0, 0.8]
      })
    }),
    'geoMarker': new ol.style.Style({
      image: new ol.style.Circle({
        radius: 7,
        fill: new ol.style.Fill({color: 'black'}),
        stroke: new ol.style.Stroke({
          color: 'white', width: 2
        })
      }),
      zIndex: 3
    })
  };

  var animating = false;
  var speed, now;
  var startButton = document.getElementById('start-animation');
  var vectorLayer3 = new ol.layer.Vector({
    source: new ol.source.Vector({
      features: [routeFeature, startMarker, endMarker]
    }),
    style: function (feature) {
      // hide geoMarker if animation is active
      if (animating && feature.get('type') === 'geoMarker') {
        return null;
      }
      return styles[feature.get('type')];
    }
  });
  var vectorLayer_3 = new ol.layer.Vector({
    source: new ol.source.Vector({
      features: [geoMarker]
    }),
    style: function (feature) {
      // hide geoMarker if animation is active
      if (animating && feature.get('type') === 'geoMarker') {
        return null;
      }
      return styles[feature.get('type')];
    }
  });
  vectorLayer_3.setZIndex(1000);
  map2.addLayer(vectorLayer3);
  map2.addLayer(vectorLayer_3);

  var moveFeature = function (event) {
    var vectorContext = ol.render.getVectorContext(event);
    var frameState = event.frameState;
    if (animating) {
      var elapsedTime = frameState.time - now;
      var index = Math.round(speed * elapsedTime / 1000);

      if (index >= routeLength) {
        stopAnimation(true);
        return;
      }

      markers[routeLength - 1 - index].setVisible(true);

      var currentPoint = new ol.geom.Point(routeCoords[routeLength - 1 - index]);
      var feature = new ol.Feature(currentPoint);
      vectorContext.drawFeature(feature, styles.geoMarker);
    }
    map2.render();
  };

  function startAnimation() {
    if (animating) {
      stopAnimation(false);
    } else {
      for (let i in markers)
        markers[i].setVisible(false);
      animating = true;
      now = new Date().getTime();
      speed = 5;
      geoMarker.setStyle(null);
      vectorLayer3.on('postrender', moveFeature);
      map2.render();
    }
  }

  function stopAnimation(ended) {
    animating = false;
    var coord = ended ? routeCoords[0] : routeCoords[routeLength - 1];
    var geometry = geoMarker.getGeometry();
    geometry.setCoordinates(coord);
    vectorLayer3.un('postrender', moveFeature);
  }

  startButton.addEventListener('click', startAnimation, false);
}

function hexToAscii(str1) {
  if (str1 == null || str1.length == 0)
    return '';
  var hex = str1.toString();
  var str = '';
  for (var n = 0; n < hex.length; n += 2) {
    str += String.fromCharCode(parseInt(hex.substr(n, 2), 16));
  }
  return str;
}

function asciiToHex(str) {
  var arr1 = [];
  for (var n = 0, l = str.length; n < l; n++) {
    var hex = Number(str.charCodeAt(n)).toString(16);
    arr1.push(hex);
  }
  return arr1.join('');
}

function getHomeTabContent(vehicle, device, position, group) {
  if (position.attributes) {
    let attributes = JSON.parse(position.attributes.attributes);
    let course = position.course - 45;
    let void_str = "";
    let html = `
          <div id="accordion_now" role="tablist">
            <div class="card">
              <div class="card-header" role="tab" id="headingOne">
                <h5 class="mb-0">
                  <a data-toggle="collapse" href="#general_now_map_vehicle" aria-expanded="true"
                     aria-controls="collapseOne">
                    Map
                  </a>
                </h5>
              </div>

              <div id="general_now_map_vehicle" class="collapse show" role="tabpanel" aria-labelledby="headingOne"
                   data-parent="#accordion_now">
                <div class="card-block">
                  <div id="vehicle-detail-map" class="map" style="height: 300px;"></div>
                </div>
              </div>
            </div>
            <div class="card">
              <div class="card-header" role="tab" id="headingTwo">
                <h5 class="mb-0">
                  <a class="collapsed" data-toggle="collapse" href="#general_now_vehicle" aria-expanded="false"
                     aria-controls="collapseTwo">
                    <%= _("General") %>
                  </a>
                </h5>
              </div>
              <div id="general_now_vehicle" class="collapse" role="tabpanel" aria-labelledby="headingTwo"
                   data-parent="#accordion_now">
                <div class="card-block">

                </div>
              </div>
            </div>
            <div class="card-block">
              ${getRowForTableData("<%= _("Serial/IMEI") %>", device.uniqueid)}
              ${getRowForTableData("<%= _("Vechicle Name") %>", vehicle.name)}
              ${getRowForTableData("<%= _("Group") %>", group.name)}
              ${getRowForTableData("<%= _("Hardware Name") %>", device.name)}
              ${getRowForTableData("<%= _("Phone") %>", device.phone)}
              ${getRowForTableData("<%= _("Address") %>", ((position.address != null) ? position.address : "<a href='javascript:void(0);' onclick=\"getAddressFromCoords(this, '" + position.id + "', '" + position.latitude + "', '" + position.longitude + "');\"><%= _("Show Address") %></a>"))}
              ${getRowForTableData("<%= _("Last Reported") %>", device.lastupdate.replace(/\..*/, "").replace("T", " "))}
              ${getRowForTableData("<%= _("Direction") %>", "" +
                "<img style='width: 50px;transform: rotate(" + course + "deg);-ms-transform: rotate(" + course + "deg);-moz-transform: rotate(" + course + "deg);-webkit-transform: rotate(" + course + "deg);-o-transform: rotate(" + course + "deg);' " +
                "src='/assets/images/logos/logo_compass.svg'> " +
                getCourseNameFromCourseDegs(position.course) +
                '<a class="btn-details" href="https://www.instantstreetview.com/@' + position.latitude + ',' + position.longitude + ',10.5h,-19.38p,1z" target="_blank" style="margin-left: 10px" title="Street view"> <i class="fas fa-street-view s-4"></i> Street View</a>'
              )}
              ${getRowForTableData("<%= _("Lat/Lon") %>", "<a target='_blank' href='https://www.google.com/maps/place/(" + position.latitude + "+" + position.longitude + ")'><%= _("Open ubication") %></a>")}
              ${getRowForTableData("<%= _("Motion") %>", attributes.motion)}
              ${getRowForTableData("<%= _("Odometer") %>", parseInt(attributes.odometer) / 1000)}
              ${getRowForTableData("<%= _("Speed") %>", position.speed.toFixed(0))}
              ${getRowForTableData("<%= _("Altitude") %>", position.altitude)}
              ${getRowForTableData("<%= _("Fuel") %>", attributes.fuel)}
              ${getRowForTableData("<%= _("Temperature 1") %>", attributes.temp1)}
              ${getRowForTableData("<%= _("Temperature 2") %>", attributes.temp2)}
              ${getRowForTableData("<%= _("Temperature 3") %>", attributes.temp3)}
              ${getRowForTableData("<%= _("Acd1") %>", attributes.acd1)}
              ${getRowForTableData("<%= _("Acd1") %>", attributes.acd1)}
              ${getRowForTableData("<%= _("Acd1") %>", attributes.acd1)}
              ${getRowForTableData("<%= _("Rpm") %>", attributes.rpm)}
            `;
    if (attributes.batteryLevel) {
      let battery = parseFloat(attributes.batteryLevel);
      let img = "";
      if (battery >= 80) {
        img = '<img title="' + attributes.batteryLevel + '%" style="height: 40px;" src="<%= asset_path("others/battery_very_good.svg") %>">  ' + attributes.batteryLevel + "%";
      } else if (battery <= 80 && battery >= 60) {
        img = '<img title="' + attributes.batteryLevel + '%" style="height: 40px;" src="<%= asset_path("others/battery_good.svg") %>">  ' + attributes.batteryLevel + "%";
      } else if (battery < 60 && battery >= 40) {
        img = '<img title="' + attributes.batteryLevel + '%" style="height: 40px;" src="<%= asset_path("others/battery_regular.svg") %>">  ' + attributes.batteryLevel + "%";
      } else if (battery < 40 && battery >= 20) {
        img = '<img title="' + attributes.batteryLevel + '%" style="height: 40px;" src="<%= asset_path("others/battery_bad.svg") %>">  ' + attributes.batteryLevel + "%";
      } else if (battery < 20) {
        img = '<img title="' + attributes.batteryLevel + '%" style="height: 40px;" src="<%= asset_path("others/battery_very_bad.svg") %>">  ' + attributes.batteryLevel + "%";
      }
      html += `${getRowForTableData("<%= _("Battery Level") %>", img)}`;
    }


    html += `
              ${getRowForTableData("<%= _("Battery Voltage") %>", attributes.power)}
            </div>
          </div>
        `;
    return html;
  } else {
    alert("No se tiene una posición válida")
  }
}
function getSessionTabContent(vehicle, device, position, group) {
  let attributes = JSON.parse(position.attributes.attributes);
  let attributes2 = JSON.parse(position.attributes.attributes);
  delete (attributes2["raw"]);
  attributes2 = JSON.stringify(attributes2);
  let html = `
        <div id="accordion_session" role="tablist">
          <div class="card">
            <div class="card-header" role="tab" id="headingOne">
              <h5 class="mb-0">
                <a data-toggle="collapse" href="#general_vehicle" aria-expanded="true"
                   aria-controls="collapseOne">
                  <%= _("General") %>
                </a>
              </h5>
            </div>

            <div id="general_vehicle" class="collapse show" role="tabpanel" aria-labelledby="headingOne"
                 data-parent="#accordion">
              <div class="card-block">
                ${getRowForTableData("<%= _("Vechicle Name") %>", vehicle.name)}
                ${getRowForTableData("<%= _("Serial/IMEI") %>", device.uniqueid)}
                ${getRowForTableData("<%= _("Hardware Name") %>", device.name)}
                ${getRowForTableData("<%= _("Phone") %>", device.phone)}
                ${getRowForTableData("<%= _("Address") %>", ((position.address != null) ? position.address : "<a href='javascript:void(0);' onclick=\"getAddressFromCoords(this, '" + position.id + "', '" + position.latitude + "', '" + position.longitude + "');\"><%= _("Show Address") %></a>"))}
                ${getRowForTableData("<%= _("Last Reported") %>", device.lastupdate.replace(/\..*/, "").replace("T", " "))}
                ${getRowForTableData("<%= _("Lat/Lon") %>", "<a target='_blank' href='https://www.google.com/maps/place/(" + position.latitude + "+" + position.longitude + ")'><%= _("Open ubication") %></a>")}
                ${(CURRENT_USER_ADMIN) ? getRowForTableData("<%= _("Command Received") %>", hexToAscii(attributes.raw)) : ''}
              </div>
            </div>
          </div>
          <div class="card">
            <div class="card-header" role="tab" id="headingTwo">
              <h5 class="mb-0">
                <a class="collapsed" data-toggle="collapse" href="#detail_vehicle_info" aria-expanded="false"
                   aria-controls="collapseTwo">
                  <%= _("Vechicle information") %>
                </a>
              </h5>
            </div>
            <div id="detail_vehicle_info" class="collapse show" role="tabpanel" aria-labelledby="headingTwo"
                 data-parent="#accordion">
              <div class="card-block">
                ${getRowForTableData("<%= _("Vechicle Name") %>", vehicle.name)}
                ${getRowForTableData("<%= _("Vechicle VIN") %>", vehicle.vin)}
                ${getRowForTableData("<%= _("Vechicle Make") %>", vehicle.make)}
                ${getRowForTableData("<%= _("Vechicle Model") %>", vehicle.model)}
                ${getRowForTableData("<%= _("Vechicle Year") %>", vehicle.year)}
                ${getRowForTableData("<%= _("Vechicle Color") %>", vehicle.color)}
              </div>
            </div>
          </div>
        </div>
      `;
  return html;
}

function getCommandsTabContent(only_historical, commands, commands_receive, commands_sends) {
  let html = '';
  if (!only_historical) {
    html = `
              <div id="accordion_commands" role="tablist">
                <div class="card">
                  <div class="card-header" role="tab" id="headingOne1">
                    <h5 class="mb-0">
                      <a data-toggle="collapse" href="#commands_to_send" aria-expanded="true"
                         aria-controls="collapseOne">
                        <%= _("Commands List") %>
                      </a>
                    </h5>
                  </div>

                  <div id="commands_to_send" class="collapse show" role="tabpanel" aria-labelledby="headingOne1"
                       data-parent="#accordion">
                    <div class="card-block">
              `;

    if(CURRENT_USER_ADMIN) {
      commands.push({"type_command":"rebootConnection", "name": "REINICIAR CONEXIÓN", "enable": true})
    }

    for (let i in commands) {
      let command = commands[i];
      let buttons = '';
      if (command.enable)
        buttons += '<button onclick="sendCommand(\'' + asciiToHex(JSON.stringify(command)) + '\')">Send</button>'
      if (command.enable_sms && global_actual_vehicle.device.phone && global_actual_vehicle.device.phone != "")
        buttons += '<button onclick="sendCommand(\'' + asciiToHex(JSON.stringify(command)) + '\', true)">Send SMS</button>';

      html += getRowForTableData(command.name, buttons);
    }

    html += `
                  </div>
                </div>
              </div>
            `;


    html += `
                  <div class="card">
                    <div class="card-header" role="tab" id="heading-modal" style="display: flex;"'>
                      <h5 class="mb-0">
                        <a class="historical_events_link_tab collapsed" data-toggle="collapse" href="#detail_history_info" aria-expanded="false"
                           aria-controls="collapseTwo">
                          <%= _("Historical command") %>
                        </a>
                      </h5>
                      <button align="rigth" class="refresh_commands_table"><%= _("Refresh") %></button>
                    </div>
                    <div id="detail_history_info" class="collapse" role="tabpanel" aria-labelledby="heading-modal"
                         data-parent="#accordion">
                      <div class="card-block content_table_commands">
              `;

    html += `
                  <table id="table_commands" class="simple clickable table-striped table-hover">
                      <thead>
                          <tr>
                              <th><%= _("Date") %></th>
                              <th><%= _("Id/Event") %></th>
                              <th><%= _("Text") %></th>
                          </tr>
                      </thead>
                  <tbody>
                `;

    for (let i in commands_receive) {
      let command_receive = commands_receive[i];
      let attributes = JSON.parse(command_receive.attributes.attributes);
      html += `
                        <tr>
                `;
      html += `<td>${command_receive.servertime.replace(/\..*/, "").replace("T", " ")}</td>`;

      if (command_receive.event_type_name) {
        html += `<td>${command_receive.event_type_name}</td>`;
      } else if (command_receive.type_event) {
        html += `<td>${command_receive.type_event}`;
        if (command_receive.cod_event)
          html += `${command_receive.cod_event}`;
        html += '</td>';

      } else
        html += `<td>${command_receive.id}</td>`;

      if (attributes.raw)
        html += `<td>${hexToAscii(attributes.raw)}</td>`;
      else
        html += `<td>${command_receive.latitude} / ${command_receive.longitude}</td>`;
      html += `
                        </tr>
                `;
    }

    for (let i in commands_sends) {
      let command_send = commands_sends[i];
      let attributes = command_send.attributes;
      html += `
                        <tr>
                `;
      html += `<td>${command_send.servertime.replace(/\..*/, "").replace("T", " ")}</td>`;

      html += `<td>CMD-SEND</td>`;
      html += `<td>${command_send.command}</td>`;
      html += `
                        </tr>
                `;
    }
    html += `
                      </tbody>
                  </table>
                `;

    html += `
                  </div>
                </div>
              </div>
            </div>
          `;
  } else {
    html += `
              <table id="table_commands" class="simple clickable table-striped table-hover">
                  <thead>
                      <tr>
                          <th><%= _("Date") %></th>
                          <th><%= _("Id/Event") %></th>
                          <th><%= _("Text") %></th>
                      </tr>
                  </thead>
              <tbody>
            `;

    for (let i in commands_receive) {
      let command_receive = commands_receive[i];
      let attributes = JSON.parse(command_receive.attributes.attributes);
      html += `
                        <tr>
                `;
      html += `<td>${command_receive.fixtime.replace(/\..*/, "").replace("T", " ")}</td>`;
      if (command_receive.event_type_name) {
        html += `<td>${command_receive.event_type_name}</td>`;
      } else if (command_receive.type_event) {
        html += `<td>${command_receive.type_event}`;
        if (command_receive.cod_event)
          html += `${command_receive.cod_event}`;
        html += '</td>';
      } else
        html += `<td>${command_receive.id}</td>`;

      if (attributes.raw)
        html += `<td>${hexToAscii(attributes.raw)}</td>`;
      else
        html += `<td>${command_receive.latitude} / ${command_receive.longitude}</td>`;
      html += `
                        </tr>
                `;
    }

    for (let i in commands_sends) {
      let command_send = commands_sends[i];
      let attributes = command_send.attributes;
      html += `
                        <tr>
                `;
      html += `<td>${command_send.servertime.replace(/\..*/, "").replace("T", " ")}</td>`;

      html += `<td>CMD-SEND</td>`;
      html += `<td>${command_send.command}</td>`;
      html += `
                        </tr>
                `;
    }
    html += `
                      </tbody>
                  </table>
                `;
  }
  return html;
}

function getGeofencesTabContent(only_historical, geofences) {
  let html = '';
  if (!only_historical) {
    html += `
                <div id="accordion_geofences" role="tablist">
                  <div class="card">
                    <div class="card-header" role="tab" id="heading-modal" style="display: flex;"'>
                      <h5 class="mb-0">
                        <a class="historical_geofences_link_tab collapsed" data-toggle="collapse" href="#detail_location_info" aria-expanded="false"
                           aria-controls="collapseTwo">
                          <%= _("Assign Geofences") %>
                        </a>
                      </h5>
                      <button align="rigth" class="refresh_geofences_table"><%= _("Refresh") %></button>
                    </div>
                    <div id="detail_location_info" class="collapse show" role="tabpanel" aria-labelledby="heading-modal"
                         data-parent="#accordion">
                      <div class="card-block content_table_geofences">
              `;

    html += `
                  <table id="table_geofences" class="simple clickable table-striped table-hover">
                      <thead>
                          <tr>
                              <th><%= _("Geofence name") %></th>
                              <th><%= _("Action") %></th>
                              <th><%= _("Days") %></th>
                              <th><%= _("Time(min - max)") %></th>
                              <th><%= _("Speed(min - max) km/h") %></th>
                              <th><%= _("Generate Alert?") %></th>
                          </tr>
                      </thead>
                  <tbody>
                `;

    for (let i in geofences) {
      let geofence = geofences[i];
      html += `
                        <tr>
                `;
      html += `<td><a data-remote="true" href="/geofences/${geofence.geofenceid}?data=${btoa(JSON.stringify(global_actual_vehicle))}">${geofence.name}</a></td>`;
      html += `<td>${geofence.action}</td>`;
      html += `<td>${geofence.days}</td>`;
      html += `<td>${geofence.time_in} - ${geofence.time_out}</td>`;
      html += `<td>${(parseFloat(geofence.min_speed) * 1.852).toFixed(0)} - ${(parseFloat(geofence.max_speed) * 1.852).toFixed(0)}</td>`;
      html += `<td>${geofence.generate_alert}</td>`;
      html += `
                        </tr>
                `;
    }
    html += `
                      </tbody>
                  </table>
                `;

    html += `
                  </div>
                </div>
              </div>
            </div>
          `;
  } else {
    html += `
              <table id="table_geofences" class="simple clickable table-striped table-hover">
                  <thead>
                      <tr>
                                                        <th><%= _("Geofence name") %></th>
                              <th><%= _("Action") %></th>
                              <th><%= _("Email") %></th>
                              <th><%= _("Days") %></th>
                              <th><%= _("Time(min - max)") %></th>
                              <th><%= _("Speed(min - max)") %></th>
                              <th><%= _("Generate Alert?") %></th>
                      </tr>
                  </thead>
              <tbody>
            `;

    for (let i in geofences) {
      let geofence = geofences[i];
      html += `
                        <tr>
                `;
      html += `<td><a data-remote="true" href="/geofences/${geofence.geofenceid}?data=${btoa(JSON.stringify(global_actual_vehicle))}">${geofence.name}</a></td>`;
      html += `<td>${geofence.action}</td>`;
      html += `<td>${geofence.email}</td>`;
      html += `<td>${geofence.days}</td>`;
      html += `<td>${geofence.time_in} - ${geofence.time_out}</td>`;
      html += `<td>${geofence.min_speed} - ${geofence.max_speed}</td>`;
      html += `<td>${geofence.generate_alert}</td>`;

      html += `
                        </tr>
                `;
    }

    html += `
                      </tbody>
                  </table>
                `;
  }
  return html;
}

function getLocationsTabContent(only_historical, positions) {
  let html = '';
  let fuel_capacity = global_actual_vehicle.vehicle.fuel_capacity;
  if (!only_historical) {
    html += `
                <div id="accordion_locations" role="tablist">
                  <div class="card">
                    <div class="card-header row" role="tab" id="heading-modal" style="display: flex;"'>
                      <h5 class="mb-0">
                        <a class="historical_locations_link_tab collapsed" data-toggle="collapse" href="#detail_location_info" aria-expanded="false"
                           aria-controls="collapseTwo">
                          <%= _("Historical locations") %>
                        </a>
                      </h5>
                      <div class='col-md-3'>
                        <button align="rigth" class="refresh_locations_table"><%= _("Refresh") %></button>
                      </div>
                      <div class='col-md-6'>
                        <%= _("Date ini") %>
                        <input type='date' style='width: 130px' id='location_date_ini'>
                        <%= _("Date end") %>
                        <input type='date' style='width: 130px' id='location_date_end'>
                        <button align="rigth" class="refresh_locations_table_with_date"><%= _("Send") %></button>
                      </div>
                    </div>
                    <div id="detail_location_info" class="collapse show" role="tabpanel" aria-labelledby="heading-modal"
                         data-parent="#accordion">
                      <div class="card-block content_table_positions">
              `;

    html += `
                  <table id="table_positions" class="simple clickable table-striped table-hover">
                      <thead>
                          <tr>
                              <th><%= _("Date") %></th>
                              <th><%= _("Id/Event") %></th>
                              <th><%= _("Address") %></th>
                              <th><%= _("Speed") %></th>
                              <th><%= _("% Battery") %></th>
                              <th><%= _("Temperature 1") %></th>
                              <th><%= _("Battery Voltage") %></th>
                              <th><%= _("Ignition") %></th>
                              <th><%= _("Fuel") %></th>
                          </tr>
                      </thead>
                  <tbody>
                `;

    for (let i in positions) {
      let position = positions[i];
      let attributes = JSON.parse(position.attributes.attributes);
      html += `
                        <tr>
                `;
      html += `<td>${position.fixtime.replace(/\..*/, "").replace("T", " ")}</td>`;

      if (position.event_type_name) {
        html += `<td>${position.id} - ${position.event_type_name}</td>`;
      } else if (position.type_event) {
        html += `<td>${position.id} - ${position.type_event}`;
        if (position.cod_event)
          html += `${position.cod_event}`;
        html += '</td>';

      } else
        html += `<td>${position.id}</td>`;

      html += `<td>`;
      if (position.address != null) {
        html += `${position.address}`;
      } else {
        html += `<div><a href='javascript:void(0);' onclick="getAddressFromCoords(this, ${position.id}, '${position.latitude}', '${position.longitude}');"><%= _("Show Address") %></a></div>`;
      }
      html += "      <a target='_blank' href='https://www.google.com/maps/place/(" + position.latitude + "+" + position.longitude + ")'><%= _("Open ubication") %></a>";
      html += `</td>`;

      html += `<td>${position.speed.toFixed(0)}</td>`;
      html += `<td>${(attributes.batteryLevel != null) ? attributes.batteryLevel : 0}</td>`;
      html += `<td>${(attributes.temp1 != null) ? attributes.temp1.toFixed(2) + '°C' : '--'}</td>`;
      html += `<td>${(attributes.power != null) ? attributes.power.toFixed(2) + 'V' : '--'}</td>`;
      html += `<td>${(attributes.ignition != null && attributes.ignition == true) ? '<%= _("Yes") %>' : '<%= _("No") %>'}</td>`;
      html += `<td>${(attributes.fuel != null && fuel_capacity != null) ? (fuel_capacity * (attributes.fuel/100)).toFixed(1) + ' gal': '--'}</td>`;

      html += `
                        </tr>
                `;
    }
    html += `
                      </tbody>
                  </table>
                `;

    html += `
                  </div>
                </div>
              </div>
            </div>
          `;
  } else {
    html += `
              <table id="table_positions" class="simple clickable table-striped table-hover">
                  <thead>
                      <tr>
                          <th><%= _("Date") %></th>
                          <th><%= _("Id/Event") %></th>
                          <th><%= _("Address") %></th>
                          <th><%= _("Speed") %></th>
                          <th><%= _("% Battery") %></th>
                          <th><%= _("Temperature 1") %></th>
                          <th><%= _("Battery Voltage") %></th>
                          <th><%= _("Ignition") %></th>
                          <th><%= _("Fuel") %></th>
                      </tr>
                  </thead>
              <tbody>
            `;

    for (let i in positions) {

      let position = positions[i];
      let attributes = JSON.parse(position.attributes.attributes);
      html += `
                        <tr>
                `;
      html += `<td>${position.fixtime.replace(/\..*/, "").replace("T", " ")}</td>`;
      if (position.event_type_name) {
        html += `<td>${position.id} - ${position.event_type_name}</td>`;
      } else if (position.type_event) {
        html += `<td>${position.id} - ${position.type_event}`;
        if (position.cod_event)
          html += `${position.cod_event}`;
        html += '</td>';
      } else
        html += `<td>${position.id}</td>`;

      html += `<td>`;
      if (position.address != null) {
        html += `${position.address}`;
      } else {
        html += `<div><a href='javascript:void(0);' onclick="getAddressFromCoords(this, ${position.id}, '${position.latitude}', '${position.longitude}');"><%= _("Show Address") %></a></div>`;
      }
      html += "      <a target='_blank' href='https://www.google.com/maps/place/(" + position.latitude + "+" + position.longitude + ")'><%= _("Open ubication") %></a>";
      html += `</td>`;
      html += `<td>${position.speed.toFixed(0)}</td>`;
      html += `<td>${(attributes.batteryLevel != null) ? attributes.batteryLevel : 0}</td>`;
      html += `<td>${(attributes.temp1 != null) ? attributes.temp1.toFixed(2) + '°C' : '--'}</td>`;
      html += `<td>${(attributes.power != null) ? attributes.power.toFixed(2) + 'V' : '--'}</td>`;
      html += `<td>${(attributes.ignition != null && attributes.ignition == true) ? '<%= _("Yes") %>' : '<%= _("No") %>'}</td>`;
      html += `<td>${(attributes.fuel != null && fuel_capacity != null) ? (fuel_capacity * (attributes.fuel/100)).toFixed(1) + ' gal': '--'}</td>`;

      html += `
                        </tr>
                `;
    }

    html += `
                      </tbody>
                  </table>
                `;
  }
  return html;
}

function getEventsTabContent(only_historical, events) {
  let html = '';
  if (!only_historical) {
    html += `
                <div id="accordion_events" role="tablist">
                  <div class="card">
                    <div class="card-header" role="tab" id="heading-modal" style="display: flex;"'>
                      <h5 class="mb-0">
                        <a class="historical_events_link_tab collapsed" data-toggle="collapse" href="#detail_event_info" aria-expanded="false"
                           aria-controls="collapseTwo">
                          <%= _("Historical events") %>
                        </a>
                      </h5>
                      <button align="rigth" class="refresh_events_table"><%= _("Refresh") %></button>
                    </div>
                    <div id="detail_event_info" class="collapse show" role="tabpanel" aria-labelledby="heading-modal"
                         data-parent="#accordion">
                      <div class="card-block content_table_events">
              `;

    html += `
                  <table id="table_events" class="simple clickable table-striped table-hover">
                      <thead>
                          <tr>
                              <th><%= _("Date") %></th>
                              <th><%= _("Id/Event") %></th>
                              <th><%= _("Event") %></th>
                          </tr>
                      </thead>
                  <tbody>
                `;

    for (let i in events) {
      let event = events[i];
      html += `<tr>`;
      html += `<td>${event.date.replace(/\..*/, "").replace("T", " ")}</td>`;
      html += `<td>${event.type_alert}`;
      html += `<td>${event.name} ${event.geofence_name ? "----> Geofence: " + event.geofence_name : ""}</td>`;
      html += `</tr>`;
    }
    html += `
                      </tbody>
                  </table>
                `;

    html += `
                  </div>
                </div>
              </div>
            </div>
          `;
  } else {
    html += `
              <table id="table_events" class="simple clickable table-striped table-hover">
                  <thead>
                      <tr>
                          <th><%= _("Date") %></th>
                          <th><%= _("Id/Event") %></th>
                          <th><%= _("Event") %></th>
                      </tr>
                  </thead>
              <tbody>
            `;

    for (let i in events) {
      let event = events[i];
      html += `<tr>`;
      html += `<td>${event.date.replace(/\..*/, "").replace("T", " ")}</td>`;
      html += `<td>${event.type_alert}`;
      html += `<td>${event.name} ${event.geofence_name ? "----> Geofence: " + event.geofence_name : ""}</td>`;
      html += `</tr>`;
    }

    html += `
                      </tbody>
                  </table>
                `;
  }
  return html;
}

function getAlertsTabContent(only_historical, device, alerts) {
  let html = '';
  if (!only_historical) {
    html += `
                <div id="accordion_alerts" role="tablist">
                  <div class="card">
                    <div class="card-header" role="tab" id="heading-modal" style="display: flex;"'>
                      <h5 class="mb-0">
                        <a class="historical_alerts_link_tab collapsed" data-toggle="collapse" href="#detail_event_info" aria-expanded="false"
                           aria-controls="collapseTwo">
                          <%= _("Historical alerts") %>
                        </a>
                      </h5>
                      <button align="rigth" class="refresh_alerts_table"><%= _("Refresh") %></button>
                    </div>
                    <div id="detail_alert_info" class="collapse show" role="tabpanel" aria-labelledby="heading-modal"
                         data-parent="#accordion">
                      <div class="card-block content_table_alerts">
              `;

    html += `
                  <table id="table_alerts" class="simple clickable table-striped table-hover">
                      <thead>
                          <tr>
                              <th><%= _("Date") %></th>
                              <th><%= _("Id/Event") %></th>
                              <th><%= _("Name") %></th>
                          </tr>
                      </thead>
                  <tbody>
                `;

    for (let i in alerts) {
      let alert = alerts[i];
      html += `
                        <tr>
                `;
      html += `<td>${alert.date.replace(/\..*/, "").replace("T", " ")}</td>`;
      html += `<td>${(alert.color_alert == "info") ? '<img style="height: 30px;" src="<%= asset_path("others/position-icon-9.jpg") %>">' : (alert.color_alert == "notice") ? '<img style="height: 30px;" src="<%= asset_path("others/warning.png") %>">' : '<img style="height: 30px;" src="<%= asset_path("others/alert.png") %>">'}${alert.type_alert}</td>`;
      html += `<td>${alert.name} ${alert.geofence_name ? "----> <%= _("Geofence") %>: " + alert.geofence_name : ""}</td>`;
      html += `</tr>`;
    }
    html += `
                      </tbody>
                  </table>
                `;

    html += `
                  </div>
                </div>
              </div>
            </div>
          `;
  } else {
    html += `
              <table id="table_alerts" class="simple clickable table-striped table-hover">
                  <thead>
                      <tr>
                          <th><%= _("Date") %></th>
                          <th><%= _("Id/Event") %></th>
                          <th><%= _("Name") %></th>
                      </tr>
                  </thead>
              <tbody>
            `;

    for (let i in alerts) {
      let alert = alerts[i];
      html += `<tr>`;
      html += `<td>${alert.date.replace(/\..*/, "").replace("T", " ")}</td>`;
      html += `<td>${(alert.color_alert == "info") ? '<img style="height: 30px;" src="<%= asset_path("others/position-icon-9.jpg") %>">' : (alert.color_alert == "notice") ? '<img style="height: 30px;" src="<%= asset_path("others/warning.png") %>">' : '<img style="height: 30px;" src="<%= asset_path("others/alert.png") %>">'}${alert.type_alert}</td>`;
      html += `<td>${alert.name} ${alert.geofence_name ? "----> <%= _("Geofence") %>: " + alert.geofence_name : ""}</td>`;
      html += ` </tr>`;
    }

    html += `
                      </tbody>
                  </table>
                `;
  }
  return html;
}

function getRowForTableData(title, value) {
  if (typeof value === "undefined")
    return '';
  let html = `
          <div class="row">
            <div class="col-md-6">
              ${title}
            </div>
            <div class="col-md-6">
              ${value}
            </div>
          </div>
          <div class="divider"></div>
        `;
  return html;
}

function sendCommand(command, sms = false) {
  command = JSON.parse(hexToAscii(command));
  let command_value = "";
  let attributes = {};
  if (command.type_command == "custom") {
    command_value = prompt("<%= _("Insert custom command") %>:");
  } else if (command.type_command == "own") {
    command.type_command = "custom";

    command_value = command.value_command;

    let param_value = command_value.substring(
      command_value.indexOf("$$") + 2,
      command_value.length
    );
    param_value = param_value.substring(
      0,
      param_value.indexOf("$$")
    );

    while (param_value != "") {
      command_value = command_value.replace("$$" + param_value + "$$", global_actual_vehicle.device[param_value]);

      param_value = command_value.substring(
        command_value.indexOf("$$") + 2,
        command_value.length
      );
      param_value = param_value.substring(
        0,
        param_value.indexOf("$$")
      );
    }
  }

  if (command_value != "")
    attributes = {
      data: command_value
    }

  let data = {
    attributes: attributes,
    description: "<%= _("new") %>...",
    deviceId: global_actual_vehicle.device.id,
    id: 0,
    textChannel: false,
    type: command.type_command
  };

  if (sms)
    data.textChannel = true;
  $(".loading-image").css("visibility", "visible");
  $.ajax({
    url: "<%= ENV["TRACCAR_SERVER_URI"] %>/api/commands/send",
    type: "POST",
    data: JSON.stringify(data),
    dataType: 'json',
    xhrFields: {
      withCredentials: true
    },
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    },
    success: function (data, textStatus, xhr) {
    },
    complete: function (xhr, textStatus) {
      $(".loading-image").css("visibility", "hidden");
      if (xhr.status == 200) {
        PNotify.success({
          title: 'Success!',
          text: '<%= _("Command send!") %>'
        });
      } else if (xhr.status == 202) {
        PNotify.notice({
          title: 'Command in queue',
          text: '<%= _("This command was not sent yet!") %>'
        });
      } else {
        PNotify.error({
          title: 'Oh No!',
          text: '<%= _("Something has failed!") %>'
        })
      }

    }
  });
}