//globals
var MARKER_TYPE_CAMPING_BOOKABLE = 1;
var MARKER_TYPE_CAMPING_NONBOOKABLE = 2;
var MARKER_TYPE_COUNTRY = 3;
var MARKER_TYPE_BEDANDBREAKFAST_RESERVABLE = 4;
var MARKER_TYPE_BEDANDBREAKFAST_NONRESERVABLE = 5;

var UI_MODE_SHOWALLITEMS = 1;
var UI_MODE_SHOWONLYPAYINGITEMS = 2;

var UI_MINZOOM;
var UI_MAXZOOM = 17;

var UI_MODE = UI_MODE_SHOWALLITEMS;
var UI_DEFAULT_ZOOM;
var UI_BORDERPADDING = 0;

var CAMPING_BOOKABLE_MINZOOM = 9;
var CAMPING_BOOKABLE_MAXZOOM = UI_MAXZOOM;

var CAMPING_NONBOOKABLE_MINZOOM = 9;
var CAMPING_NONBOOKABLE_MAXZOOM = UI_MAXZOOM;

var BEDANDBREAKFAST_RESERVABLE_MINZOOM = 6;
var BEDANDBREAKFAST_RESERVABLE_MAXZOOM = UI_MAXZOOM;

var BEDANDBREAKFAST_NONRESERVABLE_MINZOOM = 6;
var BEDANDBREAKFAST_NONRESERVABLE_MAXZOOM = UI_MAXZOOM;

var COUNTRY_MINZOOM;
var COUNTRY_MAXZOOM;

var OLD_POS_SW;
var OLD_POS_NE;

var CURRENT_ZOOM;
var OLD_ZOOM;

var CURRENT_ITEM_ID = -1;

var ITEM_TYPE_CAMPING = 1;
var ITEM_TYPE_BEDANDBREAKFAST = 2;

var CURRENT_ITEM_TYPE = -1;

if (GBrowserIsCompatible()) {
	//OBJECTS
	var map;			//will contain the GMap
	var ov;				//will contain the Overview Map Control

	var markerManager;		//ANWB style marker manger
	var contentLoader;		//loader for streaming content files
	var sidebar;			//sidebar manager

	//CONSTANTS
	//var FILE_BOOKABLE_CAMPINGS = "/verblijven/general/includes/anwb-campings-googlemaps-boekbaar.xml";
	//var FILE_NONBOOKABLE_CAMPINGS  = "/verblijven/general/includes/anwb-campings-googlemaps-nietboekbaar.xml";
	var FILE_LANDEN = "/verblijven/general/includes/googleMapLanden.xml";
	
	var ZOOM_EVENT_OCCURRED = false;

    var allowedBounds;
	
	//FUNCTIONS
	//function to init the google map based on a div element that is passed in the argument
	function initMap(divid){
	
		// to set the right current item id; camping or bedandbreakfast
		jsfPreInitGoogleMap();
		
        // The allowed region which the whole map must be within
		//
		/* 
        if (CURRENT_ITEM_TYPE == ITEM_TYPE_BEDANDBREAKFAST) {
        	allowedBounds = new GLatLngBounds(new GLatLng(48.8, 0.0), new GLatLng(54.6, 10.9)); // benelux
        	UI_MINZOOM = 6;
        	UI_DEFAULT_ZOOM = UI_MINZOOM;
        	COUNTRY_MINZOOM = UI_MINZOOM;
        	COUNTRY_MAXZOOM = Math.min(BEDANDBREAKFAST_RESERVABLE_MINZOOM, BEDANDBREAKFAST_NONRESERVABLE_MINZOOM) -1;
        } else {
	        allowedBounds = new GLatLngBounds(new GLatLng(35.4, -11.5), new GLatLng(71.0, 31.7)); // europe
	        UI_MINZOOM = 4;
	        UI_DEFAULT_ZOOM = UI_MINZOOM;
	        COUNTRY_MINZOOM = UI_MINZOOM;
	        COUNTRY_MAXZOOM = Math.min(CAMPING_BOOKABLE_MINZOOM, CAMPING_NONBOOKABLE_MINZOOM) -1;
        }
        */
		// Campings and B&B show on the Europe map  TT10211
		 allowedBounds = new GLatLngBounds(new GLatLng(35.4, -11.5), new GLatLng(71.0, 31.7)); // europe
		 if (CURRENT_ITEM_TYPE == ITEM_TYPE_BEDANDBREAKFAST) {			
	        	UI_MINZOOM = 4;
	        	UI_DEFAULT_ZOOM = UI_MINZOOM;
	        	COUNTRY_MINZOOM = UI_MINZOOM;
	        	COUNTRY_MAXZOOM = Math.min(BEDANDBREAKFAST_RESERVABLE_MINZOOM, BEDANDBREAKFAST_NONRESERVABLE_MINZOOM) -1;
	        } else {		       
		        UI_MINZOOM = 4;
		        UI_DEFAULT_ZOOM = UI_MINZOOM;
		        COUNTRY_MINZOOM = UI_MINZOOM;
		        COUNTRY_MAXZOOM = Math.min(CAMPING_BOOKABLE_MINZOOM, CAMPING_NONBOOKABLE_MINZOOM) -1;
	        }
		 		 		
		// create the map
		map = new GMap2(document.getElementById(divid));
        
		// For doing something after the map has loaded (like showing current camping in toonKaart.jsf)
		GEvent.addListener(map, "load", mapLoaded);
		//alert(jsfInitAfterMapLoaded);
		
		map.addControl(new GSmallMapControl());
		map.addControl(new GMapTypeControl());
		_mPreferMetric = true;
		map.addControl(new GScaleControl());
		map.enableDoubleClickZoom();
		map.enableContinuousZoom();
		map.enableScrollWheelZoom();
		map.scrollWheelZoomEnabled();
		
		// B&B TT10211 voor bed en breakfast ook de heel europa tonen ipv alleen de Benelux
		
       // if (CURRENT_ITEM_TYPE == ITEM_TYPE_BEDANDBREAKFAST) {
	   //		map.setCenter(new GLatLng(51.7, 5.45),UI_DEFAULT_ZOOM, G_NORMAL_MAP); // benelux
       //   } else {
	   //	map.setCenter(new GLatLng(50.464, 9.507),UI_DEFAULT_ZOOM, G_NORMAL_MAP); // europe
        //}
		map.setCenter(new GLatLng(50.464, 9.507),UI_DEFAULT_ZOOM, G_NORMAL_MAP); // europe
		CURRENT_ZOOM = UI_DEFAULT_ZOOM;
		
		
		return map;
	}
	
	function mapLoaded() {
        //nieuwe marker manager
        markerManager = new AMarkerManager(map);

		ov = initControls(map);
		if (document.getElementById('side_bar') != null) {
			sidebar = new ASidebar(document.getElementById('side_bar'));	
		} else {
			sidebar = null;
		}
		initMapEvents(map);
		initDOMEvents();

		initMapTypes(map);

        jsfInitAfterMapLoaded();
	}

	//Function to init the map controls
	function initControls(map){
	        //map controls
        	ov = new GOverviewMapControl(new GSize(100,100));
        	map.addControl(ov);
        	ov.hide(true);

        	map.hideControls();			
	}
	
	//Application init() function, the core function of the application.
	function initGoogleMap(){
		map = initMap("map");

		//laad de landen
		loadCountries(FILE_LANDEN);		
	} 


	//Function containing all event assignments for the map
	function initMapEvents(map){
		//'mouseover' listener shows controls
		GEvent.addListener(map, "mouseover", function(){
			map.showControls();
		});

		//'mouseout' listener hides controls
		GEvent.addListener(map, "mouseout", function(){
			map.hideControls(); 
		});

		// Add move listeners
		GEvent.addListener(map, "movestart", function() {
			//store the old position
			OLD_POS_NE = { longitude:map.getBounds().getNorthEast().lng(), latitude:map.getBounds().getNorthEast().lat() };
			OLD_POS_SW = { longitude:map.getBounds().getSouthWest().lng(), latitude:map.getBounds().getSouthWest().lat() };      			
		});
		
		
		 
		GEvent.addListener(map, "zoomend", function() {
			ZOOM_EVENT_OCCURRED = true;
			//alert("zoomend, zoom="+map.getZoom()+", swLng="+map.getBounds().getSouthWest().lng()+", swLat="+map.getBounds().getSouthWest().lat()+", neLng="+map.getBounds().getNorthEast().lng()+", neLat="+map.getBounds().getNorthEast().lat());
		}); 
		 
      	GEvent.addListener(map, "moveend", function() {
   			// zoom always triggers a move as well, so do not handle zoomend event!!
        	checkBounds();

			var swWgs = {
				longitude:map.getBounds().getSouthWest().lng(),
				latitude:map.getBounds().getSouthWest().lat()
			};
			var neWgs = {
				longitude:map.getBounds().getNorthEast().lng(),
				latitude:map.getBounds().getNorthEast().lat()
			};        	
        	
        	markerDataUpdate(swWgs, neWgs, OLD_POS_SW, OLD_POS_NE);
			//alert("moveend, zoom="+map.getZoom()+", swLng="+map.getBounds().getSouthWest().lng()+", swLat="+map.getBounds().getSouthWest().lat()+", neLng="+map.getBounds().getNorthEast().lng()+", neLat="+map.getBounds().getNorthEast().lat());
      	});
 	}
	
	// Function to get marker data from service (AJAX)
	function markerDataUpdate(newSwWgs, newNeWgs, oldSwWgs, oldNeWgs) {
		if (map.getZoom() > COUNTRY_MAXZOOM) {
						
			if (CURRENT_ITEM_TYPE == ITEM_TYPE_CAMPING && map.getZoom() >= CAMPING_BOOKABLE_MINZOOM){
				//get bookable campings
				GoogleMapsService.getCampingsBookable(newSwWgs, newNeWgs, oldSwWgs, oldNeWgs, processCampingBookableArray);
			}
			
			if (CURRENT_ITEM_TYPE == ITEM_TYPE_CAMPING && UI_MODE == UI_MODE_SHOWALLITEMS && map.getZoom() >= CAMPING_NONBOOKABLE_MINZOOM) {
				//get nonbookable campings
				GoogleMapsService.getCampingsNonBookable(newSwWgs, newNeWgs, oldSwWgs, oldNeWgs, processCampingNonBookableArray);
			}
			if (CURRENT_ITEM_TYPE == ITEM_TYPE_BEDANDBREAKFAST && map.getZoom() >= BEDANDBREAKFAST_RESERVABLE_MINZOOM){
				//get reservable bedandbreakfasts
				GoogleMapsService.getBedAndBreakfastsReservable(newSwWgs, newNeWgs, oldSwWgs, oldNeWgs, processBedAndBreakfastReservableArray);
			}
			
			if (CURRENT_ITEM_TYPE == ITEM_TYPE_BEDANDBREAKFAST && UI_MODE == UI_MODE_SHOWALLITEMS && map.getZoom() >= BEDANDBREAKFAST_NONRESERVABLE_MINZOOM) {
				//get nonreservable bedandbreakfasts
				GoogleMapsService.getBedAndBreakfastsNonReservable(newSwWgs, newNeWgs, oldSwWgs, oldNeWgs, processBedAndBreakfastNonReservableArray);
			}
		 }
		
		else {
			
		//	console.log("markerDataUpdate - check if sidebar is not null then update sidebar")
			if (sidebar != null) updateSideBar();
		}
	}

	//Function containing listeners for all DOM events
	function initDOMEvents(){
        	//Function to prevent page scroll within an i-frame
        	function wheelevent(e){
                	if(document.getElementById("map")){
                        	if (!e){
                                	e = window.event
                        	}

                        	if (e.preventDefault){
                                	e.preventDefault()
                        	}

                        	e.returnValue = false;
                	}
        	}

                GEvent.addDomListener(map.getContainer(), "DOMMouseScroll", wheelevent);
                map.getContainer().onmousewheel = wheelevent;
	}
	
	//Function that inits the map types
	function initMapTypes(map){
      		// ====== Restricting the range of Zoom Levels =====
      		// Get the list of map types      
      		var mt = map.getMapTypes();

      		// Overwrite the getMinimumResolution() and getMaximumResolution() methods
      		for (var i=0; i<mt.length; i++) {
        		mt[i].getMinimumResolution = function() {return UI_MINZOOM;}
        		mt[i].getMaximumResolution = function() {return UI_MAXZOOM;}
     		}
	}
	
      	//Function to check if the map position is out of range, and if so: move it back
      	function checkBounds() {
        	// Perform the check and return if OK
        	if (allowedBounds.contains(map.getCenter())) {
          		return;
        	}

        	// It`s not OK, so find the nearest allowed point and move there
        	var C = map.getCenter();
        	var X = C.lng();
        	var Y = C.lat();
		
		//Determine max values
        	var AmaxX = allowedBounds.getNorthEast().lng();
        	var AmaxY = allowedBounds.getNorthEast().lat();
        	var AminX = allowedBounds.getSouthWest().lng();
        	var AminY = allowedBounds.getSouthWest().lat();
		
		//Adjust values to allowed values if ne
        	if (X < AminX) {X = AminX;}
        	if (X > AmaxX) {X = AmaxX;}
        	if (Y < AminY) {Y = AminY;}
        	if (Y > AmaxY) {Y = AmaxY;}
        
		//move map to the nearest allowed point
        	map.setCenter(new GLatLng(Y,X));
	}

	
	//Function to load the campings file
//	function loadDefaultCampings(campingFile){
//		GDownloadUrl(campingFile, processDefaultCampings);
//	}

		
//	function loadStreamedCampings(campingFile){
//		GDownloadUrl(campingFile, processStreamedCampings);
//	}
	
//	function processDefaultCampings(doc){
//		processCampingsXML(doc, MARKER_TYPE_CAMPING_BOOKABLE);
//	}
	

//	function processStreamedCampings(doc){
//		processCampingsXML(doc, MARKER_TYPE_CAMPING_NONBOOKABLE);
//	}

	function processCampingNonBookableArray(campingArray){
		//alert("In processItemArray CAMPING_NONBOOKABLE");
		processItemArray(campingArray, MARKER_TYPE_CAMPING_NONBOOKABLE);
	}

	function processCampingBookableArray(campingArray){
		//alert("In processItemArray CAMPING_BOOKABLE");
		processItemArray(campingArray, MARKER_TYPE_CAMPING_BOOKABLE);
	}
	
	function processBedAndBreakfastNonReservableArray(bedAndBreakfastArray){
		processItemArray(bedAndBreakfastArray, MARKER_TYPE_BEDANDBREAKFAST_NONRESERVABLE);
	}

	function processBedAndBreakfastReservableArray(bedAndBreakfastArray){
		processItemArray(bedAndBreakfastArray, MARKER_TYPE_BEDANDBREAKFAST_RESERVABLE);
	}

	function processItemArray(itemsArray, type){
		markerManager.clearInvisibleItemMarkers();
				
		bestaandeItems = markerManager.getItemMarkerArray();
				
		for (i in itemsArray){
			var lat = itemsArray[i].wgs.latitude;
			var lon = itemsArray[i].wgs.longitude;
			var point = new GLatLng(lat, lon);
			var name = itemsArray[i].name;
			var uniqueId = itemsArray[i].uniqueId;
			var newMarker;
	//		console.log("itemArray" + i + " " + itemsArray[i].name)
			if (type == MARKER_TYPE_CAMPING_BOOKABLE){
				if(uniqueId == CURRENT_ITEM_ID) {
					newMarker = AMarkerFactory.createItemMarker(name, point, uniqueId, AIconFactory.getIcon("camping_current_bookable"), type);
				} else {
					newMarker = AMarkerFactory.createItemMarker(name, point, uniqueId, AIconFactory.getIcon("camping_bookable"), type);
				}	
			} else if (type == MARKER_TYPE_CAMPING_NONBOOKABLE){
				if(uniqueId == CURRENT_ITEM_ID) {
					newMarker = AMarkerFactory.createItemMarker(name, point, uniqueId, AIconFactory.getIcon("camping_current_nonbookable"), type);
				} else {
					newMarker = AMarkerFactory.createItemMarker(name, point, uniqueId, AIconFactory.getIcon("camping_nonbookable"), type);
				}			
			} else if (type == MARKER_TYPE_BEDANDBREAKFAST_RESERVABLE){
				if(uniqueId == CURRENT_ITEM_ID) {
					newMarker = AMarkerFactory.createItemMarker(name, point, uniqueId, AIconFactory.getIcon("bedandbreakfast_current_reservable"), type);
				} else {
					newMarker = AMarkerFactory.createItemMarker(name, point, uniqueId, AIconFactory.getIcon("bedandbreakfast_reservable"), type);
				}	
			} else if (type == MARKER_TYPE_BEDANDBREAKFAST_NONRESERVABLE){
				if(uniqueId == CURRENT_ITEM_ID) {
					newMarker = AMarkerFactory.createItemMarker(name, point, uniqueId, AIconFactory.getIcon("bedandbreakfast_current_nonreservable"), type);
				} else {
					newMarker = AMarkerFactory.createItemMarker(name, point, uniqueId, AIconFactory.getIcon("bedandbreakfast_nonreservable"), type);
				}			
			}
		//	markerManager.addMarker(newMarker, type);	
			//wel of niet toevoegen... in principe wel... maar de loop hierna checkt of het geen dubbele is.
			var toevoegen = true;
			

			//check op dubbele items 
			for (j in bestaandeItems){
				if (itemsArray[i].uniqueId == Number(bestaandeItems[j].uniqueId)){
					toevoegen = false;
		
		//console.debug("check op dubbele: Marker bestaat al");
				} 
			}			

			if (toevoegen){
		//	console.log("add the marker to bookable marker manager:" + newMarker.uniqueId);
			
			markerManager.addMarker(newMarker, type);	
			}		
		
		}
		
		
		 if (sidebar != null) updateSideBar();
	}

	//Function that updates the sidebar
	function updateSideBar(){
		//clear current content
		sidebar.clear();
		
		var visibleRegion = map.getBounds();

		var myHTML = "";
		var markers = markerManager.getItemMarkerArray();
		
		if (CAMPING_BOOKABLE_MINZOOM <= map.getZoom() && CAMPING_BOOKABLE_MAXZOOM >= map.getZoom()){
			var markers = markerManager.getItemMarkerArray();
			
			for (i in markers){
				if (markers[i]._type == MARKER_TYPE_CAMPING_BOOKABLE && visibleRegion.contains(markers[i].getPoint())){
					var newItem = new ASidebarItem(markers[i]);
			//	alert("In updateSideBar: add cmp bookable" + markers[i].id + " " + markers[i].label);	
					sidebar.addItem(newItem);
				}
			}			
		}
		
		if (CAMPING_NONBOOKABLE_MINZOOM <= map.getZoom() && CAMPING_NONBOOKABLE_MAXZOOM >= map.getZoom()){
			var markers = markerManager.getItemMarkerArray();
			
			for (i in markers){
				if (markers[i]._type == MARKER_TYPE_CAMPING_NONBOOKABLE && visibleRegion.contains(markers[i].getPoint())){
					var newItem = new ASidebarItem(markers[i]);
				//	alert("In updateSideBar: add cmp nonbookable" + markers[i].id + " " + markers[i].label);
					sidebar.addItem(newItem);
				}
			}			
		}		
		
		if (BEDANDBREAKFAST_RESERVABLE_MINZOOM <= map.getZoom() && BEDANDBREAKFAST_RESERVABLE_MAXZOOM >= map.getZoom()){
			 var markers = markerManager.getItemMarkerArray();
			
			for (i in markers){
				if (markers[i]._type == MARKER_TYPE_BEDANDBREAKFAST_RESERVABLE && visibleRegion.contains(markers[i].getPoint())){
					var newItem = new ASidebarItem(markers[i]);
					sidebar.addItem(newItem);
				}
			}			
		}
		
		if (BEDANDBREAKFAST_NONRESERVABLE_MINZOOM <= map.getZoom() && BEDANDBREAKFAST_NONRESERVABLE_MAXZOOM >= map.getZoom()){
			 var markers = markerManager.getItemMarkerArray();
			
			for (i in markers){
				if (markers[i]._type == MARKER_TYPE_BEDANDBREAKFAST_NONRESERVABLE && visibleRegion.contains(markers[i].getPoint())){
					var newItem = new ASidebarItem(markers[i]);
					sidebar.addItem(newItem);
				}
			}			
		}
		
		if (COUNTRY_MINZOOM <= map.getZoom() && COUNTRY_MAXZOOM >= map.getZoom()){
			
			//Loop through country markers and add them to sidebar
			
			var markers = markerManager.getCountryMarkerArray();		
			
			for (i in markers){
				var newItem = new ASidebarItem(markers[i]);
				sidebar.addItem(newItem);
			}
			
			return;
		}		
	}
	
	//Function to search for geocooordinates at google server
	function searchCoordinates(){
		//create new geocoder
		var cg = new GClientGeocoder();
	
		//get search terms from input field
		var searchArg = document.getElementById('GMapSearchBox').value;
	
		//execute query (result is handled by searchCoordinates_Result)
		cg.getLocations(searchArg, searchCoordinates_Result);
	}

	//Function that handles the search results from the google geocode search.
	function searchCoordinates_Result(response){
		//check the status code of the response 
		if (response.Status.code == 602) { //problem with geocode
			alert("Zoeken is mislukt. Probeer een ander zoekwoord en/of laat de de naam vooraf gaan door de landnaam");
		} else if (response.Status.code  == 610){ //problem with api-key
			alert("De gmaps key is onjuist voor het domein waarop het verzoek werd aangevraagd.");
		} else if (response.Status.code == 200){ //success
      			// Retrieve the object
      			var place = response.Placemark[0];

      			// Retrieve the latitude and longitude
      			var point = new GLatLng(place.Point.coordinates[1], place.Point.coordinates[0]);

      			// Center the map on this point
      			map.setCenter(point, 13);	
		} else { //problem
			alert(response.Status.code + ': ' + response.Status.request);
		}
	}

	//Function that loads the countries file
	function loadCountries(countryFile){
		//load the file containing country information
		GDownloadUrl(countryFile, processCountries);
	}

	//Function that processes the loaded countries file
	function processCountries(doc){
		//parse the document to create a xml DOM tree
		var xmldoc = GXml.parse(doc);

		//retrieve the countries in the XML file
    	var countries = xmldoc.documentElement.getElementsByTagName("country");
	 
		//loop through each of the countries
		for (var i=0; i< countries.length; i++) {
			//get the element props from the xml 
			var countryFlag = countries[i].getAttribute("flag");		
			var countryName = countries[i].getAttribute("name");
      		var point = new GLatLng(parseFloat(countries[i].getAttribute("lat")), parseFloat(countries[i].getAttribute("lng")));
			//get a marker from the factory
			var newCountryMarker = AMarkerFactory.createCountryMarker(countryName, point, countryFlag);
    			
			//add the country marker to to marker manager
			markerManager.addMarker(newCountryMarker, MARKER_TYPE_COUNTRY);
		}

		if (sidebar != null) updateSideBar();
	}
		
	function updateSelectedView(obj){
	
		if (obj.id == "rb_showonlypayingitems"){
			if (obj.checked) {
				UI_MODE = UI_MODE_SHOWONLYPAYINGITEMS;
				markerManager.clearItemMarkers();
				//map.clearOverlays();
				markerManager._itemMarkerArray = [];
				
				var swWgs = {
					longitude:map.getBounds().getSouthWest().lng(),
					latitude:map.getBounds().getSouthWest().lat()
				};
				var neWgs = {
					longitude:map.getBounds().getNorthEast().lng(),
					latitude:map.getBounds().getNorthEast().lat()
				};  
							
				markerDataUpdate(swWgs, neWgs, null, null);
			}
		} else if (obj.id == "rb_showallitems") {
			if (obj.checked) {
				UI_MODE = UI_MODE_SHOWALLITEMS;
				markerManager.clearItemMarkers();
				//map.clearOverlays();
				markerManager._itemMarkerArray = [];

				var swWgs = {
					longitude:map.getBounds().getSouthWest().lng(),
					latitude:map.getBounds().getSouthWest().lat()
				};
				var neWgs = {
					longitude:map.getBounds().getNorthEast().lng(),
					latitude:map.getBounds().getNorthEast().lat()
				};  
							
				markerDataUpdate(swWgs, neWgs, null, null);
			}
		}
	}
} /*else {
	//If the browser is not compatible with google maps, inform the user.
    alert("Sorry, uw browser ondersteunt Google Maps niet.");
}*/
