// Version 9.2 onwards written for Maps API 3.x
// V10.1 passes restos to setSelect
// v10.2 adds search
// v10.3 : new table of sort algorithm results

var map;
var geocoder;
var mapCentre;
var originalIntro;
var numberOfRestos;
var restos = new Array();
var showStars = new Array();
var showPrices = new Array();
var param;
var userSelected = -1;
var selectedResto = null;
var selectedCuisine = "All cuisines"
var infoWindow = new google.maps.InfoWindow({maxWidth: 200});
//var redMarker = "http://www.amsterdamfoodie.nl/af/map/red-small.png";
var redMarker = new google.maps.MarkerImage(
		'http://www.amsterdamfoodie.nl/af/map/red-small.png',
      // This marker is 20 pixels wide by 32 pixels tall.
      new google.maps.Size(20, 20),
      // The origin for this image is 0,0.
      new google.maps.Point(0,0)
      );
var greenMarker = new google.maps.MarkerImage(
		'http://www.amsterdamfoodie.nl/af/map/green-small.png',
      // This marker is 20 pixels wide by 32 pixels tall.
      new google.maps.Size(20, 20),
      // The origin for this image is 0,0.
      new google.maps.Point(0,0)
      );
 
//Extends basic marker with other key information
function myResto(restoName, c, stars, address, telNo, comment, bloglink, bookinglink, point, area, price, cuisine) {
	this.restoName = restoName;
	this.area = area;
	this.cuisine = cuisine;
	//this.colour = c;

	var title = "<p class='IWname'>";
	if (bloglink !== "none") title += "<a href='" + bloglink + "'>";
	title += restoName;
	if (bloglink !== "none") title += "</a>";
	title += "</p>";
	title += "<P class='IWcomment'>" + comment + "</p>";
	var wt = title;
	this.rating = parseInt( stars.substring(0,1) );
	if (this.rating > 0) wt+= "<img src='" + codeBase + this.rating + "stars.png'>";

	this.price = parseInt(price);
	if (this.price > 0) {wt+= "<img src='" + codeBase + this.price + "euro.png' style='margin-left: 15px;'>";}

	wt += "<p class='IWaddr'>" + address + " (" + telNo + ")";
	if (bookinglink != "") wt += "&nbsp;&nbsp;<a href='" + bookinglink + " target='_blank' class='booknow'>Book&nbsp now</a>";
	wt += "</p>";
		
	this.wt = wt;
	this.bookinglink = bookinglink;
	var marker = new google.maps.Marker({
		position: point,
		map: map,
		title: restoName,
		icon: redMarker
	});
	this.marker = marker;
	bindInfoWindow(this);
}

    function bindInfoWindow(r) {
      google.maps.event.addListener(r.marker, 'click', function() {
        //infoWindow.setContent(r.wt);
        //infoWindow.open(map, r.marker);
        setSelect(r);
      });
    }

function setSelect(r) {
	//alert(r.marker.getPosition());
	if (!r.marker.getVisible()) {r.marker.setVisible(true)};		//show if otherwise hidden
	if (r == selectedResto) {  // i.e. clicking on last selected icon
		unSelect(r);
	} else {		//
		if (selectedResto !== null) {unSelect(selectedResto);}  //close previous
		//Change colour and add window
		r.marker.setIcon(greenMarker);

		//document.getElementById("test").innerHTML=r.wt;
		//infoWindow.setOptions({content: t, maxWidth: 250});
		infoWindow.setContent(r.wt);
		infoWindow.open(map, r.marker);

		google.maps.event.addListener(infoWindow, 'closeclick', function() {
			unSelect(r);
		});
		selectedResto = r;
	}
}
function unSelect(r) {
	//alert ("Unselect");
	r.marker.setIcon(redMarker);
	infoWindow.close();
	selectedResto = null;
	document.getElementById("test").innerHTML = originalIntro;
}

function showAppropriate() {
    for (var i = 0; i < numberOfRestos; i++) {
            if ((	(showStars[restos[i].rating]) &&
                            ((selectedCuisine == "All cuisines") || (selectedCuisine == restos[i].cuisine)) &&
                            (showPrices[restos[i].price])) || (i == userSelected) 
                    )
            {
                    restos[i].marker.setVisible(true);
            }
            else {
                    //alert (showStars[restos[i].rating] + " : " + selectedCuisine  + " : " +  showPrices[restos[i].price]);
                    if (i == selectedResto) unSelect(restos[i]);
                    restos[i].marker.setVisible(false);
            }
    }
    top10();
}

function processEvent(evt) {
	evt = (evt) ? evt : ((event) ? event : null );
	if (evt) {
		//alert (evt);
		var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
		if (elem) {
			elem = (elem.nodeType == 1 || elem.nodeType == 9) ? elem : elem.parentNode;
			return elem;
		}
	}
}

function processCheckmarks(evt) {
	elem	= processEvent (evt);
	var stars = parseInt( elem.getAttribute("name").substring(0,1) );
	showStars[stars] = !showStars[stars];
	
	showAppropriate();
}

function processPrices(evt) {
	elem	= processEvent (evt);
	var stars = parseInt( elem.getAttribute("name").substring(0,1) );
	showPrices[stars] = !showPrices[stars];
	
	showAppropriate();
}

function processCuisine() {
    var thisSelect = document.getElementById("cuisineSelect");
    selectedCuisine = thisSelect.options[thisSelect.selectedIndex].value;
    showAppropriate();
}

function processArea() {
	switch (document.getElementById("restoByArea").value) {
		case "Amsterdam":
			map.setCenter(new google.maps.LatLng(centreLat,centreLng));
			map.setZoom(13);
			//document.getElementById('restoByArea').selectedIndex=0;
			break;
		case "Oud-West":  //Oud-West
			map.setCenter(new google.maps.LatLng(52.3664809, 4.87243652));
			map.setZoom(15);
			break;
		case "Watergraafsmeer":  //Oost/Watergraafsmeer
			map.setCenter(new google.maps.LatLng(52.3532719, 4.920158));
			map.setZoom(14);
			break;
		case "Westerpark":  //Westerpark
			map.setCenter(new google.maps.LatLng(52.3861823, 4.88136291));
			map.setZoom(15);
			break;
		case "Jordaan":  //Jordaan
			map.setCenter(new google.maps.LatLng(52.3759135, 4.88531112));
			map.setZoom(15);
			break;
		case "De Pijp":  //De Pijp
			map.setCenter(new google.maps.LatLng(52.3553688, 4.89252090));
			map.setZoom(15);
			break;
		case "Dam":  //Dam
			map.setCenter(new google.maps.LatLng(52.3713023, 4.89286422));
			map.setZoom(15);
			break;
		case "Rembrandtplein":  //Rembrandtplein
			map.setCenter(new google.maps.LatLng(52.3665857, 4.89320755));
			map.setZoom(15);
			break;
		case "Leidseplein":  //Leidseplein
			map.setCenter(new google.maps.LatLng(52.3640176, 4.88222122));
			map.setZoom(15);
			break;
		case "Nieuwmarkt":  //Nieuwmarkt
			map.setCenter(new google.maps.LatLng(52.3726909, 4.90024566));
			map.setZoom(15);
			break;
	}
	showAppropriate();
}

function doSearch() {
	//alert (document.getElementById('searchForm').type);
	if (document.getElementById('r1').checked)
		showAddress();
	else showResto();
	return false;
}

function showResto() {
	var regexp = new RegExp(document.getElementById('address').value,"i");
	//alert( regexp );
	var f = 0;
	for (var i = 0; i < numberOfRestos; i++) {
		if (restos[i].restoName.search(regexp) != "-1") {
			f++;
			setSelect(restos[i]);
		}
	}
	if (f==0) alert('"' + document.getElementById('address').value + '" not found');
}

function showAddress() {
	var ad = document.getElementById('address').value;
	var sw = new google.maps.LatLng(52.335759,4.834671);
	var ne = new google.maps.LatLng(52.412472,4.956894);
	var myBounds = new google.maps.LatLngBounds(sw, ne);
	var myOptions = {
		'address': ad,
		'latLng': mapCentre,
		'bounds': myBounds,
		'region': 'nl'
	};
	mygeocoder.geocode(myOptions, function(res, stat) {
		if (stat == google.maps.GeocoderStatus.OK) {
			//if (res.length > 1) alert (res.length + ' results');
			var homeImage = new google.maps.MarkerImage("http://www.google.com/mapfiles/kml/pal2/icon2.png");
			var homeMarker = new google.maps.Marker({
				position: res[0].geometry.location,
				map: map,
				title: 'Your address',
				icon: homeImage
			});
			//homeMarker.setVisible(true);
			var homeInfo = new google.maps.InfoWindow({
    			content: res[0].types[0]
			});
			//homeInfo.open(map, homeMarker);
		} else {
			alert(ad + " not found - try again?");
		}
		//return false;
	});
}

function showFilters() {
	//alert("turning on");
	(document.getElementById('showFilters').checked) ? document.getElementById('map_widgets').style.visibility = 'visible' : document.getElementById('map_widgets').style.visibility = 'hidden';
}

function loadMap(cLat, cLng) {
	//alert ("loading map");
	if ( document.URL.toString().indexOf("#") != -1) {
		param = document.URL.toString().substring(document.URL.toString().indexOf("#")+1, document.URL.toString().length);  //file://
	}

    var latlng = new google.maps.LatLng(cLat,cLng);
    var myOptions = {
      zoom: 13,
      center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP,
      mapTypeControl: false,
      navigationControl: true,
	  navigationControlOptions: {
	    style: google.maps.NavigationControlStyle.SMALL
	  }
    };
   map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
   google.maps.event.addListener(map, 'bounds_changed', function() {
   	top10();
 	});
   google.maps.event.addListener(map, 'center_changed', function() {
   	//alert('center changed');
 	});

   originalIntro = document.getElementById("test").innerHTML;
	mygeocoder = new google.maps.Geocoder();

	loadRestosFromMySQL();
}

function loadRestosFromMySQL() {
	//Code from google to generate xml from mysql
	downloadUrl(codeBase+"phpsqlajax_genxml2.php", function(data) {
		var xml = parseXml(data);
		var markers = xml.documentElement.getElementsByTagName("marker");
		numberOfRestos = markers.length;
		if (numberOfRestos == 0) alert('Error downloading database');
		for (var i = 0; i < markers.length; i++) {
			var rname = markers[i].getAttribute("name");
			var address = markers[i].getAttribute("address");
			var tel = markers[i].getAttribute("tel");
			var colour = markers[i].getAttribute("colour");
			var rating = markers[i].getAttribute("rating") + "stars";
			var qName = markers[i].getAttribute("qName");
			var comment = markers[i].getAttribute("comment");
			var area = markers[i].getAttribute("area");
			var cuisine = markers[i].getAttribute("cuisine");
			var price = markers[i].getAttribute("price");
			var bloglink = markers[i].getAttribute("bloglink");
			var bookinglink = markers[i].getAttribute("bookinglink");
			var point = new google.maps.LatLng(parseFloat(markers[i].getAttribute("lat")),
											parseFloat(markers[i].getAttribute("lng")));
			// function myResto(restoName, c, stars, address, comment, bloglink, point, area, cuisine)
			restos[i] = new myResto(rname,
						colour,
						rating,
						address, tel,
						comment,
						bloglink, bookinglink,
						point,
						area,
						price,
						cuisine
						);
			if (qName == param) {
				setSelect(restos[i]);
				userSelected = i;
			}
		} //end FOR loop
		showStars[0] = true;
		for (i=1; i<6; i++) {
			var p = document.getElementById(i+'_star');
			(p.checked) ? showStars[i] = true : showStars[i] = false;
			//alert("Element " + i+'_star' + " is " + showStars[i]);
		}
		for (i=1; i<4; i++) {
			var p = document.getElementById(i+'_price');
			(p.checked) ? showPrices[i] = true : showPrices[i] = false;
		}
		processCuisine();
		processArea();
	});
}
//--------- For lower section
function degrees2km(y) {
	var x = y.marker;
	var tempx = Math.abs(mapCentre.lat() - x.getPosition().lat()) / 360 * 2 * 3.14 * 6761;
	var tempy = Math.abs(mapCentre.lng() - x.getPosition().lng()) / 360 * 2 * 3.14 * 5329;
	var out = Math.sqrt(tempx * tempx + tempy * tempy);
	return out;
}

function normDist(x) {
	var z = map.getZoom();   //13 normally, 15 when zoomed
	var maxDist = 3.5;
	var minDist = maxDist * 2/7;
	var dist = Math.min(maxDist, degrees2km(x) );
	var distx = Math.max(0, minDist - (z - 13)* minDist / 3);
	return ( (maxDist-distx) - Math.max(0, dist - distx) )/(maxDist-distx);
}

function normRating(x) {
	return (parseFloat(x.rating)^0.5) / (5^0.5);
}

function algorithm(x){
	// normalise the rating
	var q = normRating(x);
	// 1 point for having a booking link
	var b = (x.bookinglink != '');
	// 1 point for 0 to distx, then decline to 0 for 7km
	dist = normDist(x);
	// cuisine type matches
	var c = 0;
	if (selectedCuisine == x.cuisine) c = 1;
	
	algo = (q + b * weightingDist + dist + c * 2);
	return algo;
}

function sortit(a, b) {
	return ( algorithm(b) - algorithm(a) );
}

function highlight(j){
	setSelect(restos[j]);
}
	var weightingDist = 0.7; 

function top10() {
	mapCentre = map.getCenter();
	//alert (mapCentre);
	restos.sort(sortit);
	var topTen = "<h3>Restaurants you might like...</h3><table id='topten'><tr>";
	// ----- OFFICIAL ---------
	topTen += "<td width=50%></td><td width=15%></td><td width=25%></td><td width=20%></td>" 
	for (i=0;i<10;i++) {
		topTen += "<tr>"
		topTen += "<td class=''><a href=javascript:highlight(" + i + ")>" + restos[i].restoName;
		topTen += "</a></td>";
		topTen += "<td class=''><a href=javascript:highlight(" + i + ")><img src='http://www.amsterdamfoodie.nl/af/map/green-small.png' border=0></a></td>"
		topTen += "<td class=''>" + restos[i].cuisine + "</td>";
		topTen += "<td class=''>";
		if (restos[i].bookinglink != '')
			topTen += "<a href='" + restos[i].bookinglink + "' class='booknow' onClick='recordOutboundLink(this, \"Outbound Links\", \"seatme.nl\");return false;'>Book&nbsp;now</a>"
		topTen += "</td>"
		topTen += "</tr>";
	}
	// ------ DEBUG -------------
/*	
	topTen += "<td width=40%></td><td width=10%></td><td width=15%></td><td width=25%></td><td width=20%></td>" 
	topTen += "<tr><td>Name (score)</td><td>Distance</td><td>Dist</td><td>Stars</td><td>Cuisine</td></tr>"
	topTen += "<tr><td></td><td>" + weightingDist + "</td><td>weightingRating</td><td>weighting</td></tr>"
	for (i=0;i<10;i++) {
		topTen += "<tr>"
		topTen += "<td class=''><a href=javascript:highlight(" + i + ")>" + restos[i].restoName;
		topTen += " (" + algorithm(restos[i]).toFixed(1) + ")";
		topTen += "</a></td>";
		topTen += "<td class=''>" +  degrees2km(restos[i]).toFixed(1) + "</td>";
		topTen += "<td class=''>" +  normDist(restos[i]).toFixed(1) + "</td>";
		//topTen += "<td class=''>" + map.getZoom() + "</td>";
		topTen += "<td class=''>" + normRating(restos[i]).toFixed(1) + "</td>";
		topTen += "<td class=''>";
		if (restos[i].bookinglink != '')
			topTen += "1"
		topTen += "</td>"
		topTen += "</tr>";
	}
	*/
	// ---------- END OF DEBUG --------
	topTen += "</table>"
	document.getElementById("top10text").innerHTML = topTen;
}

// -------- Taken from Google -------------

function downloadUrl(url,callback) {
 var request = window.ActiveXObject ?
     new ActiveXObject('Microsoft.XMLHTTP') :
     new XMLHttpRequest;

 request.onreadystatechange = function() {
   if (request.readyState == 4) {
     request.onreadystatechange = doNothing;
     callback(request.responseText, request.status);
   }
 };

 request.open('GET', url, true);
 request.send(null);
}

function parseXml(str) {
   if (window.ActiveXObject) {
     var doc = new ActiveXObject('Microsoft.XMLDOM');
     doc.loadXML(str);
     return doc;
   } else if (window.DOMParser) {
     return (new DOMParser).parseFromString(str, 'text/xml');
   }
 }

 function doNothing() {}


