/**
* @fileoverview Wrapper for Google Maps API v3
*/

// Create NetR namespace if it doesn't exist
if (typeof(NetR) === 'undefined') { 
	var NetR = {}; 
}

NetR.GMaps = function() {
	var map = null;
	// Default options
	var options = {
		defaultCenter: [63.442651, 15.629881],
		defaultZoom: 4,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		showMapTypes: true,
		mapContainerId: '',
		mapElementId: 'map',
		mapClass: '',
		markerAtCenter: false,
		markers: [],
		markersXML: '',
		XMLMarkerNodeName: '',
		XMLMarkerLinkText: '',
		loadComplete: null
	};

	/**
	* Creates a marker on the map, with info bubble displaying on mouseover
	* @param lat Latitude for marker location
	* @param lon Longitude for marker location
	* @param url URL for more info about marker location
	* @param name Name of location
	* @param linkURLs URLs of links that have corresponding map markers
	*/
	function createMarker(map, lat, lon, url, name, body, linkURLs) {
		//var point = new GLatLng(lat, lon);
		var point = new google.maps.LatLng(lat, lon);

		image = new google.maps.MarkerImage('/i/discover/markers/image.png',
		// This marker is 20 pixels wide by 32 pixels tall.
			new google.maps.Size(58, 58),
		// The origin for this image is 0,0.
			new google.maps.Point(0, 0),
		// The anchor for this image is the base of the flagpole at 0,32.
			new google.maps.Point(29, 58)
		);

		var shadow = new google.maps.MarkerImage('/i/discover/markers/shadow.png',
		// The shadow image is larger in the horizontal dimension
		// while the position and offset are the same as for the main image.
			new google.maps.Size(87, 58),
			new google.maps.Point(0, 0),
			new google.maps.Point(29, 58)
		);

		var marker = new google.maps.Marker({
			position: point,
			map: map,
			shadow: shadow,
			icon: image,
//			shape: {
//				coord: [1, 1, 1, 16, 16, 16, 16, 1],
//				type: 'poly'
//			},
			title: name
		});

		var windowHtml = '<div class="bubble"><a class="action" href="' + url + '">' + name + '</a><br />' + body + '</div>';
		var infowindow = new google.maps.InfoWindow({
			content: windowHtml
		});

		google.maps.event.addListener(marker, 'click', function() {
			infowindow.open(this.map, marker);
		});

		var domain = "http://" + document.domain;
		if (linkURLs[domain + url]) {
			$(linkURLs[domain + url]).bind('mouseover', windowHtml);
		}
	}

	/**
	* Creates markers from XML document on map
	* @param xml The XML document returned by an Ajax request
	*/
	function createMarkers(xml) {
		var points = xml.getElementsByTagName(options.XMLMarkerNodeName);
		var linkURLs = {};
		if (options.restaurantList) {
			var linkContainer = document.getElementById(options.restaurantList);
			if (linkContainer) {
				var links = linkContainer.getElementsByTagName("a");
				for (var i = 0, len = links.length; i < len; i++) {
					linkURLs[links[i].href] = links[i];
				}
			}
		}
		var point;
		for (var i = 0, len = points.length; i < len; i++) {
			point = points[i];
			createMarker(this.map, point.getAttribute('latitude'), point.getAttribute('longitude'), point.getAttribute('URL'), point.getAttribute('name'), point.getAttribute('body'), linkURLs);
		}
	}

	/**
	* Performs Ajax call to get XML data for markers
	* @requires jQuery
	* @param {string} XMLPath URL for XML document
	*/
	function loadMarkersFromXML(XMLPath) {
		$.ajax({
			type: 'GET',
			dataType: 'xml',
			url: XMLPath,
			success: function(xml) {
				createMarkers(xml);
			}
		});
	}

	/**
	* Loads map into element with id from options.mapContainerId
	*/
	function load() {
		if (document.getElementById(options.mapContainerId)) {
			// Create element
			var mapContainer = document.getElementById(options.mapContainerId);
			var mapElement = document.createElement('div');
			mapElement.id = options.mapElementId;

			if (options.mapClass && options.mapClass.length > 0) {
				mapElement.className = options.mapClass;
			}

			mapContainer.innerHTML = '';
			mapContainer.appendChild(mapElement);

			var centerPoint = new google.maps.LatLng(options.defaultCenter[0], options.defaultCenter[1]);

			// Init map
			map = new google.maps.Map(mapElement, {
				center: centerPoint,
				zoom: options.defaultZoom,
				mapTypeId: options.mapTypeId,
				mapTypeControl: options.showMapTypes,
				mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.DROPDOWN_MENU }
			});

			// Marker at center point?
			if (options.markerAtCenter) {
				new google.maps.Marker({
					position: centerPoint,
					map: map
				});
			}

			// Add additional markers?
			if (options.markers && options.markers.length > 0) {
				for (var i = 0, len = options.markers.length; i < len; i++) {
					map.addOverlay(new GMarker(new GLatLng(options.markers[i][0], options.markers[i][1])));
				}
			}

			if (options.markersXML && options.markersXML.length > 0) {
				loadMarkersFromXML(options.markersXML, createMarkers);
			}

			// Execute loadComplete function (if it exists)
			if (typeof (options.loadComplete) === "function") {
				options.loadComplete(map);
			}
		}
	}

	/**
	* Accessor function for map object
	*/
	function getMap() {
		return map;
	}

	/**
	* Initialization
	*/
	function init(opts) {
		if (!document.getElementById || !document.createElement) {
			return;
		}
		// If options were supplied, apply them to the option Object.
		for (var key in opts) {
			if (options.hasOwnProperty(key)) {
				options[key] = opts[key];
			}
		}
		load();
		return map;
	}

	return {
		init: init,
		createMarkers: createMarkers,
		createMarker: createMarker,
		getMap: getMap
	};
} ();
