import { generateUrl } from '@nextcloud/router';
import { dirname, brify, metersToDistance, metersToElevation, kmphToSpeed, minPerKmToPace, formatTimeSeconds, getUrlParameter } from './utils';
import escapeHTML from 'escape-html';
function TracksController(optionsController, timeFilterController) {
this.track_MARKER_VIEW_SIZE = 30;
this.optionsController = optionsController;
this.timeFilterController = timeFilterController;
this.mainLayer = null;
this.elevationControl = null;
this.closeElevationButton = null;
// indexed by track id
// those actually added to map, those which get toggled
this.mapTrackLayers = {};
// layers which actually contain lines/waypoints, those which get filtered
this.trackLayers = {};
this.trackColors = {};
this.trackDivIcon = {};
this.tracks = {};
this.firstDate = null;
this.lastDate = null;
// used by optionsController to know if tracks loading
// was done before or after option restoration
this.trackListLoaded = false;
this.changingColorOf = null;
this.lastZIndex = 1000;
this.sortOrder = 'name';
}
TracksController.prototype = {
// set up favorites-related UI stuff
initController : function(map) {
this.map = map;
this.mainLayer = L.featureGroup();
this.mainLayer.on('click', this.getTrackMarkerOnClickFunction());
var that = this;
// UI events
// toggle a track
$('body').on('click', '.track-line .track-name', function(e) {
var id = $(this).parent().attr('track');
that.toggleTrack(id, true);
});
// zoom on track
$('body').on('click', '.zoomTrackButton', function(e) {
var id = $(this).parent().parent().parent().parent().attr('track');
that.zoomOnTrack(id);
});
// sort
$('body').on('click', '#sort-name-tracks', function(e) {
that.sortOrder = 'name';
that.sortTracks();
that.optionsController.saveOptionValues({tracksSortOrder: 'name'});
});
$('body').on('click', '#sort-date-tracks', function(e) {
that.sortOrder = 'date';
that.sortTracks();
that.optionsController.saveOptionValues({tracksSortOrder: 'date'});
});
// show/hide all tracks
$('body').on('click', '#select-all-tracks', function(e) {
that.showAllTracks();
var trackList = Object.keys(that.trackLayers);
var trackStringList = trackList.join('|');
that.optionsController.saveOptionValues({enabledTracks: trackStringList});
that.optionsController.enabledTracks = trackList;
that.optionsController.saveOptionValues({tracksEnabled: that.map.hasLayer(that.mainLayer)});
});
$('body').on('click', '#select-no-tracks', function(e) {
that.hideAllTracks();
var trackStringList = '';
that.optionsController.saveOptionValues({enabledTracks: trackStringList});
that.optionsController.enabledTracks = [];
that.optionsController.saveOptionValues({tracksEnabled: that.map.hasLayer(that.mainLayer)});
});
// toggle tracks
$('body').on('click', '#navigation-tracks > a', function(e) {
that.toggleTracks();
that.optionsController.saveOptionValues({tracksEnabled: that.map.hasLayer(that.mainLayer)});
that.updateMyFirstLastDates(true);
if (that.map.hasLayer(that.mainLayer) && !$('#navigation-tracks').hasClass('open')) {
that.toggleTrackList();
that.optionsController.saveOptionValues({trackListShow: $('#navigation-tracks').hasClass('open')});
}
});
// expand track list
$('body').on('click', '#navigation-tracks', function(e) {
if (e.target.tagName === 'LI' && $(e.target).attr('id') === 'navigation-tracks') {
that.toggleTrackList();
that.optionsController.saveOptionValues({trackListShow: $('#navigation-tracks').hasClass('open')});
}
});
$('body').on('click', '.changeTrackColor', function(e) {
var id = $(this).parent().parent().parent().parent().attr('track');
that.askChangeTrackColor(id);
});
// context menu event
$('body').on('click', '.contextChangeTrackColor', function(e) {
var id = parseInt($(this).parent().parent().attr('trackid'));
that.askChangeTrackColor(id);
that.map.closePopup();
});
$('body').on('change', '#trackcolorinput', function(e) {
that.okColor();
});
$('body').on('click', '.drawElevationButton', function(e) {
var id = $(this).attr('track');
that.showTrackElevation(id);
});
$('body').on('click', '.contextShowElevation', function(e) {
var id = parseInt($(this).parent().parent().attr('trackid'));
that.showTrackElevation(id);
that.map.closePopup();
});
$('body').on('click', '.showTrackElevation', function(e) {
var id = $(this).parent().parent().parent().parent().attr('track');
that.showTrackElevation(id);
});
// close elevation char button
this.closeElevationButton = L.easyButton({
position: 'bottomleft',
states: [{
stateName: 'no-importa',
icon: 'fa-times',
title: t('maps', 'Close elevation chart'),
onClick: function(btn, map) {
that.clearElevationControl();
}
}]
});
},
// expand or fold track list in sidebar
toggleTrackList: function() {
$('#navigation-tracks').toggleClass('open');
},
// toggle tracks general layer on map and save state in user options
toggleTracks: function() {
if (this.map.hasLayer(this.mainLayer)) {
this.map.removeLayer(this.mainLayer);
$('#navigation-tracks').removeClass('active');
$('#map').focus();
}
else {
if (!this.trackListLoaded) {
this.getTracks();
}
this.map.addLayer(this.mainLayer);
$('#navigation-tracks').addClass('active');
}
},
// add/remove markers from layers considering current filter values
updateFilterDisplay: function() {
var startFilter = this.timeFilterController.valueBegin;
var endFilter = this.timeFilterController.valueEnd;
var id, layer, i, date;
for (id in this.trackLayers) {
date = this.trackLayers[id].date;
// if it was not filtered, check if it should be removed
if (this.mapTrackLayers[id].hasLayer(this.trackLayers[id])) {
if (date && (date < startFilter || date > endFilter)) {
this.mapTrackLayers[id].removeLayer(this.trackLayers[id]);
}
}
// if it was filtered, check if it should be added
else {
if (date && (date >= startFilter && date <= endFilter)) {
this.mapTrackLayers[id].addLayer(this.trackLayers[id]);
}
}
}
},
updateMyFirstLastDates: function(updateSlider=false) {
if (!this.map.hasLayer(this.mainLayer)) {
this.firstDate = null;
this.lastDate = null;
}
else {
var id;
// we update dates only if nothing is currently loading
for (id in this.mapTrackLayers) {
if (this.mainLayer.hasLayer(this.mapTrackLayers[id]) && !this.trackLayers[id].loaded) {
return;
}
}
var initMinDate = Math.floor(Date.now() / 1000) + 1000000
var initMaxDate = 0;
var first = initMinDate;
var last = initMaxDate;
for (id in this.mapTrackLayers) {
if (this.mainLayer.hasLayer(this.mapTrackLayers[id]) && this.trackLayers[id].loaded && this.trackLayers[id].date) {
if (this.trackLayers[id].date < first) {
first = this.trackLayers[id].date;
}
if (this.trackLayers[id].date > last) {
last = this.trackLayers[id].date;
}
}
}
if (first !== initMinDate
&& last !== initMaxDate) {
this.firstDate = first;
this.lastDate = last;
}
else {
this.firstDate = null;
this.lastDate = null;
}
}
if (updateSlider) {
this.timeFilterController.updateSliderRangeFromController();
this.timeFilterController.setSliderToMaxInterval();
}
},
saveEnabledTracks: function(additionalIds=[]) {
var trackList = [];
var layer;
for (var id in this.mapTrackLayers) {
layer = this.mapTrackLayers[id];
if (this.mainLayer.hasLayer(layer)) {
trackList.push(id);
}
}
for (var i=0; i < additionalIds.length; i++) {
trackList.push(additionalIds[i]);
}
var trackStringList = trackList.join('|');
this.optionsController.saveOptionValues({enabledTracks: trackStringList});
// this is used when tracks are loaded again
this.optionsController.enabledTracks = trackList;
},
showAllTracks: function() {
if (!this.map.hasLayer(this.mainLayer)) {
this.toggleTracks();
}
for (var id in this.mapTrackLayers) {
if (!this.mainLayer.hasLayer(this.mapTrackLayers[id])) {
this.toggleTrack(id);
}
}
this.updateMyFirstLastDates(true);
},
hideAllTracks: function() {
for (var id in this.mapTrackLayers) {
if (this.mainLayer.hasLayer(this.mapTrackLayers[id])) {
this.toggleTrack(id);
}
}
this.updateMyFirstLastDates(true);
},
removeTrackMap: function(id) {
this.mainLayer.removeLayer(this.mapTrackLayers[id]);
this.mapTrackLayers[id].removeLayer(this.trackLayers[id]);
delete this.mapTrackLayers[id];
delete this.trackLayers[id];
delete this.trackColors[id];
delete this.trackDivIcon[id];
delete this.tracks[id];
$('style[track='+id+']').remove();
$('#track-list > li[track="'+id+'"]').fadeOut('slow', function() {
$(this).remove();
});
},
addTrackMap: function(track, show=false, pageLoad=false, zoom=false) {
// color
var color = track.color || (OCA.Theming ? OCA.Theming.color : '#0082c9');
this.trackColors[track.id] = color;
this.trackDivIcon[track.id] = L.divIcon({
iconAnchor: [12, 25],
className: 'trackWaypoint trackWaypoint-'+track.id,
html: ''
});
this.tracks[track.id] = track;
this.tracks[track.id].metadata = track.metadata === '' ? {} : $.parseJSON(track.metadata);
this.tracks[track.id].icon = L.divIcon(L.extend({
html: '
',
className: 'leaflet-marker-track track-marker track-marker-'+track.id
}, null, {
iconSize: [this.track_MARKER_VIEW_SIZE, this.track_MARKER_VIEW_SIZE],
iconAnchor: [this.track_MARKER_VIEW_SIZE / 2, this.track_MARKER_VIEW_SIZE]
}));
this.mapTrackLayers[track.id] = L.featureGroup();
this.trackLayers[track.id] = L.featureGroup();
this.trackLayers[track.id].loaded = false;
this.mapTrackLayers[track.id].addLayer(this.trackLayers[track.id]);
this.addMenuEntry(track, color);
// enable if in saved options or if it should be enabled for another reason
if (show || this.optionsController.enabledTracks.indexOf(track.id) !== -1) {
this.toggleTrack(track.id, false, pageLoad, zoom);
}
},
addMenuEntry: function(track, color) {
var name = track.file_name;
var path = track.file_path;
// side menu entry
var imgurl = generateUrl('/svg/core/categories/monitoring?color='+color.replace('#', ''));
var li = '