/**
* @name leafletmap.js
* @version 3.5
* @Uses Leaflet API
* @date 12-05-20
* @author Lignumaqua - Mike Wood
*
* For Leaflet Map GSAK Macro
*
*/




function writecookie(cookiename,k) { document.cookie=cookiename+'='+k+'; expires=Fri, 31 Dec 2030 00:00:00 UTC' };

function clearcookie(cookiename,k) { document.cookie=cookiename+'='+k+'; expires=Fri, 31 Dec 2000 00:00:00 UTC' };

function readCookie(cookieName){
	var searchName = cookieName + "="
	var cookies = document.cookie
	var start = cookies.indexOf(cookieName)
	if (start == -1){ // cookie not found
		return "-1"
	}
	start += searchName.length //start of the cookie data
	var end = cookies.indexOf(";", start)
	if (end == -1){
		end = cookies.length
	}
	return cookies.substring(start, end)
}




// Add .indexOf() definition for IE8 or earlier
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;
    var from = Number(arguments[1]) || 0;
    from = (from < 0) ? Math.ceil(from) : Math.floor(from);
    if (from < 0) {
     from += len;
    }
    for (; from < len; from++) {
      if (from in this && this[from] === elt) {
        return from;
      }
    }
    return -1;
  };
}

  
//---- Get lat and long ----//
function latlon(point) {
	lat = point.lat();
	lon = point.lng();
	lat = Math.round(lat*1000000)/1000000; 
	lon = Math.round(lon*1000000)/1000000;
}
 
 
 
 //---- Coordinates to clipboard ----//
 function gsakclip(e) {
 	window.location.assign("gsak://%FF/ClipBoard/" + Math.round(e.latlng.lat*1000000)/1000000 + " " + Math.round(e.latlng.lng*1000000)/1000000);
 }
 
 
 //---- Create URI link for Get Nearest Macro ----//
 function getnearestmacro(e) {
 	window.location.assign("gsak://%FF/Macro/GetNearestCache?" + e.latlng.lat + " " + e.latlng.lng);
}

//---- Create URI link for Macro Options----//
 function macrooptions(e) {
 	window.location.assign("gsak://%FF/Macro/Leaflet_Map?options");
}

 function showall(e) {
	map.fitBounds(bounds);	
}
 

 function showhidelabels(e) {
   if (tooltipsvisible){
	map.eachLayer(function(layer) {
      if (layer.getTooltip) {
        var toolTip = layer.getTooltip();
        if (toolTip) {
          this.map.closeTooltip(toolTip);
        }
      }
    });
	} else {
	map.eachLayer(function(layer) {
      if (layer.getTooltip) {
        var toolTip = layer.getTooltip();
        if (toolTip) {
          this.map.openTooltip(toolTip);
        }
      }
    });
	}
	tooltipsvisible = !tooltipsvisible;
}
 


function sendtoGSAK() {
	var theForm, newInput1, newInput2, newInput3;

		var boxlist = gsakCoordinates();

		randomid=Math.floor(Math.random()*10000000000);
		// Create a <form>
		theForm = document.createElement('form');
		theForm.action = 'http://gsak.net/google/polygoncoordinatestogsak.php';
		//theForm.action = 'http://gsak.net/testform.html';
		theForm.method = 'post';
		theForm.target = 'upload_target';
		// Next create the <input>s in the form and give them names and values
		newInput1 = document.createElement('input');
		newInput1.type = 'hidden';
		newInput1.name = 'command';
		newInput1.value = 'save';
		newInput2 = document.createElement('input');
		newInput2.type = 'hidden';
		newInput2.name = 'id';
		newInput2.value = randomid;
		newInput3 = document.createElement('input');
		newInput3.type = 'hidden';
		newInput3.name = 'boxdata';
		newInput3.value = boxlist;
		// Add inputs to form
		theForm.appendChild(newInput1);
		theForm.appendChild(newInput2);
		theForm.appendChild(newInput3);
		// Add the whole thing to the DOM
		document.getElementById('hidden_form_container').appendChild(theForm);
		//Submit it
		theForm.submit();

		// Check if data has been received
		checkurl = 'http://gsak.net/stats/maps/checkpolygoncoordinatestogsak.php?id=' + randomid;

		// Wait 1 second and then send to GSAK
		//setTimeout(afterTimeout, 1000, [randomid]);
		loadCheck(checkurl);
}

//
//function sendtoGSAK() {
//	var boxlist = gsakCoordinates(selectedShape);
//	randomid=Math.floor(Math.random()*10000000000);
//	var ajaxreq = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
//	ajaxreq.open('POST','http://gsak.net/google/polygoncoordinatestogsak.php');
//	ajaxreq.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
//	ajaxreq.send('command=save&id=' + randomid + '&boxdata=' + boxlist)
//	ajaxreq.onreadystatechange = function(){
//		if(ajaxreq.readyState==4) {
//			// Check if data has been received
//			checkurl = 'http://gsak.net/stats/maps/checkpolygoncoordinatestogsak.php?id=' + randomid;
//			loadCheck(checkurl);
//		}
//	}
//}


function loadCheck(url) {
	var headID = document.getElementsByTagName("head")[0];
	var newScript = document.createElement('script');
	newScript.type = 'text/javascript';
	newScript.src = url;
	headID.appendChild(newScript);
}

var count = 1;

function loadCheckReply(status) {
	if (status == 'good') {
		//alert(status + ', ' + count);
		afterGoodsend();
	} else {
		count = count++;
		if (count >10) {
			alert('Cannot contact GSAK server');
		} else {
			setTimeout(loadCheck, 250, [checkurl]);
		}
	}
}


function afterGoodsend()
{
	gsakuri = 'gsak://%FF/LinePoly/' + randomid;
	location.href=gsakuri;
}

function afterTimeout()
{
	gsakuri = 'gsak://%FF/LinePoly/' + randomid;
	location.href=gsakuri;
}

function googlestreetview(e)
{
	window.open("https://www.google.com/maps?layer=c&cbll=" + Math.round(e.latlng.lat*1000000)/1000000 + "," + Math.round(e.latlng.lng*1000000)/1000000);
}


function gsakCoordinates(){
		var coordtext = "";
		//alert(outputFileMode);

		// print coords header
		coordtext =  "";
		// loop to print coords


		for (var i = 0; i<(points[0].length); i++) {

			var lat = points[0][i].lat;
			lat = lat.toFixed(6);
			var longi = points[0][i].lng;
			longi = longi.toFixed(6);
			coordtext += lat + "," + longi + ";";
		}

		// Repeat first point to close it
		
			var lat = points[0][0].lat;
			lat = lat.toFixed(6);
			var longi = points[0][0].lng;
			longi = longi.toFixed(6);
			coordtext += lat + "," + longi + ";";
		
		return coordtext;

}




//---- Print Map----//
 function printMap(e) {
 	window.print();
 }


function initialize() {

// Workaround for Microsoft Browser Component always sending IE8 as the User Agent
if (navigator.userAgent.match(/MSIE 8/)) {
	Object.defineProperty(navigator, "userAgent", { 
    	get: function () { 
        	return "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)"; // customized user agent
    	}
	});
}

	//-----icon references----->

	//var cacheicon = L.icon({iconUrl: 'cacheicons/' + cacheimage + mrk + '_e.png',iconSize: [27, 34],iconAnchor: [4, 34],popupAnchor: [0, -20],shadowUrl: 'cacheicons/shadow1.png',shadowSize: [45, 34],shadowAnchor: [4, 34]});
	
	
	var iconName = new Array('A','B','C','E','G','I','L','M','O','R','T','U','V','W','X','Y','Z','H','F','D','P','J','Q');
	var imageName = new Array('ape1','le1','ci1','ev1','be1','wh1','lo1','mu1','other1','ea1','tr1','un1','vi1','we1','maze1','wm1','mega1','hq1','lf1','hq1','bp1','giga1','lab1');



	if (imagefolder == 'small') {
	
	for (i=0; i<iconName.length;i++)
	{
		window[iconName[i] + "_icon"] = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/small/" + imageName[i] + ".png",
		iconSize: [12,20],
		iconAnchor: [6,20],
		popupAnchor: [0,0]
		});

		window[iconName[i] + "_f_icon"] = L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/small/" + "found1" + ".png",
		iconSize: [12,20],
		iconAnchor: [6,20],
		popupAnchor: [0,0]
		});

		window[iconName[i] + "_e_icon"] = L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/small/" + imageName[i] + "_e" + ".png",
		iconSize: [12,20],
		iconAnchor: [6,20],
		popupAnchor: [0,0]
		});

		window[iconName[i] + "_f_e_icon"] = L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/small/" + "found1_e" + ".png",
		iconSize: [12,20],
		iconAnchor: [6,20],
		popupAnchor: [0,0]
		});
	}	
		
		} else {
	
	for (i=0; i<iconName.length;i++)
		{
		window[iconName[i] + "_icon"] = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/" + imageName[i] + ".png",
    		iconSize: [27, 34],
    		iconAnchor: [4, 34],
    		popupAnchor: [0, -20],
    		shadowUrl: "http://gsak.net/stats/maps/cacheicons/shadow1.png",
    		shadowSize: [45, 34],
    		shadowAnchor: [4, 34]
    		});
				

		window[iconName[i] + "_f_icon"] = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/" + imageName[i] + "_f" + ".png",
    		iconSize: [27, 34],
    		iconAnchor: [4, 34],
    		popupAnchor: [0, -20],
    		shadowUrl: "http://gsak.net/stats/maps/cacheicons/shadow1.png",
    		shadowSize: [45, 34],
    		shadowAnchor: [4, 34]
    		});
		
		window[iconName[i] + "_e_icon"] = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/" + imageName[i] + "_e" + ".png",
    		iconSize: [27, 34],
    		iconAnchor: [4, 34],
    		popupAnchor: [0, -20],
    		shadowUrl: "http://gsak.net/stats/maps/cacheicons/shadow1.png",
    		shadowSize: [45, 34],
    		shadowAnchor: [4, 34]
    		});

		window[iconName[i] + "_f_e_icon"] = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/" + imageName[i] + "_f_e" + ".png",
    		iconSize: [27, 34],
    		iconAnchor: [4, 34],
    		popupAnchor: [0, -20],
    		shadowUrl: "http://gsak.net/stats/maps/cacheicons/shadow1.png",
    		shadowSize: [45, 34],
    		shadowAnchor: [4, 34]
    		});
		}
	}
	
	var iconName = new Array('final_location','stages_of_a_multicache','parking_area','question_to_answer','reference_point','trailhead','virtual_stage','physical_stage');
	var imageName = new Array('final1','multistage1','parking1','question1','reference1','trailhead1','question1','multistage1');
	
	for (i=0; i<iconName.length;i++)
		{
		window[iconName[i] + "_icon"] = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/" + imageName[i] + ".png",
    		iconSize: [27, 34],
    		iconAnchor: [4, 34],
    		popupAnchor: [0, -20],
    		shadowUrl: "http://gsak.net/stats/maps/cacheicons/shadow1.png",
    		shadowSize: [45, 34],
    		shadowAnchor: [4, 34]
    		});
		}
	


	found_icon = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/found1.png",
    		iconSize: [27, 34],
    		iconAnchor: [4, 34],
    		popupAnchor: [0, -20],
    		shadowUrl: "http://gsak.net/stats/maps/cacheicons/shadow1.png",
    		shadowSize: [45, 34],
    		shadowAnchor: [4, 34]
    		});	


	childicon = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/waypoint1.png",
    		iconSize: [27, 34],
    		iconAnchor: [4, 34],
    		popupAnchor: [0, -20],
    		shadowUrl: "http://gsak.net/stats/maps/cacheicons/shadow1.png",
    		shadowSize: [45, 34],
    		shadowAnchor: [4, 34]
    		});	
	

	correctedicon = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/traffic_cone.png",
    		iconSize: [16, 16],
    		iconAnchor: [8, 16]
    		});	

	dnficon = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/dnf.png",
    		iconSize: [16, 16],
    		iconAnchor: [-8, 36]
    		});	

	ownedicon = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/owned.png",
    		iconSize: [16, 16],
    		iconAnchor: [-8, 36]
    		});	


	ringicon = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/ring.png",
    		iconSize: [31, 20],
    		iconAnchor: [15, 10]
    		});	


	if (imagefolder == 'small') {
		unavailable_icon = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/small/unavailable.png",
			iconSize: [27, 34],
    		iconAnchor: [10, 26],

    		});	
	
		flagicon = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/userflag.png",
			iconSize: [16, 16],
    		iconAnchor: [4,36],
    		});	

	} else {

	unavailable_icon = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/unavailable.png",
    		iconSize: [27, 34],
    		iconAnchor: [4, 34],
    		popupAnchor: [0, -20],
    		shadowUrl: "http://gsak.net/stats/maps/cacheicons/shadow1.png",
    		shadowSize: [45, 34],
    		shadowAnchor: [4, 34]
    		});	

	flagicon = new L.icon({iconUrl: "http://gsak.net/stats/maps/cacheicons/userflag.png",
    		iconSize: [16, 16],
    		iconAnchor: [-4, 40]
    		});	
	}

	


// Create Map

 	 map = L.map('map', {
 	 		scrollWheelZoom: scrollwheelZoom_user,
 	 		contextmenu: true,
 	 		 contextmenuItems: [{
	      	  // Toggle Clustering
		      text: 'Show/Hide Clusters',
		      callback: toggleclustering
		  }, {
	      	  // Toggle Tooltips
		      text: 'Show/Hide Labels',
		      callback: showhidelabels
		  }, {
 	 		  // Get Nearest
 	 		  text: 'Select Nearest Cache to Here',
		      callback: getnearestmacro
		  }, {
	      	  // Coordinates to clipboard
		      text: 'Copy Coords to Clipboard',
		      callback: gsakclip
		  }, {
	      	  // Polygon to GSAK
		      text: 'Send Polygon to GSAK Filter',
		      callback: sendtoGSAK
		  }, {
		  	  // Google Street View
		      text: 'Google Street View',
		      callback: googlestreetview
		  }, {
	      	  // Macro options
		      text: 'Options',
		      callback: macrooptions
		  }, '-', {
	      	  // Print Map
		      text: 'Print Map',
		      callback: printMap
		  }, '-', {
	      	  // Version
		      text: 'Version: ' + revNumber,
	      }]
 	 });
 	 bounds = new L.latLngBounds();

// Scale control

L.control.scale().addTo(map);


// GPX File Load

var filestyle = {
            color: 'blue',
            opacity: 1.0,
            fillOpacity: 0.5,
            weight: 2,
            clickable: false
        };


 L.Control.FileLayerLoad.LABEL = '<img class="iconstyle" src="http://gsak.net/stats/maps/cacheicons/folder.svg" alt="file icon"/>';
        control = L.Control.fileLayerLoad({
            fitBounds: true,
            layerOptions: {
                style: filestyle,
                pointToLayer: function (data, latlng) {
                    return L.circleMarker(
                        latlng,
                        { style: filestyle }
                    );
                }
            }
        });
        control.addTo(map);
        control.loader.on('data:loaded', function (e) {
            var layer = e.layer;
            console.log(layer);
            // Add to map layer switcher
        	mapLayerControl.addOverlay(layer, e.filename);
        });



	 osmLink = '<a href="http://openstreetmap.org">OpenStreetMap</a>';
     osmUrl = 'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
     osmAttrib = '&copy; ' + osmLink + ' Contributors';
     osmMap = L.tileLayer(osmUrl, {attribution: osmAttrib, maxZoom: 19});

     optLink = '<a href="https://opentopomap.org">OpenTopoMap</a>';
     optUrl = 'https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png';
     optAttrib = '&copy; ' + optLink + ' Contributors';
     optMap = L.tileLayer(optUrl, {attribution: optAttrib, maxZoom: 18});


	 esrisatLink = '<a href="http://www.esri.com/">Esri</a>';
     esrisatUrl = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}.png';
     esrisatAttrib = '&copy; '+ esrisatLink +' Contributors & '+ esrisatLink;
     esrisatMap = L.tileLayer(esrisatUrl, {attribution: esrisatAttrib, maxZoom: 18});
     
    //  boundariesUrl = 'https://maps.heigit.org/openmapsurfer/tms/1.0.0/adminb/webmercator/{z}/{x}/{-y}.png';
	//  boundariesAttrib = 'Heidelberg';
	// boundariesMap = L.tileLayer(boundariesUrl, {attribution: boundariesAttrib, zoomOffset: -1, maxZoom: 18});
	
	 boundariesUrl = 'http://openmap.gsak.net/styles/osm-boundaries/{z}/{x}/{y}.png';     
	 boundariesAttrib = 'GSAK - OpenMapTiles';
     boundariesMap = L.tileLayer(boundariesUrl, {attribution: boundariesAttrib, zoomOffset: 0, maxZoom: 18});

     overlays = {
			"Admin Boundaries": boundariesMap
		};
           	  
   	 //add the OSM tile layer
   	 osmMap.addTo(map);

     map.attributionControl.setPrefix(''); // Don't show the 'Powered by Leaflet' text. Attribution overload


	baseLayers = {
			"OSM": osmMap,
			"ESRI Satellite": esrisatMap,
			"OpenTopo": optMap
		};

mapLayerControl = new L.control.layers();

// Initialise the FeatureGroup to store editable layers
var drawnItems = new L.FeatureGroup();
map.addLayer(drawnItems);


 var options = {
        draw: {
            polyline: false,
            polygon: {
                allowIntersection: false, // Restricts shapes to simple polygons
                drawError: {
                    color: '#e1e100', // Color the shape will turn when intersects
                    message: '<strong>No intersections allowed!<strong>' // Message that will show when intersect
                },
            },
            circle: false, // Turns off this drawing tool
            rectangle: false,
            marker: false,
            circlemarker: false,
        },
        edit: {
            featureGroup: drawnItems,
            remove: false
        }
    };


// Initialise the draw control and pass it the FeatureGroup of editable layers
var drawControl = new L.Control.Draw(options);
map.addControl(drawControl);

map.on(L.Draw.Event.CREATED, function (e) {
  var type = e.layerType
  var layer = e.layer;

  // Do whatever else you need to. (save to db, add to map etc)
  if (type === 'polygon') {
      points = layer._latlngs;
   }

  drawnItems.addLayer(layer);
});


// One click control

var oneclickEnabled = oneclick;

var oneclickControl =  L.Control.extend({

  options: {
    position: 'topleft'
  },

  onAdd: function (map) {
    var container = L.DomUtil.create('input');
    container.type="image";
    container.title="Toggle One Click";
    container.style.backgroundColor = 'mediumseagreen';     
    container.src = "https://gsak.net/stats/maps/cacheicons/onefingericon.png";
    container.style.width = '16px';
    container.style.height = '16px';
    container.style.padding = '2px';
    container.style.border = '2px solid grey';
    container.style.borderRadius = '3px';
    
    container.onclick = function(){
      console.log('buttonClicked');
       if (oneclickEnabled) {
        container.style.backgroundColor = '#ea5b5b'; 
        oneclickEnabled = false;
      } else {
        container.style.backgroundColor = 'mediumseagreen'; 
        oneclickEnabled = true;
      }

    }

    return container;
  }
});

if (oneclick) {
  map.addControl(new oneclickControl());
}




//function usermaps(){}




// Additional Map Type Plug-ins //
//==============================//

usermaps();

//==============================//

mapLayerControl = L.control.layers(baseLayers,overlays);
map.addControl(mapLayerControl);

// Feature detect + local reference
storage = false;
fail = true;
uid = '';
try {
	uid = new Date;
	(storage = window.localStorage).setItem(uid, uid);
	fail = storage.getItem(uid) != uid;
	storage.removeItem(uid);
	fail && (storage = false);
} catch (exception) {}

var is_chrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1;
// Default value
	zoomcookie = 14;

	//----read cookie and set zoom accordingly---

	if (!storage) {
		//alert("Not Chrome");
		zoomcookie = readCookie('zoomleafletmacro');
		//alert (zoomcookie);
		if (zoomcookie == "-1") {zoomcookie = '14';}
		zoomcookie = parseInt(zoomcookie);
		
	} else {
		zoomcookie = storage.getItem('zoomleafletmacro');
		if ((typeof zoomcookie=="undefined") || (zoomcookie === null)) {zoomcookie = "14";}
		zoomcookie = parseInt(zoomcookie);
	}

	
		markers = L.markerClusterGroup({
		disableClusteringAtZoom:disableClusteringAtZoom_user,
		maxClusterRadius:maxClusterRadius_user,
		chunkedLoading: false,
		animate: showanimation,
		spiderfyOnMaxZoom:false,
		iconCreateFunction: function (cluster) {

				mark = cluster.getAllChildMarkers();
				var n = 0;
				for (var i = 0; i < mark.length; i++) {
					if (mark[i].cache === true) {
						n = n+1;
					};
				}
				
		var c = ' marker-cluster-';
		if (n < 10) {
			c += 'small';
		} else if (n < 100) {
			c += 'medium';
		} else {
			c += 'large';
		}

		return new L.DivIcon({ html: '<div><span>' + n + '</span></div>', className: 'marker-cluster' + c, iconSize: new L.Point(40, 40) });

		}
	});

	//Remove everything outside the current view with a small amount of padding - this speeds things up a lot!
		markers._getExpandedVisibleBounds = function () {
    		return markers._map.getBounds().pad(0.1);
		};



// Style for the Delorme overlays
	jsonStyle = {
    fillColor: "#4040ff",
    color: "#4040ff",
    weight: 2,
    fill: false,
    opacity: 1,
    clickable: false
};


userpoints();

	map.addLayer(markers);

	
	//map.fitBounds(bounds);
	


//==== Function to switch layers ====//

function switchLayer(destLayer) { 
    for (var base in baseLayers) {
    //console.log(base); 
        if (map.hasLayer(baseLayers[base]) && base != destLayer) { 
            map.removeLayer(baseLayers[base]); 
        } 
    }
    for (var base in baseLayers) { 
        if (base == destLayer) { 
            map.addLayer(baseLayers[base]); 
        } 
    }
}; 



//----read cookie and set maptype accordingly---
	if (!storage) {
		//alert("Not Chrome");
		typecookie = readCookie('typeleafletmacro');
		//alert (typecookie);
		if ((typeof typecookie === "undefined") || (typecookie === null) || (typeof baseLayers[typecookie] === 'undefined')) {typecookie = "OSM";}
		switchLayer(typecookie);
	} else {
		typecookie = storage.getItem('typeleafletmacro');
		if ((typeof typecookie === "undefined") || (typecookie === null) || (typeof baseLayers[typecookie] === 'undefined')) {typecookie = "OSM";}
		switchLayer(typecookie);
	}

// Add listener to see if map type changes and store it, use local storage if we can


	map.on('baselayerchange', function (e) {
		k = e.name;
		//alert(k);
		//console.log(e);
		if (!storage) {
			writecookie('typeleafletmacro', k);
		} else {
			storage.setItem('typeleafletmacro', k);
		}
	}); 

// Add listener to see if zoom changes and store it, use local storage if we can
 
 
 	map.on('zoomend', function()  {
 		k = map.getZoom();
 		//alert(k);
 		if (!storage) {
 			writecookie('zoomleafletmacro', k);
 			//alert(k);
 		} else {
 			storage.setItem('zoomleafletmacro', k);
 		}
 	}); 
 
 

map.fitBounds(bounds);

// Catch mousedown events so we can see if the Shift key is pressed
document.addEventListener('mousedown',function (e) {
	clickfrommenu = false;
   if (e.shiftKey || oneclickEnabled == false) {
      clickfrommenu = true;
   }
});

// If in One Click mode, don't open Info Window unless Shift key is pressed

map.on('popupopen', function(e) {

   if (clickfrommenu == false && oneclick == true){
         map.closePopup();
    }else {
    }   clickfrommenu=false;
});


// Catch zoomend eventsand dynamically change MarkerVisibleBounds

// map.on('zoomend', function(e) {
// 	var zoom = map.getZoom();
//	if (zoom >15) {
//		markers._getExpandedVisibleBounds = function () {return markers._map.getBounds().pad(1.0)};
//	} else {
//		markers._getExpandedVisibleBounds = function () {return markers._map.getBounds().pad(0.1)};
//	}
// });



// Catch zoomend and moveend events so we can toggle any new tooltips
// Always Hide tool tips at low zooms

var lastZoom;
map.on('zoomend moveend', function(e) {
if (!tooltipsvisible){
	map.eachLayer(function(layer) {
      if (layer.getTooltip) {
        var toolTip = layer.getTooltip();
        if (toolTip) {
          this.map.closeTooltip(toolTip);
        }
      }
    });
} else {
var zoom = map.getZoom();
  if (zoom < 8 && (!lastZoom || lastZoom >= 8)) {
    map.eachLayer(function(l) {
      if (l.getTooltip) {
        var toolTip = l.getTooltip();
        if (toolTip) {
          this.map.closeTooltip(toolTip);
        }
      }
    });
  } else if (zoom >= 8 && (!lastZoom || lastZoom < 8)) {
    map.eachLayer(function(l) {
      if (l.getTooltip) {
        var toolTip = l.getTooltip();
        if (toolTip) {
          this.map.addLayer(toolTip);
        }
      }
    });
  }
  lastZoom = zoom;
}});


// Catch zoomend and moveend to see if we need to add/remove flags , circles, dnf, owned, and unavailable icons
map.on('zoomend moveend', function(e) {
	showvisibleflags();
	showvisibleunavailables();
	showvisiblednfs();
	showvisibleowned();
	showvisiblecircles();
	showvisiblechildren();
	showvisiblechildcircles();
 });

markers.on('animationend', function(e) {
	showvisibleflags();
	showvisibleunavailables();
	showvisiblednfs();
	showvisibleowned();
	showvisiblecircles();
	showvisiblechildren();
	showvisiblechildcircles();
 });

if (showclusters == false) {
	markers.disableClustering();
} 


showvisibleflags();
showvisibleunavailables();
showvisiblednfs();
showvisibleowned();
showvisiblecircles();
showvisiblechildren();
showvisiblechildcircles();

} // End of initialize


function gsakButtons(gccode,closewindow,flagmarker) {
	var gsakcode = "<b>View:</b><a href=\"javascript:viewLink('" + gccode + "'," + closewindow + ")\" ><img class='gsak' src='http://gsak.net/stats/maps/viewicon.gif'></a>&nbsp;&nbsp;<b>Flag:</b><a href=\"javascript:flagLink('" + gccode + "'," + closewindow + ",'" + flagmarker + "')\"><img class='gsak' src='http://gsak.net/stats/maps/flagicon.gif'></a>&nbsp;&nbsp;<b>Sort:</b><a href=\"javascript:sortLink('" + gccode + "'," + closewindow + ")\"><img class='gsak' src='http://gsak.net/stats/maps/incsorticon.gif'></a>";
	return gsakcode;
}

function viewLink(gccode,closewindow) {
	location.href = 'gsak://%FF/search/' + gccode + '/' + database;
}

// Show visible unavailable
function showvisibleunavailables() {
	unavailablemarkers.forEach(function(thisunavailable) { 
		unavailableid = thisunavailable.options.alt;
		markerid = unavailableid.replace('u', 'm');
		if (map.hasLayer(window[markerid])) {
			thisunavailable.addTo(map);
			} else {
			thisunavailable.removeFrom(map);
		}
	}
)};

// Show visible dnf
function showvisiblednfs() {
	dnfmarkers.forEach(function(thisdnf) { 
		dnfid = thisdnf.options.alt;
		markerid = dnfid.replace('d', 'm');
		if (map.hasLayer(window[markerid])) {
			thisdnf.addTo(map);
			} else {
			thisdnf.removeFrom(map);
		}
	}
)};

// Show visible owned
function showvisibleowned() {
	ownedmarkers.forEach(function(thisowned) { 
		ownedid = thisowned.options.alt;
		markerid = ownedid.replace('o', 'm');
		if (map.hasLayer(window[markerid])) {
			thisowned.addTo(map);
			} else {
			thisowned.removeFrom(map);
		}
	}
)};

// Show visible circles
function showvisiblecircles() {
	circlemarkers.forEach(function(thiscircle) { 
		circleid = thiscircle.options.alt;
		markerid = circleid.replace('k', 'm');
		if (map.hasLayer(window[markerid])) {
			thiscircle.addTo(map);
			} else {
			thiscircle.removeFrom(map);
		}
	}
)};


// Show visible children
function showvisiblechildren() {
	childmarkers.forEach(function(thischild) { 
		childid = thischild.options.alt;
		markerid = childid.replace('c', 'm');
		var mapBounds = map.getBounds().pad(0.1);
		if ((map.hasLayer(window[markerid]) || !showclusters || map.getZoom() >= markers.options.disableClusteringAtZoom) && mapBounds.contains(thischild.getLatLng())) {
			thischild.addTo(map);
			} else {
			thischild.removeFrom(map);
		}
	}
)};

// Show visible child circles
function showvisiblechildcircles() {
	childcirclemarkers.forEach(function(thischildcircle) { 
		childcircleid = thischildcircle.options.alt;
		markerid = childcircleid.replace('ck', 'm');
		var mapBounds = map.getBounds().pad(0.1);
		if ((map.hasLayer(window[markerid]) || !showclusters || map.getZoom() >= markers.options.disableClusteringAtZoom) && mapBounds.contains(thischildcircle.getLatLng())) {
			thischildcircle.addTo(map);
			} else {
			thischildcircle.removeFrom(map);
		}
	}
)};


// Show visible flags
function showvisibleflags() {
	removeflags();
	flagmarkers.forEach(function(thisflag) { 
		flagid = thisflag.options.alt;
		markerid = flagid.replace('f', 'm');
		if (map.hasLayer(window[markerid])) {
			thisflag.addTo(map);
			} else {
			thisflag.removeFrom(map);
		}
	}
)};

//Remove all flags
function removeflags() {
	allflagmarkers.forEach(function(thisflag) { 
		if (map.hasLayer(thisflag)) {
			thisflag.removeFrom(map);
		}
	}
)};

function deleteflag(flagalt) {
	newArray = [];
	for (var i = 0, len = flagmarkers.length; i < len; i++) {
    	thisflag = flagmarkers[i];
    	if (thisflag.options.alt !== flagalt) { 
        	newArray.push(thisflag);
    	}
	}
	flagmarkers = newArray;
}

function flagLink(gccode,closewindow,flagmarker) {
	var tempflagmarker = window[flagmarker]
	if (typeof tempflagmarker !='undefined') {
		if (tempflagmarker != null) {
			if(map.hasLayer(tempflagmarker)){
				// Remove from flagmarkers array
         		deleteflag(flagmarker);
      		} else {
      			// Add to visible flagmarkers array
      			flagmarkers.push(tempflagmarker);
      		}
      		showvisibleflags();
		}
	}
	location.href = 'gsak://%FF/flagtoggle' + silent + '/' + gccode + '/' + database;
	if (closewindow == true) {
		map.closePopup();
	}
}


function sortLink(gccode,closewindow) {
	location.href = 'gsak://%FF/macro:silent/incsort?' + gccode;
	if (closewindow == true) {
		map.closePopup();
	}
}

function quick(gccode,flag,usersort,flagmarker) {
	var tempflagmarker = window[flagmarker];
	var tempmarker = window[flagmarker.replace("f", "m")];
	if (clickfrommenu == false) {
	if ((flag == true) && (usersort == true)) {
		if (typeof tempflagmarker !='undefined') {
			if(tempflagmarker != null) {
				if(map.hasLayer(tempflagmarker)){
         			// Remove from flagmarkers array
         			deleteflag(flagmarker);
      			} else {
      				// Add to visible flagmarkers array
      				flagmarkers.push(tempflagmarker);
      			}
      			showvisibleflags();
			}
			location.href = 'gsak://%FF/macro:silent/incsortandflag?' + gccode;
		}
	} else {

		if (flag == true) {
			location.href = 'gsak://%FF/flagtoggle' + silent + '/' + gccode + '/' + database;
			if (typeof tempflagmarker !='undefined'){
			 	if(tempflagmarker != null) {
					if(map.hasLayer(tempflagmarker)){
         				// Remove from flagmarkers array
         				deleteflag(flagmarker);
      				} else {
      					// Add to visible flagmarkers array
      					flagmarkers.push(tempflagmarker);
      				}
      				showvisibleflags();
				}
			}
		}
		if (usersort == true) {
			location.href = 'gsak://%FF/macro' + silent + '/incsort?' + gccode;
		}
	}
  }
}


function toggleclustering() {
	if (showclusters) {
		markers.disableClustering();
		showclusters = false;
	} else {
		markers.enableClustering();
		showclusters = true;
	}
}


function hideclusters(e) {
	
}
