/**
 * @author toby
 */

/* variables */
var map;
var addstorymap;
var deselectCurrent = function(){};

function addLoadEvent(func){
	var oldonload = window.onload;
	if(typeof window.onload != 'function'){
		window.onload = func;
	}else{
		window.onload = function(){
			oldonload();
			func();
		}
	}
}

function addUnloadEvent(func){
	var oldonunload = window.unonload;
	if(typeof window.unonload != 'function'){
		window.unonload = func;
	}else{
		window.unonload = function(){
			oldonunload();
			func();
		}
	}
}

function mapUnload(){
	GUnload();
}

/* this function loads the map */
function mapInit(){
	/*sets whether to display the geocode search field or not */
	showGeoCodeSearch(useGeocodeSearch);

	if(GBrowserIsCompatible()){
		map = new GMap2(document.getElementById("map"));
		var location = new GLatLng(initLat,initLng);
		map.addControl(new GLargeMapControl());
		map.addControl(new GMapTypeControl());
		map.setCenter(location, initZoom);
		map.setMapType(initMapType);
		retrieveMarkers();
		changeBodyClass("loading", "standby");
	}
	else {
		alert('Your browser is unable to support Google Maps. You will need to upgrade to a more recent browser version to view this interactive.');
	}
}

/* this function runs an AJAX request to get back all published stories from db */
function retrieveMarkers(){
	var category;
	var allCategories = {"All":[]};
	
	var request = GXmlHttp.create();

	var getVars = "?f=" + configfolder + "&l=" + limit;
	request.open('GET','/vastatic/map_uploads/includes/allmarkers.php' + getVars,true);

	request.onreadystatechange = function(){
		if(request.readyState == 4 && request.status == 200){
			var xmlDoc = request.responseText;
			//var markers;
			eval(xmlDoc);

			if(markers!="empty"){
				for(id in markers){
					initializePoint(markers[id]);
					allCategories[markers[id].category] = true;
				}
				//set up category list://
				for(category in allCategories){
					initialiseFilterList(category,markers);
				}
				//set up the two states of the 'add story' button//
			}
			initialiseAddStoryButton(markers);
		}
	}
	request.send(null);
}

/* this function sets up the 'Add Story' button behaviours */
function initialiseAddStoryButton(markers){
	var addstory = document.getElementById("addstory");
	addstory.innerHTML = addStoryButtonText;
	setTopBarMsg(categoriesText);
	var mapwrapper = document.getElementById("map-wrapper");
	var filterlist = document.getElementById("filter-list");
	addstory.onmouseover = changeCursor(addstory,"pointer");
	
	addstory.onclick=function(){
		var state = mapwrapper.className;
		if(state=="view"){
			setTopBarMsg(addStoryInstruction);
			filterlist.style.marginLeft = "-1000px";
			mapwrapper.className = "edit";
			addstory.innerHTML = viewStoryButtonText;
			map.closeInfoWindow();
			deselectTopPosts();
			if(markers!="empty"){
				for(id in markers) {
					markers[id].hide();
				}
			}			
			addstorymap = GEvent.addListener(map,'click',function(overlay,latlng){
				var longitude = latlng.lng();
				var latitude = latlng.lat();
				var uploadform = uploadForm(longitude,latitude);
				map.openInfoWindow(latlng,uploadform);
			});	
		}
		else{
			GEvent.removeListener(addstorymap);
			map.closeInfoWindow();
			setTopBarMsg(categoriesText);
			filterlist.style.marginLeft = "0px";
			mapwrapper.className = "view";
			addstory.innerHTML = addStoryButtonText;
			var category = filterlist.className;
			if(markers!="empty"){
				for(id in markers) {
					if(markers[id].category == category || "All" == category) {
						if(!firstpoint){
							var firstpoint = new GLatLng(markers[id].latitude,markers[id].longitude);
						}
						markers[id].show();
					} else {
						markers[id].hide();
					}
				}
			}
		}
	}
}

/* this function builds the list of categories by which the stories can be filtered */
function initialiseFilterList(category,markers){
	var firstpoint;
	var filterlist = document.getElementById("filter-list");
	var listitem = document.createElement("li");
	var listitemlink = listitem.appendChild(document.createElement("a"));
	listitemlink.href = "";
	listitemlink.innerHTML = category;
	listitemlink.onclick = function(){
		changeBodyClass("standby", "loading");
		deselectTopPosts();
		for(id in markers) {
			if(markers[id].category == category || "All" == category) {
				if(!firstpoint){
					var firstpoint = new GLatLng(markers[id].latitude,markers[id].longitude);
				}
				markers[id].show();
				filterlist.className = category;
			} else {
				markers[id].hide();
			}
		}	
		map.setZoom(13);
		map.closeInfoWindow();
		changeBodyClass("loading","standby");
		map.panTo(firstpoint);
		return false;	
	}
	filterlist.appendChild(listitem);
}

/* this function is called for each story that is found, it sets the behaviours for each marker,
 * and its related link in the right hand 'Locations' menu
 */
function initializePoint(pointData){
	var point = new GPoint(pointData.longitude,pointData.latitude);
	var marker = new GMarker(point);
	var markerhtml = formatMarkerContent(pointData);
	
	var listitem;
	var visible = false;
	listitem = createLinkItem(point, pointData, marker, markerhtml);
	
	GEvent.addListener(marker,'click',
		function(){
			marker.openInfoWindowHtml(markerhtml);
			if(listitem){
				highlightTopPost(listitem);
			}else{
				deselectTopPosts();
			}
		}
	);
	pointData.show = function(){
		if(!visible){
			if(listitem){
				document.getElementById("top-posts-list").appendChild(listitem);
			}
			map.addOverlay(marker);
			visible = true;
		}
	}
	pointData.hide = function(){
		if(visible){
			if(listitem){
				document.getElementById("top-posts-list").removeChild(listitem);
			}
			map.removeOverlay(marker);
			visible = false;
		}
	}

	pointData.show();

	
}

/* this function formats each item in the right hand Location menu, and adds the focusPoint behaviour */
function createLinkItem(point, pointData, marker, markerhtml) {
	var listitem = document.createElement("li");
	listitem.innerHTML = "<strong>Location: " + pointData.placename + "</strong><br/>" 
					+ "Entered by: " + pointData.creatorname;
	if(pointData.date){
		listitem.innerHTML += ", " + pointData.date;
	}
	var focusPoint = function(){
		highlightTopPost(listitem);
		marker.openInfoWindowHtml(markerhtml);
		return false;
	}
	

	listitem.onmouseover = changeCursor(listitem,"pointer");
	listitem.onclick = focusPoint;
	document.getElementById("top-posts-list").appendChild(listitem);
	
	return listitem;
}

/* this function changes the cursor style*/
function changeCursor(element, cursorstyle){
	var changecursor = element.style.cursor = cursorstyle;
	return changecursor;
}

/* this function is an AJAX call to a PHP file which makes a request to the Google Geocode service.
 * it is run each time a user makes a Street or ZIP search
 */
function geocodeSearch(searchtype){
	var searchterm = encodeURIComponent(document.getElementById(searchtype).value);
	var getVars = "?type=" + searchtype + "&q=" + searchterm + "&f=" + configfolder;
	var request = GXmlHttp.create();
	/*GLog.write("/vastatic/map_uploads/includes/geocode.php" + getVars);*/
	request.open("GET","/vastatic/map_uploads/includes/geocode.php" + getVars, true);
	request.onreadystatechange = function(){
		if(request.readyState == 4 && request.status == 200){
			var georesults = "";
			var results = request.responseText;
			eval(results);
			var resultpara = document.getElementById("search-results-msg");
			var resultlist = document.getElementById("search-results-list");
			clearResultList(resultlist);
			if(georesults.length > 1){
				for(id in georesults){
					var resultrow = createResultsRow(georesults[id]);
					resultlist.appendChild(resultrow);
				}
				resultpara.innerHTML = multiResultsMsg;		
			}
			else if(georesults.length == 1) {
				var resultrow = createResultsRow(georesults[0]);
				resultlist.appendChild(resultrow);
				resultpara.innerHTML = singleResultsMsg;	
			}
			else {
				resultpara.innerHTML = noResultsMsg;
			}
		}
	}
	request.send(null);
}

/* this function produces the HTML that goes into the Info Window when you click on the map when it is in 'edit' state */
function uploadForm(longitude,latitude){
	var uploadDiv = document.createElement("div");
	uploadDiv.setAttribute("id","uploadformdiv");
	uploadDiv.innerHTML = "<p>" + uploadLinkMsg + "</p>";
	var uploadForm = document.createElement("form");
	uploadForm.setAttribute("action","index.php");
	uploadForm.setAttribute("method","post");
	uploadForm.setAttribute("name","newPostForm");
	uploadForm.onsubmit = function(){submit();};
	uploadForm.innerHTML = '<input type="hidden" name="section" id="section" value="3" />'
	+ '<input type="hidden" name="longitude" id="longitude" value="' + longitude + '" />'
	+ '<input type="hidden" name="latitude" id="latitude" value="' + latitude + '" />'
	+ '<tr><td class="col1"></td><td class="col2"><input type="submit" value="Submit Your Own Story" id="mapsubmit" /></td></tr>'
	+ '</table>';
	uploadDiv.appendChild(uploadForm);
	return uploadDiv;
}

/* this function produces the HTML displayed when a user opens the Info Window of a marker when the map is in 'view' state */
function formatMarkerContent(pointData){
	var markercontent = "<div id='markercontent'>";
	if(pointData.imgurl!=''){
		markercontent += "<img src='" + pointData.imgurl + "' alt=''>";
	}
	markercontent += "<h3>" + pointData.placename;
	if(pointData.date){
		markercontent += 	", " + pointData.date;
	}
	markercontent += "</h3>";	
	markercontent += "<p>" + pointData.description + "</p>";
	markercontent += "<p>User: <strong>" + pointData.creatorname + "</strong><br/>";
	markercontent += "Category: " + pointData.category + "</p>";
	markercontent += "<div class='clear' style='width: 100%;'></div></div>";

	return markercontent;
}

/* this function highlights an item in the right hand menu when the corresponding marker on the map is selected */
function highlightTopPost(listitem){
	deselectCurrent();
	listitem.className = 'current';
	deselectCurrent = function() {listitem.className = ''};
}

/* this function de-highlights all items in the right hand 'Location' menu */
function deselectTopPosts(){
	var topposts = document.getElementById("top-posts-list");
	var listitems = topposts.getElementsByTagName("li");
	for(var i=0; i < listitems.length; i++ ){
		listitems[i].className = '';
	}	
}

/* this function returns all the results of a street or zip code, and attaches the appropriate behaviour*/
function createResultsRow(georesult){
	var resultlistitem = document.createElement("li");
	resultlistitem.innerHTML = "<a href=''/>"
	+ georesult.address + "</a>";
	var resultPoint = new GLatLng(georesult.latitude, georesult.longitude);
	var panToResult = function(){
		map.closeInfoWindow();
		map.setZoom(16);
		map.panTo(resultPoint);
		return false;
	}
	resultlistitem.onclick = panToResult;
	return resultlistitem;
}

/* this function empties the existing results list, and is called each time a new search is run */
function clearResultList(resultlist){
	var listitems = resultlist.getElementsByTagName("li");
	for(var i = 0; i < listitems.length; i++){
		resultlist.removeChild(listitems[i]);
	}
}

/* this function shows or hides the search box, depending on whether useGeocodeSearch has been set to 0 or 1*/
function showGeoCodeSearch(useGeocodeSearch){
	var searchform = document.getElementById("search-bar");
	if(useGeocodeSearch==0){
		searchform.style.display = "none";
	} else {
		searchform.style.display = "block";
	}
}

/* this function handles changing the text displayed in the top bar of the map interface, before any other elements*/
function setTopBarMsg(msg){
	var topbarmsg = document.getElementById("top-bar-msg");
	topbarmsg.innerHTML = "";
	topbarmsg.innerHTML = msg;	
}

/* this function changes the body tag class */
function changeBodyClass(from, to){
	document.body.className = document.body.className.replace(from, to);
	return false;
}







addLoadEvent(mapInit);
addUnloadEvent(mapUnload);








