var MapEvents = {
	$resultTemplate: null,
	$infowinTemplate: null,
	iconTemplate: null,
	
	$tab: null,
	
	form: {
		$selMonth: null,
		$selYear: null,
		$cbCats: null
	},
	
	$results: null,
	
	cache:{},
	lastResults: [],
	
	setup: function(load) {
		MapEvents.$tab = $('#luau').removeClass('hidden');

		MapEvents.form.$selMonth = MapEvents.$tab.find("select[name=eventMonth]");
		MapEvents.form.$selYear  = MapEvents.$tab.find("select[name=eventYear]");
		MapEvents.form.$cbCats   = MapEvents.$tab.find('input.ecatCB');

		MapEvents.$results = MapEvents.$tab.find('.results:first');
		
		// Listen for click on "update map" button
		MapEvents.$tab.find('button.updatemap').click(function(){ MapEvents.search(); });
		// Listen for click on "Select All" link
		MapEvents.$tab.find('a.selectAll').click(function() { MapEvents.toggleSelectAll(); return false; });
		
		// Import the result row
		MapEvents.$resultTemplate = MapEvents.$results.find('.event').remove().removeClass('hidden');
		
		Sm2Poi.Map.addListener('tab_change', MapEvents.onTabChange);
		
		MapEvents.$results.height(300);
		
		// If no initial tab is selected, or this is specified as the initial tab, open this tab
		if (load.indexOf('luau') === 0) {
			var params = load.split('/');
			if (params[1]) {
				var ids = params[1].split(',');
				MapEvents.form.$cbCats.each(function() {
					this.checked = $.inArray(this.value, ids) >= 0;
				});
				MapEvents.search(function() {
					if (params[2]) {
						MapEvents.map(params[2]);
					}
				});
			}
			Sm2Poi.Map.openTab('luau');
		}
	},
	
	toggleSelectAll: function() {
		var cats = MapEvents.form.$cbCats.filter(':checked');
		MapEvents.form.$cbCats.attr('checked', cats.length!=MapEvents.form.$cbCats.length);
	},
	
	search: function(callback) {
		MapEvents.$results.removeClass('empty').addClass('loading').find('.event').remove();
		var ids = MapEvents.getCheckedCategories();
		
		// Request data from the server
		$.getJSON('/sitemanager2/events/ajax.php', {act:'mapSearch', categories:ids.join(','), date:MapEvents.$tab.find("select[name=eventMonth]").val()+'-'+MapEvents.$tab.find("select[name=eventYear]").val()}, function(data) {
			MapEvents.handleSearchResults(data, callback);
		});
	},
	
	/**
	 * Takes IDs returned from the server and displays them
	 * @param {Array} ids List of IDs to load
	 * @param {Function} callback Function to call when all POIs have been loaded
	 */
	handleSearchResults: function(ids, callback) {
		if (!ids) {
		//if (!ids  ||  !parseInt(ids[0])) {
			MapEvents.displayResults({}, []);
			if (callback) callback();
		} else {
			MapEvents.getEvents(ids, 
				function(events, ids) {
					MapEvents.displayResults(events, ids);
					if (callback) { callback(); }
				}
			);
		}
	},
	
	displayResults: function(events, ids) {
		var results = [];
		var markers = [];
		MapEvents.lastResults = ids;
		
		$.each(ids, function() {
			// If this ID is new, build marker and result row for it
			if ( !MapEvents.cache[this].marker ) {
				MapEvents.cache[this].marker = MapEvents.buildMarker(events[this]);
				MapEvents.cache[this].result = MapEvents.buildResult(events[this]);
			}
			results.push(MapEvents.cache[this].result);
			markers.push(MapEvents.cache[this].marker);
		});
			
		MapEvents.showResults(results);
		MapEvents.showMarkers(markers);
	},
	
	buildResult: function(data) {
		// Set map icon source
		var mapIconSrc = '/sitemanager2/poi/images/genericMapIcon.png';
		if (parseInt(data.mapIconId)) mapIconSrc = '/sitemanager2/poi/mapicon.php?id='+data.poi.mapIconId+'&type=legend';
		
		var x = data._id.split('-');
		var date = data.start.split(' ')[0].split('-');
		$row = MapEvents.$resultTemplate.clone()
			.find('img.mapicon').attr('src', mapIconSrc).end()
			.find('.data_title').html("<strong>"+data.title+"</strong>").end()
			.find('.data_date').html(date[1]+"/"+date[2]+"/"+date[0]).end()
			.find('a.map').attr('href', 'javascript:MapEvents.map("'+data._id+'")').end()
			.find('a.info').attr('href', '/events/'+data._id).click(function() { MapEvents.saveLink(); }).end()
			;
			
		// If addressable, show address
		if (data.city  &&  data.state) $row.find('address').html(data.city+', '+data.state);
		else $row.find('address').remove();

			
		// If mappable, show link
		$row.addClass('mappable');
			
		$row.data('city', data.poi.city);
			
		return $row;
	},
	
	buildMarker: function(data) {
		
		var marker = null;

		var fn = function() {

			MapEvents.map(data._id);
		}
		marker = Sm2Poi.Map.createMarker(data.poi.lat, data.poi.lon, fn, data.poi.mapIconId);
		marker._sm2Id = data.id;
		marker.title = data.title;
		
		return marker;
	},
	
	buildInfoWindowHtml: function(data) {
		var html = '<div class="infowin">';
		
		html += '<div class="title">' + data.title + '</div>';
		
		if (data.poi) html += '<div class="poi">at ' + data.poi.title + '</div>';
		
		html += '<div class="links">';
		html += 	'<a href="/links/'+data.id+'" onclick="MapEvents.saveLink()"><img src="/sitemanager2/poi/images/icon_info.png" alt="[>]"/> More Info</a>';
		html +=     '<br />';
		
		var inIt = Sm2Poi.Itinerary.inItinerary(data.id);
		var cl = inIt ? 'in' : 'out';
		var ht = inIt ? 'Remove from My Itinerary' : 'Add to My Itinerary';
		
		if (Sm2Poi.Itinerary.inItinerary(data.id))
			html += '<a rel="'+data.id+'" class="toggleItineraryLink" href="" onclick="Sm2Poi.Itinerary.toggleLink('+data.id+'); return false;"><img src="/sitemanager2/poi/images/icon_itineraryRem.png" alt="[-]"/> Remove from My Itinerary</a>';
		else
			html += '<a rel="'+data.id+'" class="toggleItineraryLink" href="" onclick="Sm2Poi.Itinerary.toggleLink('+data.id+'); return false;"><img src="/sitemanager2/poi/images/icon_itineraryAdd.png" alt="[+]"/> Add to My Itinerary</a>';
		html += '</div>';
		
		html += '</div>';
		return html;
	},
	
	showMarkers: function(arr) {
		Sm2Poi.Map.gmap.clearOverlays();
		$.each(arr, function() { Sm2Poi.Map.gmap.addOverlay(this); });
	},
	
	showResults: function(arr) {
		var lastCity = '';
		
		MapEvents.$results.removeClass('loading');
		if (arr.length == 0) MapEvents.$results.addClass('empty');
		else MapEvents.$results.removeClass('empty');

		$.each(arr, function() {
			var city = this.data('city');
			if (city && city.toLowerCase() != lastCity) {
				lastCity = city.toLowerCase();
				MapEvents.$results.append('<li class="city">'+city+'</li>');
			}
			MapEvents.$results.append(this);
		});
	},
	
	map: function(id) {
		// Save what marker was clicked on so it can be re-selected on page refresh
		//MapEvents.saveLink('/'+id);
		MapEvents.cache[id].marker.openInfoWindow(MapEvents.buildInfoWindowHtml(MapEvents.cache[id].data));
		// Open the info window
//		MapEvents.cache[id].marker.openInfoWindow(MapEvents.buildInfoWindowHtml(Sm2Poi.Map.poiCache[id].data));
	},
	
	onTabChange: function(tab) {
		if (tab != 'luau') {
			// Hide all previous markers
			$.each(MapEvents.lastResults, function() {
				var m = MapEvents.cache[this].marker;
				if (m) {
//					m.closeInfoWindow();
					m.hide();
				}
			});
		}
		else {
			// Show the previous markers
			$.each(MapEvents.lastResults, function() {
				var m = MapEvents.cache[this].marker;
				if (m) m.show();
			});
			// Save link into URL
			//MapEvents.saveLink();
		}
	},
	
	getCheckedCategories: function() {
		var cats = MapEvents.form.$cbCats.filter(':checked');
		//if (cats.length == MapEvents.form.$cbCats.length) return ['*'];
		
		var result = cats.map(function() { return this.value; });
		return $.makeArray(result);
	},
	
	saveLink: function(extra) {
		var cats = MapEvents.getCheckedCategories();
		var date = $("#eventMonth").val()+'-'+$("#eventYear").val();
		window.location.replace('#events/' + date + (cats.length>0 ? '/'+cats.join(',') : '') + (extra || ''));
	},
	
	/**
	 * Loads a set of events from the cache (or remote database, if not in cache)
	 * @param {Array} ids List of event IDs to return data for
	 * @param {Function} callback Function to call with full events data:
	 *                            function callback(data, ids)
	 *                            data={1:{...}, 2:{...}, ...}
	 *                            ids=[1,2,...]
	 */
	getEvents: function(ids, callback) {
		var f = [];
		var d = {};
		// Loop through the given IDs and figure out which ones we need to
		// fetch data for
		$.each(ids, function() {
			if (!MapEvents.cache[this]) {
				f.push(this);
			} else { 
				d[this] = MapEvents.cache[this].data;
			}
		});

		// Fetch data for unloaded events
		if (f.length > 0) {
			$.getJSON('/sitemanager2/events/ajax.php', {act:'mapGet', ids:f.join(',')}, function(evData) {
				var poiIds = [];
				$.each(evData, function() {
					MapEvents.cache[this._id] = {data:this};
					d[this._id] = this;
					if (this.poiId) poiIds.push(this.poiId);
				});
				if (poiIds.length > 0) {
					Sm2Poi.Map.getPois(poiIds, function() {
						callback(d, ids);
					});
				} else {
					callback(d, ids);
				}
			});
		} else { // All events already in cache
			callback(d, ids);
		}
	}
};
Sm2Poi.Map.addListener('map_ready', MapEvents.setup);
