$(function() {
	new GUI();
});

GUI = function() {
	var self = this;
	this.MFDistiller =	new MFDistiller();
	google.load("maps", "2", {
		callback: function() {
			self.initialize();
		}
	});	
	$(document).unload(function() { 
		self.unload();
	});
}
GUI.prototype = {
	initialize: function() {
		this.map = new GoogleMap({
			targetElement: 	$("#gMap").get(0),
			startLat: 		52.432572,
			startLng: 		5.254712,
			startZmLvl: 	6
		});
		this.plotVCardsToMap(this.MFDistiller.getGeodVCards()); 
		//this.initializeRouter($("form#routeplanner"), $("div#directions"));
	},
	unload: function() {
		GUnload();
	},
	plotVCardsToMap: function(vcards) {
		for(var i = 0; i < vcards.length; i++) {
			var cardTitle;
			if(vcards[i].vcard.isCompany) {
				cardTitle = '<strong>' + vcards[i].vcard.org.organizationName + '</strong><div>' + vcards[i].vcard.org.organizationUnit + '</div>';
			} else if(vcards[i].vcard.nickname == vcards[i].vcard.fn) {
				cardTitle = '<strong>' + vcards[i].vcard.nickname + '</strong>';
			} else {
				cardTitle = '<strong>' + vcards[i].vcard.honorificPrefix + vcards[i].vcard.fn + ' ' + vcards[i].vcard.n + vcards[i].vcard.honorificSuffix + '</strong>';
			}
			var info = '<div class="GMapMarkerInfo" style="padding:0 10px 1em 10px;"><div>' + cardTitle + '</div><div>' + vcards[i].address.streetAddress + '</div><div>' + vcards[i].address.postalCode + ' ' + vcards[i].address.locality + '</div><div>' + vcards[i].address.countryName + '</div></div>';
			this.map.addPoint({
				latitude: vcards[i].latitude,
				longitude: vcards[i].longitude,
				info: info
			});
			this.map.setZoomToData();
		}
	},
	initializeRouter: function(form, panel) {
		this.routerForm = form;
		this.directionsPanel = panel;
		var self = this;
		form.submit(function(e) {
			e.preventDefault();
			var from = form.get(0).saddr.value;
			var to = form.get(0).daddr.value;
			self.askDirections(from, to, panel);
		});
	},
	askDirections: function(from, to) {
		this.map.getDirections(from, to, this.directionsPanel);
	}
}





// Make a Google Map
/* documentation at: http://code.google.com/apis/maps/documentation/ */
GoogleMap = function(params) {
	this.map = new google.maps.Map2(params["targetElement"]);
	this.map.setCenter(new google.maps.LatLng(params["startLat"] || 37.160317, params["startLng"] || 5.273438), params["startZmLvl"] || 2);	
	this.map.addControl(new GSmallMapControl());
	this.map.addControl(new GMapTypeControl());
	this.markers = new Array();
	this.directions;
	this.bounds = new GLatLngBounds();
}
GoogleMap.prototype = {
	addPoint: function(params) {
		var point = new GLatLng(params["latitude"], params["longitude"]);
		var marker = this.markers[this.markers.length] = this.createMarker(point,params["info"])
		this.map.addOverlay(marker);
		this.bounds.extend(point);
	},
	purgeMarkers: function() {
		this.map.clearOverlays()
		this.bounds = new GLatLngBounds();
	},
	createMarker: function(point, html) {		
        var marker = new GMarker(point);
        GEvent.addListener(marker, "click", function() {
			marker.openInfoWindowHtml(html);
        });
        return marker;
	},
	addKML: function(url) {
		var gx = new GGeoXml(url);
		this.map.addOverlay(gx);
	},
	getDirections: function(from, to, panel) {
		var self = this;
		this.directionsPanel = panel;
		if(this.directions) this.directions.clear();
		this.directions = new GDirections(this.map, (this.directionsPanel) ? this.directionsPanel.get(0) : null);
		var testFrom = new GClientGeocoder();
		testFrom.getLatLng(from, function() { self.fetchDirections(from, to); });
		// TODO: feedback bij onsuccesvolle test, test aparte method maken
	},
	fetchDirections: function(from, to) {
		var query = "from:" + from + " to:" + to;
		var options = {
			locale: 			"nl",
			preserveViewport: 	false
		}
		this.directions.load(query, options);		
	},
	setZoomToData: function() {
		this.map.setZoom(this.map.getBoundsZoomLevel(this.bounds)-1);
		this.map.setCenter(this.bounds.getCenter());
	}
}





// Scrape Microformats
/* specs at: 	http://microformats.org/wiki/hcard, 
				http://microformats.org/wiki/adr */
MFDistiller = function(root) {
	this.root = root ? root : $(document);
	this.vcards = this.distillVCards();
}
MFDistiller.prototype = {
	distillVCards: function() {
		var cards = new Array();
		$(".vcard", this.root).each(function() {
			// fetch separate email addresses
			var emails = new Array();
			$(".email", $(this)).each(function() {
				emails[emails.length] = {
					type: 				$("abbr.type", $(this)).attr("title") || $(".type", $(this)).text(),
					value: 				$("abbr.value", $(this)).attr("title") || $(".value", $(this)).text() || $(this).text()
				}
			});
			// fetch separate telephone numbers
			var tels = new Array();
			$(".tel", $(this)).each(function() {
				tels[tels.length] = {
					type: 				$("abbr.type", $(this)).attr("title") || $(".type", $(this)).text(),
					value: 				$("abbr.value", $(this)).attr("title") || $(".value", $(this)).text() || $(this).text()
				}
			});
			// fetch separate addresses
			var addresses = new Array();
			$(".adr", $(this)).each(function() {
				addresses[addresses.length] = {
					type: 				$("abbr.type", $(this)).attr("title") || $(".type", $(this)).text(),
					streetAddress: 		$(".street-address", $(this)).text(),
					extendedAddress: 	$(".extended-address", $(this)).text(),
					locality: 			$(".locality", $(this)).text(),
					region: 			$("abbr.region", $(this)).attr("title") || $(".region", $(this)).text(),
					postalCode: 		$(".postal-code", $(this)).text(),
					postOfficeBox: 		$("abbr.post-office-box", $(this)).attr("title") || $(".post-office-box", $(this)).text(),
					countryName: 		$("abbr.country-name", $(this)).attr("title") || $(".country-name", $(this)).text(),
					geo: 				{
											latitude: $(".geo abbr.latitude", $(this)).attr("title") || $(".geo .latitude", $(this)).text(),
											longitude: $(".geo abbr.longitude", $(this)).attr("title") || $(".geo .longitude", $(this)).text(),
											tz: $(".geo abbr.tz", $(this)).attr("title") || $(".geo .tz", $(this)).text()
										}
				}
			});
			// construct vcard object
			var vcard = {
				sourceElement:		$(this),
				uid: 				{
										type: $(".uid abbr.type", $(this)).attr("title") || $(".uid .type", $(this)).text(),
										value: $(".uid abbr.value", $(this)).attr("title") || $(".uid .value", $(this)).text() || $(".uid", $(this)).text()
									},
				rev: 				$("abbr.rev", $(this)).attr("title") || $(".rev", $(this)).text(),
				Class: 				$("abbr.class", $(this)).attr("title") || $(".class", $(this)).text() || "public",
				fn: 				$(".fn", $(this)).text(),
				n: 					$(".n", $(this)).text(),
				givenName: 			$(".given-name", $(this)).text(),
				additionalName: 	$("abbr.additional-name", $(this)).attr("title") || $(".additional-name", $(this)).text(),
				familyName: 		$(".family-name", $(this)).text(),
				nickName: 			$(".nickname", $(this)).text(),
				honorificPrefix: 	$("abbr.honorific-prefix", $(this)).attr("title") || $(".honorific-prefix", $(this)).text(),
				honorificSuffix: 	$("abbr.honorific-suffix", $(this)).attr("title") || $(".honorific-suffix", $(this)).text(),
				title: 				$("abbr.title", $(this)).attr("title") || $(".title", $(this)).text(),
				role: 				$(".role", $(this)).text(),
				org: 				{
										organizationName: $(".organization-name", $(this)).text() || $(".org", $(this)).text(),
										organizationUnit: $(".organization-unit", $(this)).text()
									},
				email: 				emails,
				url: 				$("a.url", $(this)).attr("href") || $(".url", $(this)).text(),
				tel: 				tels,
				adr: 				addresses,
				bday: 				$("abbr.bday", $(this)).attr("title") || $(".bday", $(this)).text(),
				photo: 				$("a.photo", $(this)).attr("href") || $("img.photo", $(this)).attr("src") || "",
				logo: 				$("img.logo", $(this)).attr("src") || "",
				category: 			$(".category", $(this)).text(),
				note: 				$(".note", $(this)).text(),
				mailer: 			$(".mailer", $(this)).text(),
				sortString: 		$("abbr.sort-string", $(this)).attr("title") || $(".sort-string", $(this)).text(),
				isCompany: 			$(".org", $(this)).text() == $(".fn", $(this)).text()
			}
			cards[cards.length] = vcard;
		});
		//console.log(cards);
		return cards;
	},
	getVCards: function() {
		return this.vcards;
	},
	getGeodVCards: function() {
		var output = new Array();
		for(var i = 0; i < this.vcards.length; i++) {
			if(this.vcards[i].adr.length > 0) for(var j = 0; j < this.vcards[i].adr.length; j++) {
				var lat = this.vcards[i].adr[j].geo.latitude;
				var lng = this.vcards[i].adr[j].geo.longitude;
				if(lat && lng) {
					output[output.length] = {
						latitude: lat,
						longitude: lng,
						address: this.vcards[i].adr[j],
						vcard: this.vcards[i]
					}
				}
			}
		}
		return output;
	}
}

