Completed
Push — master ( 7ac5da...5cb984 )
by
unknown
06:39
created

js/script.js (6 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
/**
2
 * ownCloud - maps
3
 *
4
 * This file is licensed under the Affero General Public License version 3 or
5
 * later. See the COPYING file.
6
 *
7
 * @author Sander Brand <[email protected]>
8
 * @copyright Sander Brand 2014
9
 */
10
/** Testing
11
 */
12
13
Array.prototype.clean = function(deleteValue) {
14
	for (var i = 0; i < this.length; i++) {
15
		if (this[i] == deleteValue) {
16
			this.splice(i, 1);
17
			i--;
18
		}
19
	}
20
	return this;
21
};
22
Array.prototype.unique = function() {
23
	var unique = [];
24
	for (var i = 0; i < this.length; i++) {
25
		if (unique.indexOf(this[i]) == -1) {
26
			unique.push(this[i]);
27
		}
28
	}
29
	return unique;
30
};
31
(function($, OC) {
32
33
	var normalMarkerImg = OC.filePath('maps', 'css', 'leaflet/images/marker-icon.png');
34
	var normalMarkerIcon = L.icon({
35
		iconUrl : normalMarkerImg,
36
		iconSize : [31, 37],
37
		iconAnchor : [15, 37],
38
		popupAnchor : [0, -37]
39
	});
40
41
	var favMarkerImg = OC.filePath('maps', 'img', 'icons/favMarker.png');
42
	var favMarkerIcon = L.icon({
43
		iconUrl : favMarkerImg,
44
		iconSize : [31, 37],
45
		iconAnchor : [15, 37],
46
		popupAnchor : [0, -37]
47
	});
48
49
	function addGeocodeMarker(latlng) {
50
		Maps.droppedPin = new L.marker(latlng);
51
		var decoder = L.Control.Geocoder.nominatim();
52
		decoder.reverse(latlng, 67108864, function(results) {
53
			var result = results[0];
54
			setTimeout(function() {
55
				var knownFields = ['country', 'country_code', 'postcode', 'residential', 'road', 'state', 'suburb', 'town', 'house_number'];
56
				var popupHtml = '';
57
				$.each(result.originalObject.address, function(k, v) {
58
					if ($.inArray(k, knownFields) == -1) {
59
						var prefix = k;
60
						popupHtml += v + '<br />';
61
					}
62
				})
63
				var houseNo = (result.originalObject.address.house_number) ? result.originalObject.address.house_number : '';
64
				popupHtml += result.originalObject.address.road + ' ' + houseNo + '<br />';
65
				popupHtml += result.originalObject.address.town + ', ' + result.originalObject.address.state + ', ' + result.originalObject.address.country;
66
				toolKit.addMarker(Maps.droppedPin, popupHtml, true);
67
			}, 50);
68
69
		})
70
	}
71
72
	$.fn.clickToggle = function(func1, func2) {
73
		var funcs = [func1, func2];
74
		this.data('toggleclicked', 0);
75
		this.click(function() {
76
			var data = $(this).data();
77
			var tc = data.toggleclicked;
78
			$.proxy(funcs[tc], this)();
79
			data.toggleclicked = (tc + 1) % 2;
80
		});
81
		return this;
82
	};
83
84
	// initialize map when page ready
85
	$(document).ready(function() {
86
		marker = null;
87
		circle = null;
88
		firstRun = true;
89
90
		var attribution = '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors, <a href="http://creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>';
91
92
		var mapQuest = L.tileLayer('http://otile{s}.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.png', {
93
			attribution : attribution,
94
			subdomains : "1234"
95
		})
96
		/*	var mapbox = L.tileLayer('https://a.tiles.mapbox.com/v3/liedman.h9ekn0f1/{z}/{x}/{y}.png', {
97
		 attribution : attribution + ' Tiles <a href="https://www.mapbox.com/about/maps/">MapBox</a>'
98
		 })
99
		 var blackAndWhite = L.tileLayer('http://{s}.www.toolserver.org/tiles/bw-mapnik/{z}/{x}/{y}.png', {
100
		 attribution : attribution
101
		 })
102
103
		 var airial = L.tileLayer('http://server.arcgisonline.com/ArcGIS/' + 'rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
104
		 attribution : attribution + ' Tiles © Esri',
105
		 subdomains : "1234"
106
		 })*/
107
108
		/*var clouds = L.tileLayer('http://{s}.tile.openweathermap.org/map/clouds/{z}/{x}/{y}.png', {
109
		 attribution : 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
110
		 opacity : 0.5
111
		 })
112
		 var wind = L.tileLayer('http://{s}.tile.openweathermap.org/map/wind/{z}/{x}/{y}.png', {
113
		 attribution : 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
114
		 opacity : 0.5
115
		 })
116
		 var temperature = L.tileLayer('http://{s}.tile.openweathermap.org/map/temp/{z}/{x}/{y}.png', {
117
		 attribution : 'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',
118
		 opacity : 0.5
119
		 })
120
121
		 var seamarks = L.tileLayer('http://tiles.openseamap.org/seamark/{z}/{x}/{y}.png', {
122
		 attribution : 'Map data &copy; <a href="http://openweathermap.org">OpenSeaMap</a>',
123
		 opacity : 1.0
124
		 })
125
126
		 var none = L.tileLayer('http://{s}.tile.openweathermap.org/map/temp/{z}/{x}/{y}.png', {
127
		 attribution : '',
128
		 opacity : 0.0
129
		 })*/
130
131
		var oldPosition = $.jStorage.get('location', {
132
			lat : 21.303210151521565,
133
			lng : 6.15234375
134
		});
135
		var oldZoom = $.jStorage.get('zoom', 3);
136
137
		map = L.map('map', {
138
			center : new L.LatLng(oldPosition.lat, oldPosition.lng),
139
			zoom : oldZoom,
140
			zoomControl : false,
141
			layers : [mapQuest]
142
		});
143
		map.options.minZoom = 3;
144
		var hash = new L.Hash(map);
145
		/*var baseMaps = {
146
		 "MapBox" : mapbox,
147
		 "Mapnik" : mapnik,
148
		 "Black and White" : blackAndWhite,
149
		 "Airial" : airial
150
		 };*/
151
152
		//map.addControl(new L.Control.Compass());
153
		/*map.addControl(new L.Control.Zoom({
154
			position: 'bottomright'
155
		}));*/
156
		map.addControl(new L.Control.Gps({
157
			minZoom : 14,
158
			autoActive: 1,
159
			style : {
160
				radius : 16, //marker circle style
161
				weight : 3,
162
				color : '#0A00FF',
163
				fill : true
164
			},
165
			position : 'topleft',
166
		}));
167
		$('.leaflet-control-layers-overlays').removeProp('multiple');
168
		map.on('popupopen', function(e) {
169
			currentMarker = e.popup._source;
170
		});
171
		routing = L.Routing.control({
172
			waypoints : [],
173
			geocoder : L.Control.Geocoder.nominatim(),
174
			plan : L.Routing.plan(null, {
175
				waypointIcon : function(i) {
176
					return new L.Icon.Label.Default({
177
						labelText : String.fromCharCode(65 + i)
178
					});
179
				}
180
			})
181
		}).addTo(map);
182
		$(".leaflet-routing-geocoders").appendTo("#searchContainer");
183
		$(".leaflet-routing-container").appendTo("#searchContainer");
184
		$('.geocoder-0').attr('completiontype', 'local');
185
186
		// properly style as input field
187
		//$('#searchContainer').find('input').attr('type', 'text');
188
189
		map.on('mousedown', function(e) {
190
			Maps.mouseDowntime = new Date().getTime();
191
		});
192
193
		map.on('mouseup', function(e) {
194
			if (e.originalEvent.target.className !== 'leaflet-tile leaflet-tile-loaded' && e.originalEvent.target.nodeName != 'svg')
195
				return;
196
197
			var curTime = new Date().getTime();
198
			if (Maps.droppedPin) {
199
				map.removeLayer(Maps.droppedPin);
200
				Maps.droppedPin = false;
201
				if ($('.geocoder-0').attr('completiontype') === 'local' && ($('.geocoder-0').val() == '')) {
202
					$('.geocoder-0').val('');
203
				}
204
			}
205
			if (/*(curTime - Maps.mouseDowntime) > 200 && */Maps.dragging === false) {//200 = 2 seconds
206
				addGeocodeMarker(e.latlng);
207
			}
208
209
		});
210
211
		map.on("dragstart", function() {
212
			Maps.dragging = true;
213
		})
214
		map.on("dragend zoomend", function(e) {
215
			Maps.saveCurrentLocation(e);
216
			Maps.dragging = false;
217
			var searchInput = $('.geocoder-0')
218
			if (searchInput.attr('completiontype') == 'local' && searchInput.val() != '') {
219
				var data = {
220
					search : searchInput.val(),
221
					bbox : map.getBounds().toBBoxString()
222
				}
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
223
				clearTimeout(searchTimeout);
224
				searchTimeout = setTimeout(function() {
225
					console.log('Get new results');
226
					mapSearch.getSearchResults(data, mapSearch.showResultsOnMap);
227
				}, 500);
228
			}
229
		})
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
230
231
		$(document).on('click', '.toggle-children', function(e) {
232
			var subCat = $(this).parent().find('ul');
233
			if (subCat.is(":visible")) {
234
				subCat.slideUp();
235
			} else {
236
				subCat.removeClass('hidden');
237
				subCat.slideDown();
238
			}
239
		})
240
		var poiCats = ['shop'];
241
		$.each(poiCats, function(i, cat) {
242
			poiTypes[cat] = poiTypes[cat].sort()
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
243
			iconHTML = '';
244
			$.each(poiTypes[cat], function(i, layer) {
245
				if (this != "") {
0 ignored issues
show
It is recommended to use !== to compare with .

Generally, it is recommended to use strict comparison whenever possible and not to rely on the weaker type-juggling comparison operator.

Read more about comparison operations.

Loading history...
246
					iconHTML = '';
247
					var icon = toolKit.getPoiIcon(this);
248
					if (icon) {
249
						$('#' + cat + '-items').append('<li><a class="subLayer" data-layerGroup="' + cat + '" data-layerValue="' + this + '">' + iconHTML + this + '</a></li>')
0 ignored issues
show
There should be a semicolon.

Requirement of semicolons purely is a coding style issue since JavaScript has specific rules about semicolons which are followed by all browsers.

Further Readings:

Loading history...
250
					}
251
				}
252
			})
253
		});
254
		function convertLatLon(latD, lonD, latDir, lonDir){
255
			var lon = lonD[0] + lonD[1]/60 + lonD[2]/(60*60);
256
			var lat = latD[0] + latD[1]/60 + latD[2]/(60*60);
257
			if (latDir == "S") {
258
				lat = lat * -1;
259
			}
260
			if(lonDir == "W"){
261
				lon = lon * -1;
262
			}
263
			return {
264
				lat: lat,
265
				lon: lon
266
			};
267
		}
268
		$('.photoLayer').clickToggle(function() {
269
			OC.dialogs.filepicker("Select your photo", function addJpegFile(path){
270
				for(i=0; i<path.length; i++){
271
					var p = path[i];
272
					if(p.indexOf('/') === 0) p = p.substr(1);
273
					var separator = p.lastIndexOf('/');
274
					var dir = p.substr(0, separator);
275
					var file = p.substr(separator + 1);
276
					var picUrl = OC.generateUrl('apps/files/ajax/download.php?dir={dir}&files={file}', {
277
						dir: dir,
278
						file: file
279
					});
280
					new ImageInfo(
281
						picUrl,
282
						(function (element){
283
							return function (imageinfo){
284
								var exif = imageinfo.getAllFields().exif;
285
								var latD = exif.GPSLatitude;
286
								var lonD = exif.GPSLongitude;
287
								var latDir = exif.GPSLatitudeRef;
288
								var lonDir = exif.GPSLongitudeRef;
289
								var latlon = convertLatLon(latD, lonD, latDir, lonDir);
290
								var photoIcon = L.icon({
291
									iconUrl: picUrl,
292
									iconSize : [42, 49],
293
									iconAnchor : [21, 49],
294
									popupAnchor : [0, -49],
295
									className : 'photo-marker'
296
								});
297
298
								var markerHTML = '<h2>' + file + "</h2>";
299
								/*markerHTML += '<br />Latitude: ' + latlon.lat + " " + latDir;
300
								markerHTML += '<br />Longitude: ' + latlon.lon + " " + lonDir;
301
								markerHTML += '<br />Altitude: ' + exif.GPSAltitude + "m";*/
302
								var marker = L.marker([latlon.lat, latlon.lon], {
303
									icon : photoIcon
304
								});
305
								toolKit.addMarker(marker, markerHTML);
306
							};
307
						})(this)
308
					).readFileData();
309
				}
310
			}, true, ["image/jpeg", "image/png", "image/gif"], true);
311
		}, function() {
312
			//TODO
313
		});
314
315
		/* Favorites layer: Show by default, remember visibility */
316
		$('.favoriteLayer').click(function() {
317
			if($.jStorage.get('favorites')) {
318
				favorites.hide();
319
				$.jStorage.set('favorites', false);
320
				$('#favoriteMenu').removeClass('active').addClass('icon-star').removeClass('icon-starred');
321
			} else {
322
				favorites.show();
323
				$.jStorage.set('favorites', true);
324
				$('#favoriteMenu').addClass('active').addClass('icon-starred').removeClass('icon-star');
325
			}
326
		});
327
		if($.jStorage.get('favorites') === null) {
328
			favorites.show();
329
			$.jStorage.set('favorites', true);
330
			$('#favoriteMenu').addClass('active').addClass('icon-starred').removeClass('icon-star');
331
		}
332
		if($.jStorage.get('favorites')) {
333
			favorites.show();
334
			$('#favoriteMenu').addClass('active').addClass('icon-starred').removeClass('icon-star');
335
		} else {
336
			favorites.hide();
337
		}
338
339
340
		$('.contactLayer').clickToggle(function() {
341
			Maps.loadAdressBooks()
342
		}, function() {
343
			favorites.hide()
0 ignored issues
show
There were too many errors found in this file; checking aborted after 24%.

If JSHint finds too many errors in a file, it aborts checking altogether because it suspects a configuration issue.

Further Reading:

Loading history...
344
		});
345
		$(document).on('click', '.subLayer', function() {
346
			var layerGroup = $(this).attr('data-layerGroup');
347
			var layerValue = $(this).attr('data-layerValue');
348
			var isVisible = $(this).find('i').length;
349
350
			if (isVisible == 1) {
351
				$('.' + layerValue).css({
352
					'visibility' : 'hidden'
353
				})
354
				$(this).find('i').remove();
355
				Maps.updateLayers(false, false);
356
			} else {
357
				$('.' + layerValue).css({
358
					'visibility' : 'visible'
359
				})
360
				$(this).append('<i class="icon-toggle fright micon activeLayer"></i>');
361
				//if($('.'+layerValue).length==0){
362
				Maps.updateLayers(layerGroup, layerValue);
363
				/*} else{
364
				 Maps.updateLayers(false,false);
365
				 }*/
366
367
			}
368
		});
369
370
		$(document).on('click', '.device', function() {
371
			var isVisible = $(this).find('i').length;
372
			var dId = $(this).attr('data-deviceId')
373
			if (isVisible == 1) {
374
				$(this).find('i').remove();
375
				Maps.clearDevicePositions();
376
				Maps.clearDevicePosistionHistory(dId);
377
				var index = Maps.activeDevices.indexOf(dId);
378
				Maps.activeDevices.splice(index, 1);
379
				Maps.loadDevicesLastPosition();
380
			} else {
381
				Maps.activeDevices.push(dId);
382
				Maps.loadDevicesLastPosition();
383
				$(this).append('<i class="icon-toggle fright micon"></i>');
384
			}
385
		});
386
387
		$(document).on('click', '.keepDeviceCentered', function(e) {
388
			var isVisible = $(this).parent().find('i').length;
389
			var dId = $(this).parent().attr('data-deviceId')
390
			e.stopPropagation()
391
			if ($(this).hasClass('tracOn')) {
392
				$(this).removeClass('tracOn');
393
				Maps.traceDevice = null;
394
			} else {
395
				$('.keepDeviceCentered').removeClass('tracOn');
396
				$(this).addClass('tracOn');
397
				if (!isVisible) {
398
					Maps.activeDevices.push(dId);
399
					Maps.traceDevice = dId;
400
					Maps.loadDevicesLastPosition();
401
					$(this).parent().append('<i class="icon-toggle fright micon"></i>');
402
				} else {
403
					Maps.traceDevice = dId;
404
					Maps.loadDevicesLastPosition();
405
				}
406
			}
407
408
		});
409
410
		/**
411
		 * Setup datepickers
412
		 */
413
		$('.datetime').datetimepicker({
414
			dateFormat : 'dd-mm-yy',
415
			minDate : -900
416
		});
417
418
		$(document).on('click', '.deviceHistory', function(e) {
419
			var isVisible = $(this).parent().find('i').length;
420
			var dId = $(this).parent().attr('data-deviceId');
421
			var _this = this;
422
			e.stopPropagation();
423
			if (!isVisible) {
424
				$(".datetime").datepicker("disable");
425
				$('#showHistoryPopup').dialog({
426
					open : function() {
427
						$(".datetime").datepicker("enable");
428
						var currentDate = new Date();
429
						var month = ((currentDate.getMonth() * 1 + 1) < 10) ? '0' + (currentDate.getMonth() * 1 + 1) : (currentDate.getMonth() * 1 + 1);
430
						$('#deviceHistory [name="startDate"]').val(currentDate.getDate() + '-' + month + '-' + currentDate.getFullYear() + ' 00:00');
431
					},
432
					buttons : {
433
						"Cancel" : function() {
434
							$(this).dialog('destroy');
435
						},
436
						"Ok" : function() {
437
							var startDate = $('#deviceHistory [name="startDate"]').val();
438
							var endDate = $('#deviceHistory [name="endDate"]').val();
439
							var keepCenter = $('#deviceHistory [name="keepCenter"]').is(':checked');
440
							Maps.loadDevicePosistionHistory(dId, keepCenter, startDate, endDate);
441
							$(_this).parent().append('<i class="icon-toggle fright micon"></i>');
442
							$(this).dialog('destroy');
443
						}
444
					}
445
				});
446
			} else {
447
				Maps.clearDevicePosistionHistory(dId);
448
				$(this).parent().find('i').remove();
449
			}
450
451
		});
452
453
		/**
454
		 * Custom search function
455
		 */
456
		/*    searchItems = []*/
457
		searchTimeout = 0;
458
459
		$(document).on('keyup blur', '.geocoder-0', function(e) {
460
			if ($(this).attr('completiontype') != 'local')
461
				return;
462
463
			var data = {
464
				search : $(this).val(),
465
				bbox : map.getBounds().toBBoxString()
466
			}
467
			clearTimeout(searchTimeout);
468
			if ($(this).val() == '') {
469
				mapSearch.clearSearchResults();
470
				mapSearch._ids = [];
471
			}
472
			if (e.keyCode != 13) {
473
				searchTimeout = setTimeout(function() {
474
475
				}, 1000)
476
			} else {
477
				mapSearch.clearSearchResults();
478
				mapSearch._ids = [];
479
				mapSearch.getSearchResults(data, mapSearch.showResultsOnMap);
480
			}
481
482
		});
483
		/**
484
		 * setDestination on click
485
		 */
486
		map.locate({
487
			setView : false,
488
			watch : false
489
		})
490
		map.on('locationfound', function doRouteCalc(e) {
491
			currentlocation = [e.latitude, e.longitude];
492
493
		})
494
		$(document).on('click', '.setDestination', function() {
495
496
			var latlng = $(this).attr('data-latlng');
497
			routing.setWaypoints([])
498
			var end = latlng.split(',');
499
			end[0] = end[0] * 1;
500
			end[1] = end[1] * 1;
501
			//map.removeLayer(routing);
502
503
			routing.setWaypoints([L.latLng(currentlocation[0], currentlocation[1]), L.latLng(end[0], end[1])]);
504
505
			$('.geocoder-1').show();
506
			map.closePopup();
507
		});
508
509
		/**
510
		 * Clear route
511
		 */
512
		$(document).on('click', '.clearroute', function() {
513
			routing.setWaypoints([]);
514
		});
515
516
	});
517
	// End document ready
518
	function onLocationFound(e) {
519
		var radius = e.accuracy / 2;
520
		if (marker != null) {
521
			map.removeLayer(marker);
522
		}
523
		if (circle != null) {
524
			map.removeLayer(circle);
525
		}
526
527
		marker = L.marker(e.latlng).addTo(map);
528
		//.bindPopup("You are within " + radius + " meters from this point").openPopup();
529
		if (radius < 5000) {
530
			circle = L.circle(e.latlng, radius).addTo(map);
531
		}
532
533
		if (firstRun) {
534
			map.panTo(e.latlng);
535
			var maxZoom = 16;
536
			map.setZoom(14);
537
			firstRun = false;
538
		}
539
	}
540
541
	mapSearch = {
542
		searchItems : [],
543
		_ids : [],
544
		getSearchResults : function(data, callback) {
545
			$.getJSON(OC.generateUrl('/apps/maps/search'), data, function renderSearchResults(r) {
546
				callback(r)
547
			})
548
		},
549
550
		showResultsOnMap : function(r) {
551
			if (map.getZoom() <= 14) {
552
				var zoomMSG = '<div class="leaflet-control-minZoomIndecator leaflet-control" style="border-radius: 3px; padding: 3px 7px; display: block; background: rgba(255, 255, 255, 0.701961);">Results might be limited due current zoom, zoom in to get more</div>'
553
				$('.leaflet-top.leaflet-middle').html(zoomMSG);
554
			} else {
555
				$('.leaflet-control-minZoomIndecator ').remove();
556
			}
557
			console.log(r)
558
559
			$.each(r.contacts, function() {
560
				var contact = this;
561
				if ($.inArray(contact.id, mapSearch._ids) != -1) {
562
					return;
563
				}
564
				if (contact.location) {
565
					if (contact.thumbnail) {
566
						var imagePath = contact.thumbnail;
567
						var iconImage = L.icon({
568
							iconUrl : imagePath,
569
							iconSize : [42, 49],
570
							iconAnchor : [21, 49],
571
							popupAnchor : [0, -49],
572
							className : 'contact-icon'
573
						});
574
					} else {
575
						var imagePath = OC.filePath('maps', 'img', 'icons/marker_anonPerson.png');
576
						var iconImage = L.icon({
577
							iconUrl : imagePath,
578
							iconSize : [42, 49],
579
							iconAnchor : [21, 49],
580
							popupAnchor : [0, -49]
581
						});
582
					}
583
584
					for(i=0; i<contact.location.length; i++){
585
						if(contact.location[i] == null) continue;
586
						var markerHTML = '<h2>' + contact.FN + "</h2>";
587
						var street = [contact.ADR[i][0], contact.ADR[i][1], contact.ADR[i][2]].clean('').join('<br />');
588
						var city = (contact.ADR[i][3]) ? contact.ADR[i][3] : '';
589
						markerHTML += '<br />' + street + ", " + city;
590
						markerHTML += (contact.TEL) ? '<br />Tel: ' + escape(contact.TEL[0]) : '';
591
						var marker = L.marker([contact.location[i].lat * 1, contact.location[i].lon * 1], {
592
							icon : iconImage
593
						});
594
						toolKit.addMarker(marker, markerHTML)
595
						mapSearch.searchItems.push(marker);
596
					}
597
				}
598
				mapSearch._ids.push(contact.id)
599
			})
600
601
			$.each(r.addresses, function() {
602
				if ($.inArray(this.place_id, mapSearch._ids) != -1) {
603
					return;
604
				}
605
				var markerHTML = this.display_name.replace(',', '<br />');
606
				var marker = new L.marker([this.lat * 1, this.lon * 1]);
607
				toolKit.addMarker(marker, markerHTML)
608
				mapSearch.searchItems.push(marker);
609
				mapSearch._ids.push(this.place_id)
610
611
			});
612
613
			$.each(r.nodes, function() {
614
				if ($.inArray(this.place_id, mapSearch._ids) != -1) {
615
					return;
616
				}
617
				var iconImage = toolKit.getPoiIcon(this.type)
618
				var markerHTML = this.display_name.replace(',', '<br />');
619
				if (iconImage) {
620
					var marker = L.marker([this.lat * 1, this.lon * 1], {
621
						icon : iconImage
622
					});
623
				} else {
624
					var marker = new L.marker([this.lat * 1, this.lon * 1]);
625
				}
626
				toolKit.addMarker(marker, markerHTML)
627
				mapSearch.searchItems.push(marker);
628
				mapSearch._ids.push(this.place_id)
629
630
			});
631
632
		},
633
634
		clearSearchResults : function() {
635
			for ( i = 0; i < mapSearch.searchItems.length; i++) {
636
				map.removeLayer(mapSearch.searchItems[i]);
637
			}
638
			mapSearch.searchItems = []
639
		}
640
	}
641
642
	Maps = {
643
		addressbooks : [],
644
		tempArr : [],
645
		tempCounter : 0,
646
		tempTotal : 0,
647
		activeLayers : [],
648
		mouseDowntime : 0,
649
		droppedPin : {},
650
		dragging : false,
651
		activeDevices : [],
652
		deviceMarkers : [],
653
		trackMarkers : {},
654
		trackingTimer : {},
655
		deviceTimer : 0,
656
		historyTrack : {},
657
		traceDevice : null,
658
		arrowHead : {},
659
		loadAdressBooks : function() {
660
			if($('#contactMenu').length == 0) return;
661
			Maps.addressbooks = [];
662
			$.get(OC.generateUrl('apps/contacts/addressbooks/'), function(r) {
663
				$.each(r.addressbooks, function() {
664
					var book = {
665
						'id' : this.id,
666
						'backend' : this.backend
667
					}
668
					Maps.addressbooks.push(book);
669
				})
670
				Maps.loadContacts();
671
			})
672
		},
673
		removePosistionHistory : function(deviceId) {
674
			for ( i = 0; i < Maps.trackMarkers[deviceId].length; i++) {
675
				map.removeLayer(Maps.trackMarkers[deviceId][i]);
676
			}
677
			if (Maps.historyTrack[deviceId]) {
678
				map.removeLayer(Maps.historyTrack[deviceId]);
679
				map.removeLayer(Maps.arrowHead[deviceId]);
680
			}
681
			clearTimeout(Maps.trackingTimer[deviceId]);
682
		},
683
684
		loadDevicePosistionHistory : function(deviceId, trackCurrentPosition, from, till) {
685
			var trackCurrentPosition = (trackCurrentPosition) ? true : false;
686
			var from = (from) ? from : '';
687
			var till = (till) ? till : '';
688
			var data = {
689
				devices : deviceId,
690
				'from' : from,
691
				'till' : till
692
			};
693
694
			if (!Maps.trackMarkers[deviceId]) {
695
				Maps.trackMarkers[deviceId] = [];
696
				Maps.arrowHead[deviceId] = [];
697
				Maps.historyTrack[deviceId] = [];
698
				Maps.trackingTimer[deviceId] = [];
699
			}
700
701
			clearTimeout(Maps.trackingTimer);
702
			$.get(OC.generateUrl('/apps/maps/api/1.0/location/loadLocations'), data, function(response) {
703
				var locations = response[deviceId];
704
				var points = [];
705
				var bounds = []
706
				var lastPosition = locations[0];
707
				for ( i = 0; i < Maps.trackMarkers[deviceId].length; i++) {
708
					map.removeLayer(Maps.trackMarkers[deviceId][i]);
709
				}
710
				if (Maps.historyTrack[deviceId]) {
711
					map.removeLayer(Maps.historyTrack[deviceId]);
712
					map.removeLayer(Maps.arrowHead[deviceId]);
713
				}
714
				if (locations.length === 0) {
715
					OC.Notification.showTimeout('No results');
716
					return;
717
				}
718
				var lastPObject = L.latLng(lastPosition.lat, lastPosition.lng) //distanceTo
719
				$.each(locations, function(k, location) {
720
					var markerHTML = '';
721
					var marker = new L.marker([location.lat * 1, location.lng * 1]);
722
					var point = new L.LatLng(location.lat * 1, location.lng * 1);
723
					//bounds.push(marker.getBounds());
724
					var markerHTML = location.name + '<br />';
725
					markerHTML += 'Lat: ' + location.lat + ' Lon: ' + location.lng + '<br />';
726
					markerHTML += 'Speed: ' + location.speed + '<br />'
727
					markerHTML += 'Time: ' + new Date(location.timestamp * 1000).toLocaleString("nl-NL")
728
					var marker = new L.marker([location.lat * 1, location.lng * 1]);
729
					if(Math.round(lastPObject.distanceTo(point))> 15){ //If markers are more then 15m between each other
730
						console.log('Distance from last point: ',Math.round(lastPObject.distanceTo(point)));
731
						Maps.trackMarkers[location.deviceId].push(marker);
732
						toolKit.addMarker(marker, markerHTML);
733
						points.push(point);
734
					}
735
					lastPObject = point;
736
				});
737
				points.reverse();
738
				Maps.historyTrack[deviceId] = new L.Polyline(points, {
739
					color : 'green',
740
					weight : 6,
741
					opacity : 0.5,
742
					smoothFactor : 1
743
744
				});
745
				Maps.historyTrack[deviceId].addTo(map);
746
				Maps.arrowHead[deviceId] = L.polylineDecorator(Maps.historyTrack[deviceId]).addTo(map);
747
				Maps.arrowHead[deviceId].setPatterns([{
748
					offset : '0%',
749
					repeat : 100,
750
					symbol : L.Symbol.arrowHead({
751
						pixelSize : 25,
752
						polygon : false,
753
						pathOptions : {
754
							stroke : true
755
						}
756
					})
757
				}]);
758
				Maps.trackingTimer[deviceId] = setTimeout(function() {
759
					Maps.loadDevicePosistionHistory(deviceId, trackCurrentPosition, from, till);
760
				}, 60000)
761
				if (trackCurrentPosition && lastPosition.deviceId == Maps.traceDevice) {
762
					map.panTo(new L.LatLng(lastPosition.lat, lastPosition.lng));
763
				}
764
			});
765
		},
766
		clearDevicePosistionHistory : function(deviceId) {
767
			for ( i = 0; i < Maps.trackMarkers[deviceId].length; i++) {
768
				map.removeLayer(Maps.trackMarkers[deviceId][i]);
769
			}
770
			map.removeLayer(Maps.historyTrack[deviceId]);
771
			map.removeLayer(Maps.arrowHead[deviceId]);
772
			clearTimeout(Maps.trackingTimer[deviceId]);
773
			Maps.trackMarkers[deviceId] = [];
774
		},
775
		loadDevicesLastPosition : function() {
776
			var data = {
777
				devices : Maps.activeDevices.join(','),
778
				limit : 1
779
			};
780
			clearTimeout(Maps.deviceTimer);
781
			if (Maps.activeDevices.length > 0) {
782
				$.get(OC.generateUrl('/apps/maps/api/1.0/location/loadLocations'), data, function(response) {
783
					Maps.clearDevicePositions();
784
					$.each(response, function(deviceId, location) {
785
						console.log(deviceId, location);
786
						var device = location[0];
787
						if (!device)
788
							return;
789
790
						var markerHTML = device.name + '<br />';
791
						markerHTML += 'Lat: ' + device.lat + ' Lon: ' + device.lng + '<br />';
792
						markerHTML += 'Speed: ' + device.speed + '<br />'
793
						markerHTML += 'Time: ' + new Date(device.timestamp * 1000).toLocaleString("nl-NL")
794
						var marker = new L.marker([device.lat * 1, device.lng * 1]);
795
						toolKit.addMarker(marker, markerHTML)
796
						Maps.deviceMarkers.push(marker);
797
						if (device.deviceId == Maps.traceDevice) {
798
							map.panTo(new L.LatLng(device.lat * 1, device.lng * 1));
799
						}
800
					});
801
					Maps.deviceTimer = setTimeout(Maps.loadDevicesLastPosition, 60000);
802
				});
803
			}
804
		},
805
		clearDevicePositions : function() {
806
			for ( i = 0; i < Maps.deviceMarkers.length; i++) {
807
				map.removeLayer(Maps.deviceMarkers[i]);
808
			}
809
			Maps.deviceMarkers = [];
810
		},
811
812
		loadContacts : function() {
813
			Maps.tempArr = [];
814
			Maps.tempTotal = 0;
815
			Maps.tempCounter = 0;
816
			$.each(Maps.addressbooks, function(ai) {
817
				$.get(OC.generateUrl('/apps/contacts/addressbook/' + this.backend + '/' + this.id + '/contacts'), function(r) {
818
					$.each(r.contacts, function(ci) {
819
						Maps.tempArr.push(this);
820
						if (ai == Maps.addressbooks.length - 1 && ci == r.contacts.length - 1) {
821
							Maps.getContactPositionData();
822
							Maps.tempTotal = Maps.tempArr.length;
823
							$('#loadingContacts').show();
824
						}
825
					});
826
				});
827
			});
828
		},
829
		getContactPositionData : function() {
830
831
			if (Maps.tempArr.length > 0) {
832
				temp = Maps.tempArr.pop();
833
				var contact = toolKit.vcardToObject(temp);
834
				toolKit.adresLookup(contact.adr, function(d) {
835
					var curperson = $.extend({}, d, contact);
836
					try {
837
						toolKit.addFavContactMarker(curperson);
838
					} catch(e) {
839
840
					}
841
					var total = Maps.tempTotal;
842
					var index = Maps.tempCounter
843
					var percent = Math.round((index / total * 100) * 100) / 100;
844
					toolKit.setProgress(percent);
845
					$('#cCounter').text(index + 1 + ' of ' + (total * 1 + 1));
846
					Maps.tempCounter++;
847
					if (index == total)
848
						$('#loadingContacts').hide()
849
					Maps.getContactPositionData();
850
				})
851
			}
852
		},
853
854
		saveCurrentLocation : function(e) {
855
			var center = map.getBounds().getCenter();
856
			var location = {
857
				lat : center.lat,
858
				lng : center.lng
859
			};
860
			$.jStorage.set('location', location)
861
			$.jStorage.set('zoom', e.target._zoom)
862
		},
863
864
		showContact : function(data) {
865
866
		},
867
868
		updateLayers : function(group, layer) {
869
			//OverPassAPI overlay
870
			//k:amenity  v:postbox
871
			var overPassQ = '';
872
			groupArr = []
873
			$('.activeLayer').each(function() {
874
				var parent = $(this).parent();
875
				var layerGroup = parent.attr('data-layerGroup');
876
				var layerValue = parent.attr('data-layerValue');
877
				overPassQ += 'node(BBOX)[' + layerGroup + '=' + layerValue + '];out;'
878
				groupArr.push(layerGroup);
879
			})
880
			if (!$('body').data('POIactive')) {
881
				Maps.activeLayers = new L.OverPassLayer({
882
					minzoom : 14,
883
					//query : OC.generateUrl('apps/maps/router?url=http://overpass-api.de/api/interpreter?data=[out:json];node(BBOX)[' + group + '='+layer+'];out;'),
884
					query : OC.generateUrl('apps/maps/router?url=(SERVERAPI)interpreter?data=[out:json];' + overPassQ),
885
					callback : function createMaker(data) {
886
						for ( i = 0; i < data.elements.length; i++) {
887
							e = data.elements[i];
888
							if (e.id in this.instance._ids) {
889
								return;
890
							}
891
							this.instance._ids[e.id] = true;
892
							var pos = new L.LatLng(e.lat, e.lon);
893
							var popup = this.instance._poiInfo(e.tags, e.id);
894
							var color = e.tags.collection_times ? 'green' : 'red';
895
							var curgroup = null;
896
897
							$.each(groupArr, function() {
898
								if (e.tags[this]) {
899
									curgroup = this;
900
								}
901
							})
902
							var icon = e.tags[curgroup].split(';');
903
							icon[0] = icon[0].toLowerCase();
904
							var marker = false;
905
							if (icon[0].indexOf(',') != -1) {
906
								icon = icon[0].split(',');
907
							}
908
							if (icon[0] != 'yes') {
909
								marker = toolKit.getPoiIcon(icon[0])
910
								if (marker) {
911
									var marker = L.marker(pos, {
912
										icon : marker,
913
									}).bindPopup(popup);
914
									toolKit.addMarker(marker, popup)
915
									//this.instance.addLayer(marker);
916
								}
917
							}
918
919
						}
920
						/*tmpTypes = tmpTypes.unique().clean('');
921
						 tmpHTML = ''
922
						 $.each(tmpTypes, function() {
923
						 isVisible = $.inArray(group + '-' + this, Maps.hiddenPOITypes);
924
						 vIcon = (isVisible == -1) ? '<i class="icon-toggle fright micon"></i>' : ''
925
						 tmpHTML += '<li><a class="subLayer" data-subLayer="' + group + '-' + this + '">' + this + vIcon + '</a><li>'
926
						 })
927
						 console.log(tmpTypes);
928
						 $('#' + group + '-items').html(tmpHTML)
929
						 $('#' + group + '-items').show();*/
930
					},
931
				});
932
				map.addLayer(Maps.activeLayers);
933
				$('body').data('POIactive', true);
934
			} else {
935
				Maps.activeLayers.options.query = OC.generateUrl('apps/maps/router?url=(SERVERAPI)interpreter?data=[out:json];' + overPassQ);
936
				if (group && layer) {
937
					Maps.activeLayers.onMoveEnd();
938
				}
939
			}
940
		},
941
		removeLayer : function(layer) {
942
			//map.removeLayer(Maps.activeLayers[layer])
943
		}
944
	}
945
	toolKit = {
946
		addMarker : function(marker, markerHTML, openPopup, fav) {
947
			fav = fav || false;
948
			var openPopup = (openPopup) ? true : false;
949
			var latlng = marker._latlng.lat + ',' + marker._latlng.lng;
950
			var markerHTML2 = '<div class="';
951
			if(fav) {
952
				markerHTML2 += 'icon-starred removeFromFav" fav-id="' + marker.options.id + '"';
953
				var editButton = document.createElement('button');
954
				editButton.className = 'icon-rename editFav';
955
				var titleEnd = markerHTML.indexOf('</h2>') + 5;
956
				markerHTML = markerHTML.slice(0, titleEnd) + editButton.outerHTML + markerHTML.slice(titleEnd);
957
			} else {
958
				markerHTML2 += 'icon-star addToFav"';
959
			}
960
			markerHTML2 += ' data-latlng="' + latlng + '" style="float: left;"></div><div class="marker-popup-content">' + markerHTML + '</div><div><a class="setDestination" data-latlng="' + latlng + '">Navigate here</a></div>';
961
			marker.addTo(map).bindPopup(markerHTML2);
962
			marker.on('mouseover', function (e) {
963
				var tgt = e.originalEvent.fromElement || e.originalEvent.relatedTarget;
964
				var parent = this._getParent(tgt, 'leaflet-popup');
965
				if(parent == marker._popup._container) return true;
966
				marker.openPopup();
967
			}, this);
968
			marker.on('mouseout', function (e) {
969
				var tgt = e.originalEvent.toElement || e.originalEvent.relatedTarget;
970
				if(this._getParent(tgt, 'leaflet-popup')) {
971
					L.DomEvent.on(marker._popup._container, 'mouseout', this._popupMouseOut, this);
972
					return true;
973
				}
974
				marker.closePopup();
975
			}, this);
976
			if (openPopup === true) {
977
				setTimeout(function() {
978
					//L.popup().setLatLng([marker._latlng.lat, marker._latlng.lng]).setContent("I am a standalone popup.").openOn(map);
979
					marker.openPopup();
980
				}, 50);
981
			}
982
		},
983
		_getParent: function(element, className) {
984
			var parent = element.parentNode;
985
			while (parent != null) {
986
				if (parent.className && L.DomUtil.hasClass(parent, className))
987
					return parent;
988
				parent = parent.parentNode;
989
			}
990
			return false;
991
		},
992
		_popupMouseOut: function(e) {
993
			L.DomEvent.off(marker._popup, 'mouseout', this._popupMouseOut, this);
994
			var tgt = e.toElement || e.relatedTarget;
995
			if (this._getParent(tgt, 'leaflet-popup')) return true;
996
			if (tgt == this._icon) return true;
997
			marker.closePopup();
998
		},
999
		getPoiIcon : function(icon) {
1000
			marker = false;
1001
			if ($.inArray(icon, L.MakiMarkers.icons) > -1) {
1002
				marker = L.MakiMarkers.icon({
1003
					'icon' : icon,
1004
					color : "#b0b",
1005
					size : "l",
1006
					className : icon
1007
				});
1008
			} else {
1009
				var mIcon = toolKit.toMakiMarkerIcon(icon.replace(' ', ''));
1010
				if (mIcon !== false) {
1011
					marker = L.MakiMarkers.icon({
1012
						'icon' : mIcon,
1013
						color : "#b0b",
1014
						size : "l",
1015
						className : icon
1016
					});
1017
				} else {
1018
					var amIcon = toolKit.toFAClass(icon.replace(' ', ''))
1019
					if (amIcon !== false) {
1020
						marker = L.AwesomeMarkers.icon({
1021
							icon : amIcon,
1022
							prefix : 'fa',
1023
							markerColor : 'red'
1024
						});
1025
						marker.options.className += ' ' + icon
1026
					}
1027
				}
1028
			}
1029
			return marker;
1030
		},
1031
1032
		toMakiMarkerIcon : function(type) {
1033
			var mapper = {
1034
				'fast-food' : ['fast_food'],
1035
				'bus' : ['bus_stop', 'bus_station'],
1036
				'beer' : ['bar', 'biergarten', 'pub'],
1037
				'telephone' : ['phone'],
1038
				'swimming' : ['swimming_pool'],
1039
				'bank' : ['atm', 'bank'],
1040
				'town-hall' : ['townhall'],
1041
				'post' : ['post_box', 'post_office'],
1042
				'bicycle' : ['bicycle_parking'],
1043
				'campsite' : ['camp_site', 'caravan_site'],
1044
				'camera' : ['viewpoint'],
1045
				'grocery' : ['supermarket', 'deli', 'convenience', 'greengrocer', 'fishmonger', 'butcher', 'marketplace'],
1046
				'alcohol-shop' : ['alcohol', 'beverages'],
1047
				'shop' : ['general', 'bag', 'furniture', 'variety_store', 'houseware', 'department_store', 'florist', 'outdoor', 'kiosk', 'kitchen', 'shoes', 'jewelry', 'sports'],
1048
				'clothing-store' : ['clothes'],
1049
				'fire-station' : ['fire_station'],
1050
				'place-of-worship' : ['place_of_worship'],
1051
				'school' : ['kindergarten'],
1052
				'parking-garage' : ['parking-entrance'],
1053
				'lodging' : ['hotel', 'guest_house', 'hostel', 'motel'],
1054
				'art-gallery' : ['gallery', 'artwork', 'paint'],
1055
				'library' : ['books', 'library'],
1056
				'pitch' : ['sports'],
1057
				'mobilephone' : ['mobile_phone', 'gsm'],
1058
				'pharmacy' : ['drugstore'],
1059
				'zoo' : ['zoo'],
1060
				'museum' : ['museum'],
1061
				'toilets' : ['toilets'],
1062
				'coffeshop' : ['coffee_shop']
1063
			}
1064
			var returnClass = false;
1065
			$.each(mapper, function(faClass, types) {
1066
				if (types.toString().indexOf(type) > -1) {
1067
					returnClass = faClass
1068
				}
1069
			})
1070
			return returnClass;
1071
		},
1072
		toFAClass : function(type) {
1073
			var mapper = {
1074
				'shopping-cart' : ['supermarkt', 'supermarket', 'department_store', 'deli'],
1075
				'medkit' : ['hospital'],
1076
				'cutlery' : ['fast_food', 'restaurant'],
1077
				'beer' : ['pub'],
1078
				'credit-card' : ['atm'],
1079
				'graduation-cap' : ['school'],
1080
				'lightbulb-o' : ['electronics'],
1081
				'cut' : ['hairdresser'],
1082
				'info' : ['information'],
1083
				'refresh' : ['recycling'],
1084
				'asterisk' : ['attraction', 'theme_park'],
1085
				'cogs' : ['car_repair'],
1086
				'wrench' : ['doityourself'],
1087
				'music' : ['hifi'],
1088
				'gift' : ['gift'],
1089
				'globe' : ['travel_agency'],
1090
				'minus' : ['bench', 'picnic_site'],
1091
				'desktop' : ['computer'],
1092
				'eye' : ['optician'],
1093
				'cubes' : ['toys'],
1094
				'file-picture' : ['photo'],
1095
				'copy' : ['copyshop'],
1096
				'paw' : ['pet'],
1097
				'clock-o' : ['clock'],
1098
				'key' : ['locksmith'],
1099
				'video-camera' : ['video'],
1100
				'magic' : ['party'],
1101
				'road' : ['living_street'],
1102
				'home' : ['residential']
1103
			}
1104
			var returnClass = false;
1105
			$.each(mapper, function(faClass, types) {
1106
				if (types.toString().indexOf(type) > -1) {
1107
					returnClass = faClass
1108
				} else {
1109
				}
1110
			})
1111
			if (returnClass == false)
1112
				console.log('Type icon not found: ' + type)
1113
			return returnClass;
1114
		},
1115
		vcardToObject : function(vcard) {
1116
			var contact = {};
1117
1118
			$.each(vcard.data, function(k, v) {
1119
				if(vcard.data.photo == true){
1120
					var uid = vcard.metadata['id'];
1121
					var parent = vcard.metadata['parent'];
1122
					var backend = vcard.metadata['backend'];
1123
					contact.thumbnail = 'apps/contacts/addressbook/' + backend + '/' + parent + '/contact/' + uid + '/photo';
1124
					contact.thumbnail = OC.generateUrl(contact.thumbnail);
1125
				}
1126
				if (v[0]) {
1127
					if ($.isArray(v[0]['value'])) {
1128
						if (k === 'ADR') {
1129
							var adr = {
1130
								street : v[0]['value'][0] + v[0]['value'][1] + v[0]['value'][2],
1131
								city : v[0]['value'][3],
1132
								postalCode : v[0]['value'][5],
1133
								country : v[0]['value'][6]
1134
							}
1135
							contact[k.toLowerCase()] = adr;
1136
						} else {
1137
							contact[k.toLowerCase()] = v[0]['value'].clean('').join(',');
1138
						}
1139
					} else {
1140
						contact[k.toLowerCase()] = v[0]['value'];
1141
					}
1142
				} else {
1143
					console.log(k, v)
1144
				}
1145
			})
1146
			return contact;
1147
		},
1148
		/**
1149
		 *
1150
		 * @param {Object} street+houseno,City,Country
1151
		 * @param {Function} callback func
1152
		 */
1153
		adresLookup : function(address, callback) {
1154
1155
			if(address !== undefined){
1156
				var getData = {
1157
					street : address.street,
1158
					city : address.city,
1159
					country : address.country
1160
				}
1161
			} else {
1162
				var getData = null;
1163
			}
1164
			$.getJSON(OC.generateUrl('/apps/maps/adresslookup'), getData, function(r) {
1165
				callback(r)
1166
			})
1167
		},
1168
		currentMarker : null,
1169
		favMarkers : [],
1170
		addFavContactMarker : function(contact) {
1171
			if (contact.thumbnail) {
1172
				var imagePath = contact.thumbnail
1173
				var iconImage = L.icon({
1174
					iconUrl : imagePath,
1175
					iconSize : [42, 49],
1176
					iconAnchor : [21, 49],
1177
					popupAnchor : [0, -49],
1178
					className : 'contact-icon'
1179
				});
1180
			} else {
1181
				var imagePath = OC.filePath('maps', 'img', 'icons/marker_anonPerson.png');
1182
				var iconImage = L.icon({
1183
					iconUrl : imagePath,
1184
					iconSize : [42, 49],
1185
					iconAnchor : [21, 49],
1186
					popupAnchor : [0, -49]
1187
				});
1188
			}
1189
1190
			var markerHTML = '<h2>' + contact.fn + "</h2>";
1191
			var street = (contact.adr.street) ? contact.adr.street : '';
1192
			var city = (contact.adr.city) ? contact.adr.city : '';
1193
			markerHTML += '<br />' + street + " " + city;
1194
			markerHTML += (contact.tel) ? '<br />Tel: ' + escape(contact.tel) : '';
1195
			var marker = L.marker([contact.lat * 1, contact.lon * 1], {
1196
				icon : iconImage
1197
			});
1198
			toolKit.addMarker(marker, markerHTML)
1199
			toolKit.favMarkers.push(marker);
1200
		},
1201
		removeFavMarkers : function() {
1202
			for ( i = 0; i < toolKit.favMarkers.length; i++) {
1203
				map.removeLayer(toolKit.favMarkers[i]);
1204
			}
1205
			toolKit.favMarkers = []
1206
		},
1207
1208
		setProgress : function(percent) {
1209
			var $element = $('#progressBar');
1210
			var progressBarWidth = percent * $element.width() / 100;
1211
			$element.find('div').animate({
1212
				width : progressBarWidth
1213
			}, 50);
1214
		}
1215
	}
1216
1217
	poiTypes = {
1218
		shop : ['atm', 'coffee_shop', 'restaurant', 'supermarket', 'bicycle', 'hotel', 'swimming_pool', 'library', 'toilets', 'post_box', 'bar'],
1219
		//TODO: define proper categories:
1220
		// Restaurants/food/coffeeshops/bars, Hotels/hostels, Touristic sites, Wifi, Transport, Fuel, Parking, Supermarket, ATM/Bank, Entertainment, Hospital/Pharmacy, Police, Toilets, Post
1221
		//shop : ['supermarket', 'bakery', 'car', 'stationery', 'hairdresser', 'mobile_phone', 'convenience', 'newsagent', 'kiosk', 'computer', 'clothes', 'variety_store', 'hearing_aids', 'florist', 'handicraft', 'candle', 'antique', 'pet', 'massage', 'electronics', 'laundry', 'doityourself', 'sports', 'jewelry', 'musical_instrument', 'chemist', 'shoes', 'beverages', 'toys', 'fishing', 'copyshop', 'beauty', 'bag', 'paint', 'bicycle', 'communication', 'furniture', 'alcohol', 'deli', 'optician', 'books', 'car_repair', 'butcher', 'outdoor', 'motorcycle', 'estate_agent', 'photo', 'gift', 'travel_agency', 'tea', 'wine', 'medical_supply', 'department_store', 'dry_cleaning', 'video', 'second_hand', 'greengrocer', 'erotic', 'curtain', 'haberdashery', 'garden_centre', 'art', 'fashion', 'bags', 'accessoires', 'confectionery', 'ice_cream', 'organic', 'music', 'boutique', 'interior', 'kitchen', 'vacant', 'tattoo', 'mall', 'camera', 'gallery', 'rc_models', 'coffee', 'bicycle_rental', 'photographer', 'ticket', 'charity', 'Shisha', 'hats', 'funeral_directors', 'locksmith', 'fabric', 'hardware', 'shoe_repair', 'hifi', 'fabrics', 'tailor', 'anime', 'market', 'grocery', 'no', 'surf', 'tobacco', 'animals', 'currency_exchange', 'souvenirs', 'internet-tele-cafe', 'photography', 'car_parts', 'antiques', 'bed', 'skating', 'ceramics', 'internet cafe', 'frame', 'brushes', 'fish', 'callshop', 'glass', 'comics', 'pottery', 'internet_cafe', 'stamps', 'radiotechnics', 'interior_decoration', 'carrental', 'interior_design', 'gramophone', 'Trödel', 'unused', 'watches', 'jewellery', 'tatoo', 'travelling', 'telecommunication', 'cigarettes', 'sports food', 'perfumery', 'unknown', 'orthopedics', 'fire_extinguisher', 'fishmonger', 'wholesale', 'lights', 'carpet', 'office_supplies', 'parquet', 'porcelain', 'lamps', 'make-up', 'art_gallery', 'telecom', 'underwear', 'watch', 'tableware', 'scuba_diving', 'christmas', 'tanning', 'craft', 'leather', 'for rent', 'glaziery', 'seafood', 'Sicherheitstechnik', 'coffee machines', 'alteration', 'decoration', 'sport_bet', 'seefood', 'mobile phone service', 'window_blind', 'tyres', 'cheese', 'medical', 'sewing-machine', 'Kaugummi-Automaten', 'Kaugummi-Automat', 'baby', 'games', 'piercing', 'Elektrohaushaltsgeräte', 'electrician', 'glasses', 'circus', 'food', 'marine', 'lottery', 'Hockey', 'electric', 'coins', 'metal workshop', 'nails', 'general', 'tanning_salon', 'crafts', 'household', 'floor', 'baby_goods', 'Patissier', 'delicatessen', 'telephone', 'Hema', 'soft_drugs', 'board_games', 'lingerie', 'candy', 'cd', 'stones', 'spiritual', 'health', 'juice', 'hemp_products', 'smartshop', 'cannabis', 'frozen_yoghurt', 'art_supplies', 'cigar', 'department', 'sok_shop', 'realestate', 'lighting', 'generic', 'nail', 'ink', 'traiteur', 'toko', 'key', 'gsm', 'artist', 'hearth', 'framing', 'espresso_machine', 'knives', 'rental', 'thrift_store', 'snacks', 'tobacconist', 'disused:butcher', 'party', 'audiologist', 'housewares', 'Fashion', 'printing', 'chandler', 'Shoes', 'Electronics', 'softdrugs', 'houseware', 'textiles', 'perfume'],
1222
		//amenity : ["post_box", "police", "atm", "recycling", "parking", "fuel", "telephone", "school", "pub", "doctors", "arts_centre", "cafe", "fast_food", "restaurant", "place_of_worship", "bank", "bicycle_parking", "drinking_water", "theatre", "bar", "bench", "waste_disposal", "nightclub", "pharmacy", "bicycle_rental", "post_office", "charging_station", "waste_basket", "vending_machine", "kindergarten", "marketplace", "dentist", "ev_charging", "bureau_de_change", "library", "cinema", "toilets", "car_wash", "fountain", "boat_rental", "taxi", "bus_parking", "public_building", "driving_school", "physical therapy", "coffee_shop", "embassy", "vacant", "coffeeshop", "ice_cream", "car_rental", "swimming_pool", "university", "casino", "community_centre", "lost_found", "grit_bin", "clock", "parking_entrance", "sauna", "brothel", "ferry_terminal", "fitness_center", "bus_station", "college", "fire_station", "health_centre", "townhall", "hospital", "veterinary", "gym", "fablab", "money_transfer", "kitchen_studio", "tanning_salon", "tanning", "studio"],
1223
		//tourism : ["artwork", "hostel", "attraction", "hotel", "information", "museum", "gallery", "viewpoint", "picnic_site", "guest_house", "theme_park", "apartment", "zoo", "camp_site", "chalet", "motel", "citytour", "aquarium"]
1224
	}
1225
1226
	mapSettings = {
1227
		openTrackingSettings : function() {
1228
			$.get(OC.generateUrl('/apps/maps/api/1.0/location/loadDevices'), function(d) {
1229
				var tableHTML;
1230
				$.each(d, function() {
1231
					tableHTML += '<tr><td>' + this.name + '</td><td>' + this.hash + '</td><td><div class="icon-delete icon" data-deviceId="' + this.id + '"></div></td></tr>';
1232
				});
1233
				$('#trackingDevices tbody').html(tableHTML);
1234
			})
1235
			$('#trackingSettingsPopup').dialog({
1236
				buttons : {
1237
					"Close" : function() {
1238
						$(this).dialog('destroy');
1239
						$('#addtracking')[0].reset()
1240
					}
1241
				}
1242
1243
			});
1244
		},
1245
		saveDevice : function() {
1246
			if ($('#addtracking input').val() == '')
1247
				return
1248
			var formData = {
1249
				name : $('#addtracking input').val()
1250
			};
1251
			$.post(OC.generateUrl('/apps/maps/api/1.0/location/adddevice'), formData, function(d) {
1252
				$('#trackingDevices tbody').append('<tr><td>' + formData.name + '</td><td>' + d.hash + '</td><td><div class="icon-delete icon" data-deviceId="' + d.id + '"></div></td></tr>');
1253
				$('#addtracking input').val('');
1254
			});
1255
		},
1256
1257
		deleteDevice : function(e) {
1258
			var dId = $(this).attr('data-deviceId');
1259
			$(this).parent().parent().remove();
1260
			///api/1.0/location/removedevice
1261
			var formData = {
1262
				deviceId : dId
1263
			};
1264
			$.post(OC.generateUrl('/apps/maps/api/1.0/location/removedevice'), formData);
1265
1266
		}
1267
	}
1268
1269
	favorites = {
1270
		favArray : [],
1271
		add : function(){
1272
			var latlng = $(this).attr('data-latlng').split(',');
1273
			var popup = document.getElementsByClassName('leaflet-popup-content')[0];
1274
			var favicon = popup.getElementsByTagName('div')[0];
1275
			var content = popup.getElementsByTagName('div')[1];
1276
1277
			var popupText = content.innerHTML;
1278
			var delimiter = '<br>';
1279
			var splitIndex = popupText.indexOf(delimiter);
1280
			content.innerHTML = popupText.substring(splitIndex + delimiter.length);
1281
			var orgTitle = popupText.substring(0, splitIndex);
1282
			var formData = {
1283
				lat : latlng[0],
1284
				lng : latlng[1],
1285
				name : orgTitle
1286
			};
1287
			$.post(OC.generateUrl('/apps/maps/api/1.0/favorite/addToFavorites'), formData, function(data) {
1288
				var markerHTML = '<h2>' + formData.name + '</h2>';
1289
				var marker = L.marker([formData.lat, formData.lng], {
1290
								icon : favMarkerIcon,
1291
								id : data.id
1292
				});
1293
				map.removeLayer(currentMarker);
1294
				currentMarker = null;
1295
				toolKit.addMarker(marker, markerHTML, true, true);
1296
				favorites.favArray.push(marker);
1297
			});
1298
		},
1299
		show : function(){
1300
			$.post(OC.generateUrl('/apps/maps/api/1.0/favorite/getFavorites'), null, function(data){
1301
				for(var i=0; i<data.length; i++){
1302
					var fav = data[i];
1303
1304
					var imagePath = OC.filePath('maps', 'img', 'icons/favMarker.png');
1305
					var iconImage = L.icon({
1306
						iconUrl : imagePath,
1307
						iconSize : [31, 37],
1308
						iconAnchor : [15, 37],
1309
						popupAnchor : [0, -37]
1310
					});
1311
1312
					var markerHTML = '<h2>' + fav.name + '</h2>';
1313
					/*markerHTML += '<br />Latitude: ' + parseFloat(fav.lat).toFixed(3);
1314
					markerHTML += '<br />Longitude: ' + parseFloat(fav.lng).toFixed(3);
1315
					markerHTML += '<br />Added: ' + new Date(fav.timestamp*1000).toString();*/
1316
					var marker = L.marker([fav.lat, fav.lng], {
1317
									icon : iconImage,
1318
									id : fav.id
1319
					});
1320
					toolKit.addMarker(marker, markerHTML, false, true);
1321
					favorites.favArray.push(marker);
1322
				}
1323
			});
1324
		},
1325
		hide : function(){
1326
			for(var i=0; i<favorites.favArray.length; i++){
1327
				map.removeLayer(favorites.favArray[i]);
1328
			}
1329
			favorites.favArray = [];
1330
		},
1331
		remove : function(){
1332
			var id = $(this).attr('fav-id');
1333
			var formData = {
1334
				id : id
1335
			};
1336
			$.post(OC.generateUrl('/apps/maps/api/1.0/favorite/removeFromFavorites'), formData, function(data){
1337
				for(i=0; i<favorites.favArray.length; ++i) {
1338
					if(favorites.favArray[i].options.id == id) {
1339
						//TODO this code toggles the star icon and the add/remove methods. Should be used as soon as the marker replacement works
1340
						var popup = document.getElementsByClassName('leaflet-popup-content')[0];
1341
						var favicon = popup.getElementsByTagName('div')[0];
1342
						var newClass = favicon.className.replace('icon-starred', 'icon-star');
1343
						favicon.className = newClass.replace('removeFromFav', 'addToFav');
1344
						var removedFav = favorites.favArray.splice(i,1)[0];
1345
						addGeocodeMarker(removedFav.getLatLng());
1346
						map.removeLayer(removedFav);
1347
						return;
1348
					}
1349
				}
1350
			});
1351
		},
1352
		edit : function() {
1353
			var popup = document.getElementsByClassName('leaflet-popup-content')[0];
1354
			var favicon = popup.getElementsByTagName('div')[0];
1355
			var id = favicon.getAttributeNode('fav-id').value;
1356
			var content = popup.getElementsByTagName('div')[1];
1357
			var titleNode = content.getElementsByTagName('h2')[0];
1358
			var title = titleNode.innerHTML;
1359
			var button = content.getElementsByClassName('editFav')[0];
1360
			var input = document.createElement('input');
1361
			input.type = 'text';
1362
			input.value = title;
1363
			titleNode.parentNode.replaceChild(input, titleNode);
1364
			button.className = 'confirmFavEdit icon-checkmark';
1365
			$(document).on('click', '.confirmFavEdit', function() {
1366
				button.className = 'icon-rename editFav';
1367
				if(title != input.value) title = input.value;
1368
				titleNode.innerHTML = title;
1369
				content.replaceChild(titleNode, input);
1370
				var formData = {
1371
					name : title,
1372
					id : id
1373
				};
1374
				$.post(OC.generateUrl('/apps/maps/api/1.0/favorite/updateFavorite'), formData, function(data){
1375
				});
1376
				$(document).off('click', '.confirmFavEdit');
1377
			});
1378
		}
1379
	}
1380
1381
	$(document).on('click', '#tracking-settings', mapSettings.openTrackingSettings);
1382
	$(document).on('click', '#addtracking button', mapSettings.saveDevice);
1383
	$(document).on('click', '#trackingDevices .icon-delete', mapSettings.deleteDevice);
1384
	$(document).on('click', '.addToFav', favorites.add);
1385
	$(document).on('click', '.removeFromFav', favorites.remove);
1386
	$(document).on('click', '.editFav', favorites.edit)
1387
1388
	/**
1389
	 * Extend the OC.Notification object with our own methods
1390
	 */
1391
	OC.Notification.showTimeout = function(text, timeout, isHTML) {
1392
		isHTML = (!isHTML) ? false : true;
1393
		OC.Notification.hide();
1394
		if (OC.Notification.notificationTimer) {
1395
			clearTimeout(notificationTimer);
1396
		}
1397
		timeout = (!timeout) ? 3000 : timeout;
1398
		if (isHTML) {
1399
			OC.Notification.showHtml(text);
1400
		} else {
1401
			OC.Notification.show(text);
1402
		}
1403
		OC.Notification.notificationTimer = setTimeout(function() {
1404
			OC.Notification.hide();
1405
		}, timeout);
1406
	}
1407
})(jQuery, OC);
1408