﻿var marker_categories = [],
markers = [],
googleMapMarkers = [],
googleMapsVar = {
	'map_current_cat': -1,
	'map_current_zoom': 6,
	'map_cleared': false,
	'blank_icon': 'blank.png',
	'map_moved': false,
	'map': null,
	'mapdiv': 'map_canvas',
	'mgr': null,
	'marker_popup': true,
	'showdirections': null,
	'directions_locale': 'uk',
	'directions_searchdiv': 'DirectionsSearch',
	'directions_resultdiv': 'Directions',
	'directions_end': null,
	'directionstext': {
		'invalid_address': 'No corresponding geographic location could be found for one of the specified addresses. This may be due to the fact that the address is relatively new, or it may be incorrect.',
		'search_label': 'Your directions from : ',
		'valid_search': 'Please enter a valid address',
		'search_button': '&gt'
	},
	'nocampsitestext': 'There are currently no campsites visible.',
	'returntoeurotext':'Return to map of Europe',
	'tooltip': null,
	'mapmarkers': new Array(),
	'googlemaptype':G_PHYSICAL_MAP,
	'googlecontrols':[new GLargeMapControl3D()],
	'nocampsitepopup': false,
	'popupheight': '250px',
	'popupwidth': '250px',
	'selectedFeatures':[],
	'groupSelectedFeature': [],
	'campsiteminzoom': 0,
	'campsitemaxzoom': 0,
	'europecontrol': null
};
var getElementsByClassName = function (className, tag, elm){
	if (document.getElementsByClassName) {
		getElementsByClassName = function (className, tag, elm) {
			elm = elm || document;
			var elements = elm.getElementsByClassName(className),
				nodeName = (tag)? new RegExp("\\b" + tag + "\\b", "i") : null,
				returnElements = [],
				current;
			for(var i=0, il=elements.length; i<il; i+=1){
				current = elements[i];
				if(!nodeName || nodeName.test(current.nodeName)) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	else if (document.evaluate) {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = "",
				xhtmlNamespace = "http://www.w3.org/1999/xhtml",
				namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
				returnElements = [],
				elements,
				node;
			for(var j=0, jl=classes.length; j<jl; j+=1){
				classesToCheck += "[contains(concat(' ', @class, ' '), ' " + classes[j] + " ')]";
			}
			try	{
				elements = document.evaluate(".//" + tag + classesToCheck, elm, namespaceResolver, 0, null);
			}
			catch (e) {
				elements = document.evaluate(".//" + tag + classesToCheck, elm, null, 0, null);
			}
			while ((node = elements.iterateNext())) {
				returnElements.push(node);
			}
			return returnElements;
		};
	}
	else {
		getElementsByClassName = function (className, tag, elm) {
			tag = tag || "*";
			elm = elm || document;
			var classes = className.split(" "),
				classesToCheck = [],
				elements = (tag === "*" && elm.all)? elm.all : elm.getElementsByTagName(tag),
				current,
				returnElements = [],
				match;
			for(var k=0, kl=classes.length; k<kl; k+=1){
				classesToCheck.push(new RegExp("(^|\\s)" + classes[k] + "(\\s|$)"));
			}
			for(var l=0, ll=elements.length; l<ll; l+=1){
				current = elements[l];
				match = false;
				for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
					match = classesToCheck[m].test(current.className);
					if (!match) {
						break;
					}
				}
				if (match) {
					returnElements.push(current);
				}
			}
			return returnElements;
		};
	}
	return getElementsByClassName(className, tag, elm);
};
function googleMapsCreateMarker(point, markerinfo) {
	var marker, mapIcon = new GIcon();
	var mapIcon2 = new GIcon();
	if (markerinfo[1] === true) {
		mapIcon.image = googleMapsVar.blank_icon;
	} else {
		mapIcon.image = marker_categories[googleMapsVar.map_current_cat][1];
	}
	mapIcon.iconSize = new GSize(32, 37);
	mapIcon.shadowSize = new GSize(22, 20);
	mapIcon.iconAnchor = new GPoint(16, 37);
	mapIcon.infoWindowAnchor = new GPoint(5, 1);
	mapIcon2.iconSize = new GSize(0, 0);
	mapIcon2.shadowSize = new GSize(0, 0);
	mapIcon2.iconAnchor = new GPoint(0, 0);
	mapIcon2.infoWindowAnchor = new GPoint(0, 0);
	markerOptions = {
		icon: mapIcon
	};
	if (markerinfo[4] !== "" && markerinfo[1] === true) {
		opts = {
			"icon": mapIcon2,
			"clickable": true,
			"labelText": markerinfo[0],
			"labelOffset": new GSize(-50, 0)
		};
	} else if (markerinfo[5] !== "" && markerinfo[4] == "" && markerinfo[1] === true) {
		opts = {
			"icon": mapIcon2,
			"clickable": true,
			"labelText": markerinfo[0],
			"labelOffset": new GSize(0, 0)
		};
	} else {
		opts = {
			"icon": mapIcon,
			"clickable": false,
			"labelText": markerinfo[0],
			"labelOffset": new GSize(-50, 0)
		};
	}
	if (markerinfo[1] === true) {
		marker = new LabeledMarker(point, opts);
	} else {
		marker = new GMarker(point, markerOptions);
	}
	if (markerinfo[1] === false) {
		marker.tooltip = '<div class="tooltip"><nobr>' + markerinfo[0] + '<\/nobr><\/div>';
		GEvent.addListener(marker, "mouseover", function () {
			googleMapsShowTooltip(marker);
		});
		GEvent.addListener(marker, "mouseout", function () {
			googleMapsVar.tooltip.style.visibility = "hidden";
		});
	}

	if (googleMapsVar.nocampsitepopup === true && googleMapsVar.map_current_cat == "0") {
	
	} else {
	    GEvent.addListener(marker, "click", function () {
		    if (markerinfo[4] !== "" && googleMapsVar.marker_popup === true) {
			    var myHtml = "<iframe src='" + markerinfo[4] + "' style='height: " + googleMapsVar.popupheight + "; width: " + googleMapsVar.popupwidth + "; ' scrolling='auto' frameborder='0'></iframe>";
			    googleMapsVar.map.openInfoWindowHtml(point, myHtml);
		    } else if (googleMapsVar.marker_popup === false && markerinfo.length >= 7 && markerinfo[6] !== "") {
			    window.location = markerinfo[6];
		    } else if (googleMapsVar.marker_popup === false && markerinfo[4] !== "") {
			    window.location = markerinfo[4];
		    } else if (markerinfo[5] !== "") {
			    googleMapsVar.map.setCenter(new GLatLng(markerinfo[2], markerinfo[3]), parseInt(markerinfo[5]));
		    }
		    googleMapsVar.tooltip.style.visibility = "hidden";
	    });
	}
	return marker;
}
function googleMapsShowTooltip(marker) {
	googleMapsVar.tooltip.innerHTML = "<div class=\"btn\"><span class=\"btnLeft\"><span class=\"btnRight\">" + marker.tooltip + "</span></span></div>";
	var point = googleMapsVar.map.getCurrentMapType().getProjection().fromLatLngToPixel(googleMapsVar.map.fromDivPixelToLatLng(new GPoint(0, 0), true), googleMapsVar.map.getZoom());
	var offset = googleMapsVar.map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(), googleMapsVar.map.getZoom());
	var anchor = marker.getIcon().iconAnchor;
	var width = parseInt(0 - (googleMapsVar.tooltip.clientWidth / 2) + 19);
	var height = googleMapsVar.tooltip.clientHeight;
	var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width, offset.y - point.y - anchor.y - height));
	pos.apply(googleMapsVar.tooltip);
	googleMapsVar.tooltip.style.visibility = "visible";
}
function googleMapsCampsiteList() {
	
	var point, campsitesinfo = "";
	var count = 0;
	var curr_zoom= googleMapsVar.map.getZoom();
	var bounds = googleMapsVar.map.getBounds();

	for (i in googleMapMarkers[0]) {
		point = googleMapMarkers[0][i].getLatLng(); // need to find which ones are in view then match with the large array
	if (bounds.containsLatLng(point)) {
	
    var zoom_max, zoom_min;
	if (googleMapsVar.campsiteminzoom > 0){
	    zoom_min = googleMapsVar.campsiteminzoom;
	} else {
	    zoom_min = marker_categories[0][2];
	}
	if (googleMapsVar.campsitemaxzoom > 0){
	    zoom_max = googleMapsVar.campsitemaxzoom;
	} else {
	    zoom_max = marker_categories[0][3];
	}	

	if (curr_zoom >= parseInt(zoom_min) && curr_zoom <= parseInt(zoom_max)) {
			campsitesinfo += "<li> <a href=\"" + markers[0][i][6] + "\">" + markers[0][i][0] + " &#187; </a></li>";
			count++;
			}
		}
	}
	if (campsitesinfo != "") {
		document.getElementById("visible_campsites_list").innerHTML = "<ul>" + campsitesinfo + "</ul>";
	} else {
		document.getElementById("visible_campsites_list").innerHTML = "<p>" + googleMapsVar.nocampsitestext +"</p>";
	}
}
function advancedSearch() { //document.getElementById("acc_types").getElementsByTagName("input"); 
	GEvent.addListener(googleMapsVar.map, "moveend", function () {
		googleMapsCampsiteList();
		if (!googleMapsVar.map_moved) {
		     
		    googleMapsVar.map.addControl(googleMapsVar.europecontrol);
		  
		    googleMapsVar.map_moved = true;
		}
	});
	googleMapsCampsiteList();
}
function googleMapsAdvanceCheck() {
	catid = 0;
	googleMapsVar.map_current_cat = catid;
	var acc_checkcount = 0,
	suitable_for_checkcount = 0,
	suitable_for_checked = [],
	acc_checked = [],
	matched_acc = [],
	matched = [];
	var acc_types = document.getElementById("acc_types").getElementsByTagName("input");
	for (i in acc_types) {
		if (acc_types[i].checked) {
			acc_checked[acc_checkcount] = acc_types[i].value;
			acc_checkcount++;
		}
	}
	var suitable_for = document.getElementById("suitable_for").getElementsByTagName("input");
	for (i in suitable_for) {
		if (suitable_for[i].checked) {
			suitable_for_checked[suitable_for_checkcount] = suitable_for[i].value;
			suitable_for_checkcount++;
		}
	}
	if (acc_checkcount == 0 && suitable_for_checkcount == 0) {
		for (i in googleMapMarkers[catid]) {
			googleMapsVar.mgr.removeMarker(googleMapMarkers[catid][i]);
		}
		
		googleMapMarkers[catid].length =[];
		googleMapsShowCategory(catid);
		googleMapsCampsiteList();
		return true;
	} else { if (acc_checkcount > 0) {
			var num = 0,
			matches = 0;
			for (i in markers[catid]) {
				matches = 0;
				for (j in acc_checked) {
					var acc = markers[catid][i][8].split(",");
					for (k in acc) {
						if (acc_checked[j] == acc[k]) {
							matches++;
						}
					}
				}
				if (matches == acc_checked.length) {
					matched_acc[i] = markers[catid][i];
				}
			}
		} else {
			matched_acc = markers[catid];
		}
		if (suitable_for_checkcount > 0) {
			matches = 0,
			num = 0;
			for (i in matched_acc) {
				matches = 0;
				for (j in suitable_for_checked) {
					var suit = matched_acc[i][7].split(",");
					for (k in suit) {
						if (suitable_for_checked[j] == suit[k]) {
							matches++;
						}
					}
				}
				if (matches == suitable_for_checked.length) {
					matched[i] = matched_acc[i];
					num++;
				}
			}
		} else {
			matched = matched_acc;
			num++;
		}
	}
	for (i in googleMapMarkers[catid]) {
		googleMapsVar.mgr.removeMarker(googleMapMarkers[catid][i]);
	}

	googleMapMarkers[catid] = [];
	if (num > 0) {
		num = 0;
		for (i in matched) {
			var point = new GLatLng(matched[i][2], matched[i][3]);
			googleMapMarkers[catid][i] = googleMapsCreateMarker(point, matched[i]);
			num++;
		}
	var zoom_max, zoom_min;
	if (googleMapsVar.map_current_cat == 0 && googleMapsVar.campsiteminzoom  > 0){
	    zoom_min = googleMapsVar.campsiteminzoom;
	} else {
	    zoom_min = marker_categories[googleMapsVar.map_current_cat][2];
	}
	if (googleMapsVar.map_current_cat == 0 && googleMapsVar.campsitemaxzoom  > 0){
	    zoom_max = googleMapsVar.campsiteminzoom;
	} else {
	    zoom_max = marker_categories[googleMapsVar.map_current_cat][3];
	}	
		googleMapsVar.mgr.addMarkers(googleMapMarkers[catid], parseInt(zoom_min), parseInt(zoom_max));
		
		googleMapsCampsiteList();
	}
	var curr_zoom= googleMapsVar.map.getZoom();

	
	
	if (curr_zoom >= parseInt(zoom_min) && curr_zoom <= parseInt(zoom_max)) {
	    googleMapsVar.mgr.refresh();
	}
}
function googleMapsAdvanceCheckv2(features,group) {
    catid = 0;
	googleMapsVar.map_current_cat = catid;
	matched = [];
	var skip = false;
   

    if ( typeof group != "undefined" && group !="") {
           
        if (typeof googleMapsVar.groupSelectedFeature[group] != "undefined") {
            if (googleMapsVar.groupSelectedFeature[group] != features) {

                for (i in googleMapsVar.selectedFeatures) { 
                
                     if (googleMapsVar.selectedFeatures[i].toLowerCase() == googleMapsVar.groupSelectedFeature[group].toLowerCase()) {
                        
                        googleMapsVar.selectedFeatures.splice(i,1);
                     }
            
                } 
                 googleMapsVar.groupSelectedFeature[group] = features;
            } else { 
            
                skip = true;
                }
        
        } else {

            googleMapsVar.groupSelectedFeature[group] = features;
        }
        
    }
    if (!skip) {
    if (!(features in oc(googleMapsVar.selectedFeatures))) {
         if (features != "") {
            googleMapsVar.selectedFeatures.push(features); 
         }

    } else {
        for (i in googleMapsVar.selectedFeatures) { 
            
             if (googleMapsVar.selectedFeatures[i] == features) {
                googleMapsVar.selectedFeatures.splice(i,1);
             }
        
        } 
       
    }
    }
   
    

    var num = 0;
    var point;
    var markerCategories = [];
    
    for (i in markers[catid]) {

		    OK = true;
            for (j in googleMapsVar.selectedFeatures) {
        
                count = 0;
                markerCategories= markers[catid][i][7].split(",");
                for (k in markerCategories) {
               
                    
                    if (markerCategories[k] == googleMapsVar.selectedFeatures[j]) {
                        count++;
                    }   
                 
                }
               
                if (count == 0) {
                    
                    OK = false;
                    break;
                    
                }
            
            } 
            if (OK == true) {

                matched[i] =  markers[catid][i];
                num++;
     
            }

    }

	var zoom_max, zoom_min;
	if (googleMapsVar.map_current_cat == 0 && googleMapsVar.campsiteminzoom  > 0){
	    zoom_min = googleMapsVar.campsiteminzoom;
	} else {
	    zoom_min = marker_categories[googleMapsVar.map_current_cat][2];
	}
	if (googleMapsVar.map_current_cat == 0 && googleMapsVar.campsitemaxzoom > 0){
	    zoom_max = googleMapsVar.campsiteminzoom;
	} else {
	    zoom_max = marker_categories[googleMapsVar.map_current_cat][3];
	}	
    for (i in googleMapMarkers[catid]) {
		    googleMapsVar.mgr.removeMarker(googleMapMarkers[catid][i]);
	    }

	    googleMapMarkers[catid] = [];
	    if (num> 0) {

		    num = 0;
		    for (i in matched) {
			    var point = new GLatLng(matched[i][2], matched[i][3]);
			    googleMapMarkers[catid][i] = googleMapsCreateMarker(point, matched[i]);
			    num++;
		    }
		    googleMapsVar.mgr.addMarkers(googleMapMarkers[catid], parseInt(zoom_min), parseInt(zoom_max));
    		
		    
	    }



    googleMapsCampsiteList();

	var curr_zoom= googleMapsVar.map.getZoom();

	
	
	if (curr_zoom >= parseInt(zoom_min) && curr_zoom <= parseInt(zoom_max)) {
	    googleMapsVar.mgr.refresh();
	}
}



function oc(a)
{
  var o = {};
  for(var i=0;i<a.length;i++)
  {
    o[a[i]]='';
  }
  return o;
}
function googleMapsinitialize(options) {
	var default_args = {
		'latitude': 46.965259400349275,
		'longitude': 3.31787109375,
		'zoom': googleMapsVar.map_current_zoom,
		'showdirections': false,
		'showadvancedoptions': false,
		'categories': '',
		'campsites': '',
		'nocampsitepopup':false,
		'showJSCats': false
	};
	for (var index in default_args) {
		if (typeof options[index] == "undefined") options[index] = default_args[index];
	}
	if (GBrowserIsCompatible()) {
		googleMapsVar.map = new GMap2(document.getElementById(googleMapsVar.mapdiv));
		if (options.showdirections === true) {
			googleMapsDirectionsInit();
			googleMapsVar.directions_end = options.latitude + "," + options.longitude;
		}
		googleMapsVar.map.setCenter(new GLatLng(options.latitude, options.longitude), options.zoom);
		googleMapsVar.map.setMapType(googleMapsVar.googlemaptype); //map.setUIToDefault();
		for (i in googleMapsVar.googlecontrols ) {
		googleMapsVar.map.addControl(googleMapsVar.googlecontrols[i]);
		
		}

		

	}
	googleMapsVar.tooltip = document.createElement("div");
	googleMapsVar.map.getPane(G_MAP_FLOAT_PANE).appendChild(googleMapsVar.tooltip);
	googleMapsVar.tooltip.style.visibility = "hidden";
	googleMapsSetupMarkers(options.categories.toLowerCase());
	if (options.showadvancedoptions === true) {	
	advancedSearch();
	googleMapsVar.europecontrol = new ReturnToEuropeControl();
	
	}
	if (options.showJSCats === true) {	
		googleMapsShowJSCats(options.categories);
	
	}
	if (options.campsites != "") googleMapsShowCampsites(options.campsites);
}
function googleMapsShowJSCats(categories) {
	var i;
	var markerContain = document.getElementById("gmapsMarkerDiv");
	var markerContainContent = ""; 
	
	for (i in marker_categories) {
		
		if (categories.toLowerCase().match(marker_categories[i][0].toLowerCase())) {
		
			markerContainContent += "<span class='category'><img src='" +marker_categories[i][1] + "' alt='" +marker_categories[i][0] + "'><strong>" +marker_categories[i][0] + "</strong></span> ";
		} 
	}
	markerContain.innerHTML = markerContainContent;

}
function googleMapsSetupMarkers(categories) {
	googleMapsVar.mgr = new MarkerManager(googleMapsVar.map);
	var i;
	for (i in marker_categories) {
		googleMapMarkers[i] = [];
		if (categories.match(marker_categories[i][0].toLowerCase())) {
			googleMapsShowCategory(i);
		}
	}
}
function googleMapsShowCategory(catid) {
	googleMapsVar.map_current_cat = catid;
	var markers2 = [],
	num = 0;
	var zoom_max, zoom_min;
	if (catid == 0 && googleMapsVar.campsiteminzoom  > 0){
	    zoom_min = googleMapsVar.campsiteminzoom;
	} else {
	    zoom_min = marker_categories[catid][2];
	}
	if (catid == 0 && googleMapsVar.campsitemaxzoom > 0){
	    zoom_max = googleMapsVar.campsitemaxzoom;
	} else {
	    zoom_max = marker_categories[catid][3];
	}
		
	if (googleMapMarkers[catid].length == 0) {
		for (i in markers[catid]) {
			var point = new GLatLng(markers[catid][i][2], markers[catid][i][3]);
			googleMapMarkers[catid][i] = googleMapsCreateMarker(point, markers[catid][i]);
			num++;
		}
		
		googleMapsVar.mgr.addMarkers(googleMapMarkers[catid], parseInt(zoom_min), parseInt(zoom_max));
		
	} else {
		for (i in googleMapMarkers[catid]) {
			googleMapsVar.mgr.removeMarker(googleMapMarkers[catid][i]);
		}
		googleMapMarkers[catid] = [];
	}
	var curr_zoom= googleMapsVar.map.getZoom();

	
	
	if (curr_zoom >= parseInt(zoom_min) && curr_zoom <= parseInt(zoom_max)) {
	    googleMapsVar.mgr.refresh();
	}
}
function googleMapsShowCampsites(campsiteList) {
	var catid = 0; // IMPORTANT: This function assumes the CAMPSITE category is the first one in the array....
	googleMapsVar.mgr = new MarkerManager(googleMapsVar.map);
	googleMapsVar.map_current_cat = catid;

	
	
	
	var aCodes = campsiteList.split(",");
	if (aCodes[0].charAt(0) != "-") {
	    for (i in aCodes) {
		    if (markers[catid][aCodes[i]] != null) {
			    var point = new GLatLng(markers[catid][aCodes[i]][2], markers[catid][aCodes[i]][3]);
			    googleMapsVar.mgr.addMarker(googleMapsCreateMarker(point, markers[catid][aCodes[i]]), 1, 17);
		    }
	    }
	} else {
	    for (i in aCodes) {
	        aCodes[i] = aCodes[i].substring(1);
	    }
	    for (j in markers[catid]) {
	        //console.log(j);
	        if (!(j in oc(aCodes))) {
    	        var point = new GLatLng(markers[catid][j][2], markers[catid][j][3]);
			    googleMapsVar.mgr.addMarker(googleMapsCreateMarker(point, markers[catid][j]), 1, 17); 
	        } else { 
	        //console.log("skip : " + j );
	        }
	    }
	
	
	}


	
	
	
	    googleMapsVar.mgr.refresh();

}
function googleMapsDirectionsInit() {
	var mapDiv = document.getElementById(googleMapsVar.mapdiv),
	parentDiv = mapDiv.parentNode,
	newDiv = document.createElement("div");
	newDiv.setAttribute("id", "Directions");
	newDiv.innerHTML = "";
	parentDiv.insertBefore(newDiv, mapDiv.nextSibling);
	var mapDiv2 = document.getElementById(googleMapsVar.mapdiv),
	newDiv2 = document.createElement("div"),
	parentDiv2 = mapDiv2.parentNode;
	newDiv2.setAttribute("id", googleMapsVar.directions_searchdiv);
	newDiv2.innerHTML = googleMapsVar.directionstext.search_label + "<input type='text' id='startAddress' name='startAddress' onkeypress='return googleMapscheckEnter(event)'><button type='button' onclick='return googleMapsdoDirections();'>" + googleMapsVar.directionstext.search_button + "</button>";
	parentDiv2.insertBefore(newDiv2, mapDiv2.nextSibling);
	directionsPanel = document.getElementById(googleMapsVar.directions_resultdiv);
	googleMapsVar.directions = new GDirections(googleMapsVar.map, directionsPanel);
}
function googleMapsdoDirections() {
	try {
		document.getElementById(googleMapsVar.directions_resultdiv).innerHTML = '';
		GEvent.addListener(googleMapsVar.directions, "error", googleMapshandleErrors);
		if (document.getElementById("startAddress").value != '') {
			googleMapsVar.directions.load("from: " + document.getElementById("startAddress").value + ", " + googleMapsVar.directions_locale + " to: " + googleMapsVar.directions_end);
		} else {
			document.getElementById(googleMapsVar.directions_resultdiv).innerHTML = googleMapsVar.directionstext.valid_search;
		}
		return false;
	} catch(err) {}
}
function googleMapscheckEnter(e) {
	var characterCode;
	if (e && e.which) {
		e = e;
		characterCode = e.which;
	} else {
		e = event;
		characterCode = e.keyCode;
	}
	if (characterCode == 13) {
		googleMapsdoDirections();
        if(e.preventDefault){ e.preventDefault()}
		return false;
	} else {
		return true;
	}
}
function googleMapshandleErrors() {
	try {
		if (googleMapsVar.directions.getStatus().code == G_GEO_UNKNOWN_ADDRESS) document.getElementById(googleMapsVar.directions_resultdiv).innerHTML = googleMapsVar.directionstext.invalid_address;
		else if (googleMapsVar.directions.getStatus().code == G_GEO_SERVER_ERROR) document.getElementById(googleMapsVar.directions_resultdiv).innerHTML = "A geocoding or directions request could not be successfully processed, yet the exact reason for the failure is not known.\n Error code: " + googleMapsVar.directions.getStatus().code;
		else if (googleMapsVar.directions.getStatus().code == G_GEO_MISSING_QUERY) document.getElementById("Directions").innerHTML = "The HTTP q parameter was either missing or had no value. For geocoder requests, this means that an empty address was specified as input. For directions requests, this means that no query was specified in the input.\n Error code: " + googleMapsVar.directions.getStatus().code;
		else if (googleMapsVar.directions.getStatus().code == G_GEO_BAD_KEY) document.getElementById(googleMapsVar.directions_resultdiv).innerHTML = "The given key is either invalid or does not match the domain for which it was given. \n Error code: " + googleMapsVar.directions.getStatus().code;
		else if (googleMapsVar.directions.getStatus().code == G_GEO_BAD_REQUEST) document.getElementById(googleMapsVar.directions_resultdiv).innerHTML = "A directions request could not be successfully parsed.\n Error code: " + googleMapsVar.directions.getStatus().code;
		else document.getElementById(googleMapsVar.directions_resultdiv).innerHTML = "An unknown error occurred.";
	} catch(err) {
		alert(err);
	}
}
/*
* LabeledMarker Class
*
* Copyright 2007 Mike Purvis (http://uwmike.com)
* 
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* 
*       http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* This class extends the Maps API's standard GMarker class with the ability
* to support markers with textual labels. Please see articles here:
*
*       http://googlemapsbook.com/2007/01/22/extending-gmarker/
*       http://googlemapsbook.com/2007/03/06/clickable-labeledmarker/
*/
/* Constructor */
function LabeledMarker(latlng, options) {
	this.latlng = latlng;
	this.labelText = options.labelText || "";
	this.labelClass = options.labelClass || "markerLabel";
	this.labelOffset = options.labelOffset || new GSize(0, 0);
	this.clickable = options.clickable || true;
	if (options.draggable) { // This version of LabeledMarker doesn't support dragging.
		options.draggable = false;
	}
	GMarker.apply(this, arguments);
}
/* It's a limitation of JavaScript inheritance that we can't conveniently
   extend GMarker without having to run its constructor. In order for the
   constructor to run, it requires some dummy GLatLng. */
LabeledMarker.prototype = new GMarker(new GLatLng(0, 0)); // Creates the text div that goes over the marker.
LabeledMarker.prototype.initialize = function (map) { // Do the GMarker constructor first.
	GMarker.prototype.initialize.apply(this, arguments);
	var div = document.createElement("div");
	div.className = this.labelClass;
	div.innerHTML = "<div class=\"btn\"><span class=\"btnLeft\"><span class=\"btnRight\"><nobr>" + this.labelText + "</nobr></span></span></div>";
	div.style.position = "absolute";
	map.getPane(G_MAP_MARKER_PANE).appendChild(div);
	if (this.clickable) { // Pass through events fired on the text div to the marker.
		var eventPassthrus = ['click', 'dblclick', 'mousedown', 'mouseup', 'mouseover', 'mouseout'];
		for (var i = 0; i < eventPassthrus.length; i++) {
			var name = eventPassthrus[i];
			GEvent.addDomListener(div, name, newEventPassthru(this, name));
		} // Mouseover behaviour for the cursor.
		div.style.cursor = "pointer";
	}
	this.map = map;
	this.div = div;
}
function newEventPassthru(obj, event) {
	return function () {
		GEvent.trigger(obj, event);
	};
} // Redraw the rectangle based on the current projection and zoom level
LabeledMarker.prototype.redraw = function (force) {
	GMarker.prototype.redraw.apply(this, arguments); // We only need to do anything if the coordinate system has changed
	if (!force) return; // Calculate the DIV coordinates of two opposite corners of our bounds to
	// get the size and position of our rectangle
	var p = this.map.fromLatLngToDivPixel(this.latlng);
	var z = GOverlay.getZIndex(this.latlng.lat()); // Now position our DIV based on the DIV coordinates of our bounds
	this.div.style.left = (p.x + this.labelOffset.width) + "px";
	this.div.style.top = (p.y + this.labelOffset.height) + "px";
	this.div.style.zIndex = z + 1; // in front of the marker
} // Remove the main DIV from the map pane, destroy event handlers
LabeledMarker.prototype.remove = function () {
	GEvent.clearInstanceListeners(this.div);
	this.div.parentNode.removeChild(this.div);
	this.div = null;
	GMarker.prototype.remove.apply(this, arguments);
}
/* 
 * MarkerManager, v1.0
 * Copyright (c) 2007 Google Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 *
 *
 * Author: Doug Ricket, others
 * 
 * Marker manager is an interface between the map and the user, designed
 * to manage adding and removing many points when the viewport changes.
 *
 *
 * Algorithm: The MM places its markers onto a grid, similar to the map tiles.
 * When the user moves the viewport, the MM computes which grid cells have
 * entered or left the viewport, and shows or hides all the markers in those
 * cells.
 * (If the users scrolls the viewport beyond the markers that are loaded,
 * no markers will be visible until the EVENT_moveend triggers an update.)
 *
 * In practical consequences, this allows 10,000 markers to be distributed over
 * a large area, and as long as only 100-200 are visible in any given viewport,
 * the user will see good performance corresponding to the 100 visible markers,
 * rather than poor performance corresponding to the total 10,000 markers.
 *
 * Note that some code is optimized for speed over space,
 * with the goal of accommodating thousands of markers.
 *
 */
function MarkerManager(map, opt_opts) {
	var me = this;
	me.map_ = map;
	me.mapZoom_ = map.getZoom();
	me.projection_ = map.getCurrentMapType().getProjection();
	opt_opts = opt_opts || {};
	me.tileSize_ = MarkerManager.DEFAULT_TILE_SIZE_;
	var maxZoom = MarkerManager.DEFAULT_MAX_ZOOM_;
	if (opt_opts.maxZoom != undefined) {
		maxZoom = opt_opts.maxZoom;
	}
	me.maxZoom_ = maxZoom;
	me.trackMarkers_ = opt_opts.trackMarkers;
	var padding;
	if (typeof opt_opts.borderPadding == "number") {
		padding = opt_opts.borderPadding;
	} else {
		padding = MarkerManager.DEFAULT_BORDER_PADDING_;
	} // The padding in pixels beyond the viewport, where we will pre-load markers.
	me.swPadding_ = new GSize(-padding, padding);
	me.nePadding_ = new GSize(padding, -padding);
	me.borderPadding_ = padding;
	me.gridWidth_ = [];
	me.grid_ = [];
	me.grid_[maxZoom] = [];
	me.numMarkers_ = [];
	me.numMarkers_[maxZoom] = 0;
	GEvent.bind(map, "moveend", me, me.onMapMoveEnd_); // NOTE: These two closures provide easy access to the map.
	// They are used as callbacks, not as methods.
	me.removeOverlay_ = function (marker) {
		map.removeOverlay(marker);
		me.shownMarkers_--;
	};
	me.addOverlay_ = function (marker) {
		map.addOverlay(marker);
		me.shownMarkers_++;
	};
	me.resetManager_();
	me.shownMarkers_ = 0;
	me.shownBounds_ = me.getMapGridBounds_();
}; // Static constants:
MarkerManager.DEFAULT_TILE_SIZE_ = 1024;
MarkerManager.DEFAULT_MAX_ZOOM_ = 17;
MarkerManager.DEFAULT_BORDER_PADDING_ = 100;
MarkerManager.MERCATOR_ZOOM_LEVEL_ZERO_RANGE = 256;
MarkerManager.prototype.resetManager_ = function () {
	var me = this;
	var mapWidth = MarkerManager.MERCATOR_ZOOM_LEVEL_ZERO_RANGE;
	for (var zoom = 0; zoom <= me.maxZoom_; ++zoom) {
		me.grid_[zoom] = [];
		me.numMarkers_[zoom] = 0;
		me.gridWidth_[zoom] = Math.ceil(mapWidth / me.tileSize_);
		mapWidth <<= 1;
	}
};
MarkerManager.prototype.clearMarkers = function () {
	var me = this;
	me.processAll_(me.shownBounds_, me.removeOverlay_);
	me.resetManager_();
};
MarkerManager.prototype.getTilePoint_ = function (latlng, zoom, padding) {
	var pixelPoint = this.projection_.fromLatLngToPixel(latlng, zoom);
	return new GPoint(Math.floor((pixelPoint.x + padding.width) / this.tileSize_), Math.floor((pixelPoint.y + padding.height) / this.tileSize_));
};
MarkerManager.prototype.addMarkerBatch_ = function (marker, minZoom, maxZoom) {
	var mPoint = marker.getPoint(); // Tracking markers is expensive, so we do this only if the
	// user explicitly requested it when creating marker manager.
	if (this.trackMarkers_) {
		GEvent.bind(marker, "changed", this, this.onMarkerMoved_);
	}
	var gridPoint = this.getTilePoint_(mPoint, maxZoom, GSize.ZERO);
	for (var zoom = maxZoom; zoom >= minZoom; zoom--) {
		var cell = this.getGridCellCreate_(gridPoint.x, gridPoint.y, zoom);
		cell.push(marker);
		gridPoint.x = gridPoint.x >> 1;
		gridPoint.y = gridPoint.y >> 1;
	}
};
MarkerManager.prototype.isGridPointVisible_ = function (point) {
	var me = this;
	var vertical = me.shownBounds_.minY <= point.y && point.y <= me.shownBounds_.maxY;
	var minX = me.shownBounds_.minX;
	var horizontal = minX <= point.x && point.x <= me.shownBounds_.maxX;
	if (!horizontal && minX < 0) {
		var width = me.gridWidth_[me.shownBounds_.z];
		horizontal = minX + width <= point.x && point.x <= width - 1;
	}
	return vertical && horizontal;
}
MarkerManager.prototype.onMarkerMoved_ = function (marker, oldPoint, newPoint) {
	var me = this;
	var zoom = me.maxZoom_;
	var changed = false;
	var oldGrid = me.getTilePoint_(oldPoint, zoom, GSize.ZERO);
	var newGrid = me.getTilePoint_(newPoint, zoom, GSize.ZERO);
	while (zoom >= 0 && (oldGrid.x != newGrid.x || oldGrid.y != newGrid.y)) {
		var cell = me.getGridCellNoCreate_(oldGrid.x, oldGrid.y, zoom);
		if (cell) {
			if (me.removeFromArray(cell, marker)) {
				me.getGridCellCreate_(newGrid.x, newGrid.y, zoom).push(marker);
			}
		}
		if (zoom == me.mapZoom_) {
			if (me.isGridPointVisible_(oldGrid)) {
				if (!me.isGridPointVisible_(newGrid)) {
					me.removeOverlay_(marker);
					changed = true;
				}
			} else { if (me.isGridPointVisible_(newGrid)) {
					me.addOverlay_(marker);
					changed = true;
				}
			}
		}
		oldGrid.x = oldGrid.x >> 1;
		oldGrid.y = oldGrid.y >> 1;
		newGrid.x = newGrid.x >> 1;
		newGrid.y = newGrid.y >> 1;
		--zoom;
	}
	if (changed) {
		me.notifyListeners_();
	}
};
MarkerManager.prototype.removeMarker = function (marker) {
	var me = this;
	var zoom = me.maxZoom_;
	var changed = false;
	var point = marker.getPoint();
	var grid = me.getTilePoint_(point, zoom, GSize.ZERO);
	while (zoom >= 0) {
		var cell = me.getGridCellNoCreate_(grid.x, grid.y, zoom);
		if (cell) {
			me.removeFromArray(cell, marker);
		} // For the current zoom we also need to update the map. Markers that no
		// longer are visible are removed from the map. This also lets us keep the count
		// of visible markers up to date.
		if (zoom == me.mapZoom_) {
			if (me.isGridPointVisible_(grid)) {
				me.removeOverlay_(marker);
				changed = true;
			}
		}
		grid.x = grid.x >> 1;
		grid.y = grid.y >> 1;
		--zoom;
	}
	if (changed) {
		me.notifyListeners_();
	}
};
MarkerManager.prototype.addMarkers = function (markers, minZoom, opt_maxZoom) {
	var maxZoom = this.getOptMaxZoom_(opt_maxZoom);
	for (i in markers) {
		this.addMarkerBatch_(markers[i], minZoom, maxZoom);
	}
	this.numMarkers_[minZoom] += markers.length;
};
MarkerManager.prototype.getOptMaxZoom_ = function (opt_maxZoom) {
	return opt_maxZoom != undefined ? opt_maxZoom : this.maxZoom_;
}
MarkerManager.prototype.getMarkerCount = function (zoom) {
	var total = 0;
	for (var z = 0; z <= zoom; z++) {
		total += this.numMarkers_[z];
	}
	return total;
};
MarkerManager.prototype.addMarker = function (marker, minZoom, opt_maxZoom) {
	var me = this;
	var maxZoom = this.getOptMaxZoom_(opt_maxZoom);
	me.addMarkerBatch_(marker, minZoom, maxZoom);
	var gridPoint = me.getTilePoint_(marker.getPoint(), me.mapZoom_, GSize.ZERO);
	if (me.isGridPointVisible_(gridPoint) && minZoom <= me.shownBounds_.z && me.shownBounds_.z <= maxZoom) {
		me.addOverlay_(marker);
		me.notifyListeners_();
	}
	this.numMarkers_[minZoom]++;
};
GBounds.prototype.containsPoint = function (point) {
	var outer = this;
	return (outer.minX <= point.x && outer.maxX >= point.x && outer.minY <= point.y && outer.maxY >= point.y);
}
MarkerManager.prototype.getGridCellCreate_ = function (x, y, z) {
	var grid = this.grid_[z];
	if (x < 0) {
		x += this.gridWidth_[z];
	}
	var gridCol = grid[x];
	if (!gridCol) {
		gridCol = grid[x] = [];
		return gridCol[y] = [];
	}
	var gridCell = gridCol[y];
	if (!gridCell) {
		return gridCol[y] = [];
	}
	return gridCell;
};
MarkerManager.prototype.getGridCellNoCreate_ = function (x, y, z) {
	var grid = this.grid_[z];
	if (x < 0) {
		x += this.gridWidth_[z];
	}
	var gridCol = grid[x];
	return gridCol ? gridCol[y] : undefined;
};
MarkerManager.prototype.getGridBounds_ = function (bounds, zoom, swPadding, nePadding) {
	zoom = Math.min(zoom, this.maxZoom_);
	var bl = bounds.getSouthWest();
	var tr = bounds.getNorthEast();
	var sw = this.getTilePoint_(bl, zoom, swPadding);
	var ne = this.getTilePoint_(tr, zoom, nePadding);
	var gw = this.gridWidth_[zoom]; // Crossing the prime meridian requires correction of bounds.
	if (tr.lng() < bl.lng() || ne.x < sw.x) {
		sw.x -= gw;
	}
	if (ne.x - sw.x + 1 >= gw) { // Computed grid bounds are larger than the world; truncate.
		sw.x = 0;
		ne.x = gw - 1;
	}
	var gridBounds = new GBounds([sw, ne]);
	gridBounds.z = zoom;
	return gridBounds;
};
MarkerManager.prototype.getMapGridBounds_ = function () {
	var me = this;
	return me.getGridBounds_(me.map_.getBounds(), me.mapZoom_, me.swPadding_, me.nePadding_);
};
MarkerManager.prototype.onMapMoveEnd_ = function () {
	var me = this;
	me.objectSetTimeout_(this, this.updateMarkers_, 0);
};
MarkerManager.prototype.objectSetTimeout_ = function (object, command, milliseconds) {
	return window.setTimeout(function () {
		command.call(object);
	},
	milliseconds);
};
MarkerManager.prototype.refresh = function () {
	var me = this;
	if (me.shownMarkers_ > 0) {
		me.processAll_(me.shownBounds_, me.removeOverlay_);
	}
	me.processAll_(me.shownBounds_, me.addOverlay_);
	me.notifyListeners_();
};
MarkerManager.prototype.updateMarkers_ = function () {
	var me = this;
	me.mapZoom_ = this.map_.getZoom();
	var newBounds = me.getMapGridBounds_(); // If the move does not include new grid sections,
	// we have no work to do:
	if (newBounds.equals(me.shownBounds_) && newBounds.z == me.shownBounds_.z) {
		return;
	}
	if (newBounds.z != me.shownBounds_.z) {
		me.processAll_(me.shownBounds_, me.removeOverlay_);
		me.processAll_(newBounds, me.addOverlay_);
	} else { // Remove markers:
		me.rectangleDiff_(me.shownBounds_, newBounds, me.removeCellMarkers_); // Add markers:
		me.rectangleDiff_(newBounds, me.shownBounds_, me.addCellMarkers_);
	}
	me.shownBounds_ = newBounds;
	me.notifyListeners_();
};
MarkerManager.prototype.notifyListeners_ = function () {
	GEvent.trigger(this, "changed", this.shownBounds_, this.shownMarkers_);
};
MarkerManager.prototype.processAll_ = function (bounds, callback) {
	for (var x = bounds.minX; x <= bounds.maxX; x++) {
		for (var y = bounds.minY; y <= bounds.maxY; y++) {
			this.processCellMarkers_(x, y, bounds.z, callback);
		}
	}
};
MarkerManager.prototype.processCellMarkers_ = function (x, y, z, callback) {
	var cell = this.getGridCellNoCreate_(x, y, z);
	if (cell) {
		for (var i = cell.length - 1; i >= 0; i--) {
			callback(cell[i]);
		}
	}
};
MarkerManager.prototype.removeCellMarkers_ = function (x, y, z) {
	this.processCellMarkers_(x, y, z, this.removeOverlay_);
};
MarkerManager.prototype.addCellMarkers_ = function (x, y, z) {
	this.processCellMarkers_(x, y, z, this.addOverlay_);
};
MarkerManager.prototype.rectangleDiff_ = function (bounds1, bounds2, callback) {
	var me = this;
	me.rectangleDiffCoords(bounds1, bounds2, function (x, y) {
		callback.apply(me, [x, y, bounds1.z]);
	});
};
MarkerManager.prototype.rectangleDiffCoords = function (bounds1, bounds2, callback) {
	var minX1 = bounds1.minX;
	var minY1 = bounds1.minY;
	var maxX1 = bounds1.maxX;
	var maxY1 = bounds1.maxY;
	var minX2 = bounds2.minX;
	var minY2 = bounds2.minY;
	var maxX2 = bounds2.maxX;
	var maxY2 = bounds2.maxY;
	for (var x = minX1; x <= maxX1; x++) { // All x in R1
		// All above:
		for (var y = minY1; y <= maxY1 && y < minY2; y++) { // y in R1 above R2
			callback(x, y);
		} // All below:
		for (var y = Math.max(maxY2 + 1, minY1); // y in R1 below R2
		y <= maxY1; y++) {
			callback(x, y);
		}
	}
	for (var y = Math.max(minY1, minY2); y <= Math.min(maxY1, maxY2); y++) { // All y in R2 and in R1
		// Strictly left:
		for (var x = Math.min(maxX1 + 1, minX2) - 1; x >= minX1; x--) { // x in R1 left of R2
			callback(x, y);
		}
		for (var x = Math.max(minX1, maxX2 + 1); // x in R1 right of R2
		x <= maxX1; x++) {
			callback(x, y);
		}
	}
};
MarkerManager.prototype.removeFromArray = function (array, value, opt_notype) {
	var shift = 0;
	for (var i = 0; i < array.length; ++i) {
		if (array[i] === value || (opt_notype && array[i] == value)) {
			array.splice(i--, 1);
			shift++;
		}
	}
	return shift;
};
    function ReturnToEuropeControl() {
    }
    ReturnToEuropeControl.prototype = new GControl();

    // Creates a one DIV for each of the buttons and places them in a container
    // DIV which is returned as our control element. We add the control to
    // to the map container and return the element for the map class to
    // position properly.
    ReturnToEuropeControl.prototype.initialize = function(map) {
      var container = document.createElement("div");

      var zoomInDiv = document.createElement("div");
      this.setButtonStyle_(zoomInDiv);
      container.appendChild(zoomInDiv);
      zoomInDiv.appendChild(document.createTextNode(googleMapsVar.returntoeurotext));
      GEvent.addDomListener(zoomInDiv, "click", function() {
        map.returnToSavedPosition();
        
        setTimeout(function () {googleMapsVar.map.removeControl(googleMapsVar.europecontrol);googleMapsVar.map_moved = false;}, 2000);
      });


     map.getContainer().appendChild(container);
      return container;
    }

    // By default, the control will appear in the top left corner of the
    // map with 7 pixels of padding.
    ReturnToEuropeControl.prototype.getDefaultPosition = function() {
      return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(7, 7));
    }

    // Sets the proper CSS for the given button element.
    ReturnToEuropeControl.prototype.setButtonStyle_ = function(button) {
      button.style.textDecoration = "none";
      button.style.color = "#5F87DF";
      button.style.backgroundColor = "white";
      button.style.font = "small Arial";
      button.style.border = "1px solid #FF6600";
      button.style.padding = "2px";
      button.style.marginBottom = "3px";
      button.style.textAlign = "center";
      button.style.width = "8em";
      button.style.cursor = "pointer";
}

