var OTHelpers = {
	cloneArray: function(dataObj) {
		var anArray = dataObj.anArray;
		var returnArray = new Array();
		$.each(anArray, function() {
			returnArray.push(this);
		});
		return returnArray;
	},
	removeItemFromArray: function(dataObj) {
		var anArray = dataObj.anArray;
		var removeItem = dataObj.anItem;
		var returnArray = new Array();
		$.each(anArray, function() {
			if (this != removeItem) {
				returnArray.push(this);
			}
		});
		return returnArray;
	}
}

/* CLASS: OTMapCustomPanel
 ************************************************************************/ 
var OTMapCustomPanel = function(dataObj) {
	this.map = dataObj.map;
	this.point = dataObj.point;
	this.type = dataObj.type;
	this.insertHTML = dataObj.insertHTML;
	this.content = $('<div class="ot-map-anchor"></div>').get()[0];
	this.panelOffset = dataObj.panelOffset;
}

OTMapCustomPanel.prototype = new GOverlay();

OTMapCustomPanel.prototype.initialize = function() {
	$(this.content).append(this.insertHTML);
	this.map.getPane(G_MAP_FLOAT_PANE).appendChild(this.content);
};


OTMapCustomPanel.prototype.remove = function() {
	this.content.parentNode.removeChild(this.content);
}

OTMapCustomPanel.prototype.redraw = function() {
	var point = this.map.fromLatLngToDivPixel(this.point);
	this.content.style.left   =  point.x + this.panelOffset.left + 'px';
	this.content.style.bottom = -point.y + this.panelOffset.bottom + 'px';
};

/* CLASS: OTMapMarker
 ************************************************************************/ 
var OTMapMarker = function(dataObj) {
	this.xmlData = dataObj.xmlData,
	this.type = dataObj.type;
	this.controller = dataObj.controller;
	this.objMap = dataObj.objMap;
	this.point = "";
	this.objMarker = "";
	this.popupContentHTML = "";
	this.urlLink =  "/";
	this.mapPanel = "";
	this.isVisible = true;
	this.isSearchVisible = true;
	this.contentId = "";
	this.extraInfoLoaded = false;
	self.extraInfo = "";
	return this;
}

OTMapMarker.prototype = {
	init: function() {
		var self = this;

		self.popupContentHTML = self.getPopupContentHTML();

		var latitude = parseFloat($(self.xmlData).attr("location").split(", ")[0]);
		var longitude = parseFloat($(self.xmlData).attr("location").split(", ")[1]);

		self.point = new GLatLng(latitude,longitude);
		self.contentId = $(self.xmlData).attr("id");
		self.initialiseMarker();

		return self;
	},
	initialiseMarker: function() {
		var self = this;

		self.objMarker = self.controller.createMarker({
			type: self.type,
			point: self.point
		});

		GEvent.addListener(self.objMarker, "click", function() {
			self.displayPanel();
			self.objMap.panTo(self.point);
			return false;
		});
	},
	initialAddMarkerToMap: function() {
		var self = this;
		self.addMarkerToMap();
		self.forceHide();
	},
	displayPanel: function() {
		var self = this;
		var aPanel = new OTMapCustomPanel({
			map: self.objMap,
			point: self.point,
			insertHTML: self.popupContentHTML,
			panelOffset: {
				left: -30,
				bottom:	10
			}
		});
		$(self.popupContentHTML).find("a.close").unbind().click( function() {
			self.removePanel();
			return false;	
		});
    	self.objMap.addOverlay(aPanel);
    	if (self.controller.lastMapPanelOwner) {
    		self.controller.lastMapPanelOwner.removePanel();
    	}
    	self.controller.lastMapPanelOwner = self;
    	self.mapPanel = aPanel;
    	self.objMarker.hide();

    	if (!self.extraInfoLoaded) {
    		self.loadExtraInfo({
    			callback: function() {
		    		self.updatePanelWithExtraInfo();	
    			}	
    		});
    	}
	},
	updatePanelWithExtraInfo: function() {
		var self = this;
		$(self.popupContentHTML).each( function() {
			$(this).find(".ot-map-popup-panel-image-holder img").attr("src",self.extraInfo.thumbUrl);
			$(this).find(".ot-map-popup-panel-content h2").text(self.extraInfo.title);
			$(this).find(".ot-map-popup-panel-content p").text(self.extraInfo.intro);
			$(this).find(".ot-map-popup-panel-bottom a").attr("href",self.extraInfo.moreUrl);
		});
		$(self.popupContentHTML).removeClass("ot-map-popup-panel-loading");
	},
	loadExtraInfo: function(dataObj) {
		var self = this;

		var callback = dataObj.callback;

		var ajaxTypeString = (self.type=="trip") ? "trip" : "journal";
		var getUrl = "/data/map-marker-detail/"+ajaxTypeString+"/"+self.contentId+"/";

		$.get( getUrl, function(xml) {
			self.extraInfo = {
				moreUrl: $(xml).find("link").text(),
				title: $(xml).find("title").text(),
				intro: $(xml).find("summary").text(),
				thumbUrl: $(xml).find("image").attr("src")
			}
			if (callback) {
				callback();	
			}
			self.extraInfoLoaded = true;
		});
	},
	removePanel: function() {
		var self = this;
    	self.objMap.removeOverlay(self.mapPanel);
    	self.controller.lastMapPanelOwner="";
    	if (self.isVisible) {
    	    self.objMarker.show();
		}
	},
	addMarkerToMap: function() {
		var self = this;
    	self.objMap.addOverlay(self.objMarker);
	},
	getPopupContentHTML: function() {
		var self = this;
		var insertHTML = '<div class="ot-map-popup-panel ot-map-popup-panel-loading ot-map-popup-panel-'+self.type+'">';
		insertHTML    += '<div class="ot-map-popup-panel-inner">';
		insertHTML    += '<div class="ot-map-popup-panel-content">';
		insertHTML    += '<div class="ot-map-popup-panel-image-holder">';
		insertHTML	  += "<img src='/assets/images/map/empty.gif' alt='' />";
		insertHTML	  += "<div class='ot-map-popup-panel-image-mask'></div>";
		insertHTML	  += "</div>";
		insertHTML    += "<h2>xxx</h2>";
		insertHTML    += "<p></p>";
		insertHTML	  += "</div>";
		insertHTML	  += "</div>";
		insertHTML	  += '<div class="ot-map-popup-panel-bottom">';
		insertHTML	  += "<a href='#'>More info</a>";
		insertHTML	  += "</div>";
		insertHTML	  += '<a href="#" class="close">Close</a>';
		insertHTML	  += "</div>";

		var domPanel = $(insertHTML).get()[0]; 

		return domPanel;
	},
	hide: function() {
		var self = this;
		self.objMarker.hide();
		self.isVisible = false;
		if (self.controller.lastMapPanelOwner == self) {
			self.removePanel();
		}
	},
	reveal: function() {
		var self = this;
			self.isVisible = true;
			if (self.isSearchVisible) {
				self.objMarker.show();
			}
	},
	forceHide: function() {
		var self = this;
		self.objMarker.hide();
	},
	forceReveal: function() {
		var self = this;
		self.objMarker.show();
	}
}

/* CLASS: OTMapController
 ************************************************************************/ 
var OTMapController = function(dataObj) {
	this.domEl = dataObj.domEl;
	this.domMap = $(this.domEl).find(".ot-map-inner").get()[0];
	this.domViewSwitcher = $(this.domEl).find(".ot-map-view-switcher").get()[0];
	this.objMap = "";
	this.markers = new Array();
	this.markers["trip"] = new Array();
	this.numMarkers = 0;
	this.objMapControls = "";
	this.baseIcon = new GIcon();
	this.lastMapPanelOwner = "";
	this.startLocation = "";
	this.numEventsInitialised = 0;
	this.mapType = "";
	this.markerTypes = new Array("trip");
	this.markerTypeConversion = {"trip":"trips"};
	this.selectedView = "trips";
	this.zoomLevel = "";
	this.feedInfo = {};
	return this;
}

OTMapController.prototype = {
	init: function() {
		var self = this;

		self.startLocation = {
			lat: 0,
			lon: 0,
			zoom: 3
		}

		$(self.domEl).find(".ot-map-data-zoom").each( function() {
			self.startLocation.zoom = parseInt($(this).text());
		});

		$(self.domEl).find(".ot-map-data-centre").each( function() {
			self.startLocation.lat = parseFloat($(this).text().split(", ")[0]);
			self.startLocation.lon = parseFloat($(this).text().split(", ")[1]);
		});

		$(self.domEl).find(".ot-map-data-feed-url").each( function() {
			self.feedInfo.url = $(this).text();
		});

		self.mapType ="main";

		self.createCustomIcons();
		self.initialiseMap({
			aDomMap: self.domMap,
			centrePoint: new GLatLng(self.startLocation.lat,self.startLocation.lon),
			zoomLevel: self.startLocation.zoom
		});

		$.get(self.feedInfo.url,{}, function(xml) {
			self.handleMarkerXML(xml);
		});

		return self;
	},

	handleMarkerXML: function(xml) {
		var self = this;

		$.each(self.markerTypes, function() {

			var markerType = this.toString();
			var xmlRelatedMarker = self.markerTypeConversion[markerType];

			$(xml).find(xmlRelatedMarker).find("entry").each(function() {
				var aMarker = new OTMapMarker({
					type: markerType,
					xmlData: this,
					controller: self,
					objMap: self.objMap
				}).init();
				self.markers[markerType].push(aMarker);
			});

			$.each(self.markers[markerType], function() {
				this.initialAddMarkerToMap();
			});

			self.groupMarkersForZoomLevel({zoomLevel: self.zoomLevel, markerType: markerType});
		});
	},
	createCustomIcons: function() {
		var self = this;
		self.baseIcon.iconSize = new GSize(30, 45);
		self.baseIcon.iconAnchor = new GPoint(6, 40);
		self.baseIcon.infoWindowAnchor = new GPoint(6, 40);
	},
	createMarker: function(dataObj) {
		var self = this;
		var type = dataObj.type;
		var point = dataObj.point;
		var iconImage = "/assets/images/map/icon-trip.png";
		var clickable = true;		
		var thisIcon = new GIcon(self.baseIcon);
		thisIcon.image = iconImage;

		return new GMarker(point, { icon: thisIcon, clickable: clickable });
	},
	initialiseMap: function(dataObj) {
		var self = this;
		var aDomMap = dataObj.aDomMap;
		var centrePoint = dataObj.centrePoint;
		self.zoomLevel = (dataObj.zoomLevel) ? dataObj.zoomLevel : 3;
		self.objMap = new GMap2(aDomMap);
		self.objMap.setMapType(G_PHYSICAL_MAP);
		self.objMap.addControl(new GLargeMapControl3D(),new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(10,10)));
		if (centrePoint) {
			self.objMap.setCenter(centrePoint, self.zoomLevel);
		}
	},
	groupMarkersForZoomLevel: function(dataObj) {
		var self = this;
		self.zoomLevel = dataObj.zoomLevel;
		var markerType = dataObj.markerType;
		var items = OTHelpers.cloneArray({ anArray: self.markers[markerType] });

		while (items.length) {
			var startItem = items[0];
			startItem.reveal();
			items = OTHelpers.removeItemFromArray({ anItem: startItem, anArray: items });
		}
	}
}

$(document).ready( function() {

	$("#ot-map").each( function() {
		new OTMapController({
			domEl: this
		}).init();
	});
	
});