/*
* μlogger
*
* Copyright(C) 2019 Bartek Fabiszewski (www.fabiszewski.net)
*
* This is free software; you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
import * as gmApi from './mapapi/api_gmaps.js';
import * as olApi from './mapapi/api_openlayers.js';
import { config, lang } from './constants.js';
import uEvent from './event.js';
import { uLogger } from './ulogger.js';
import uUtils from './utils.js';
/**
* @typedef {Object} uMap.api
* @memberOf uMap
* @type {Object}
* @property {string} name
* @property {function(uBinder, HTMLElement)} init
* @property {function} cleanup
* @property {function(uTrack, boolean)} displayTrack
* @property {function} clearMap
* @property {function(number)} animateMarker
* @property {function} getBounds
* @property {function} zoomToExtent
* @property {function} zoomToBounds
* @property {function} updateSize
*/
/**
* @class uMap
* @property {number} loadTime
* @property {?Array} savedBounds
* @property {?(gmApi|olApi)} api
* @property {?HTMLElement} mapElement
*/
export default class uMap {
/**
* @param {uBinder} binder
*/
constructor(binder) {
binder.addEventListener(uEvent.API_CHANGE, this);
binder.addEventListener(uEvent.CHART_CLICKED, this);
binder.addEventListener(uEvent.TRACK_READY, this);
binder.addEventListener(uEvent.UI_READY, this);
this.loadTime = 0;
this.savedBounds = null;
this.api = null;
this.mapElement = null;
this.lastTrackId = null;
this._binder = binder;
this.track = null;
}
/**
* Dynamic change of map api
* @param {string=} apiName API name
*/
loadMapAPI(apiName) {
if (apiName) {
config.mapapi = apiName;
try {
this.savedBounds = this.api.getBounds();
} catch (e) {
this.savedBounds = null;
}
this.api.cleanup();
}
if (config.mapapi === 'gmaps') {
this.api = gmApi;
} else {
this.api = olApi;
}
this.waitAndInit();
}
/**
* Try to initialize map engine
*/
waitAndInit() {
// wait till main api loads
if (this.loadTime > 10000) {
this.loadTime = 0;
alert(uUtils.sprintf(lang.strings['apifailure'], config.mapapi));
return;
}
try {
this.api.init(this._binder, this.mapElement);
} catch (e) {
setTimeout(() => {
this.loadTime += 50;
this.waitAndInit();
}, 50);
return;
}
this.loadTime = 0;
if (this.savedBounds) {
this.api.zoomToBounds(this.savedBounds);
}
uLogger.trackList.onChange();
// save current api as default
uUtils.setCookie('api', config.mapapi, 30);
}
/**
*
* @param {uEvent} event
* @param {*=} args
*/
handleEvent(event, args) {
if (event.type === uEvent.TRACK_READY) {
/** @type {uTrack} */
const track = args;
this.api.clearMap();
const onlyReload = track.id !== this.lastTrackId;
this.api.displayTrack(track, onlyReload);
this.lastTrackId = track.id;
} else if (event.type === uEvent.UI_READY) {
/** @type {uUI} */
const ui = args;
this.mapElement = ui.map;
this.loadMapAPI();
} else if (event.type === uEvent.API_CHANGE) {
/** @type {string} */
const api = args;
this.loadMapAPI(api);
} else if (event.type === uEvent.CHART_CLICKED) {
/** @type {number} */
const id = args;
this.api.animateMarker(id);
}
}
}