var map = function () {
	return {

		// Vars
		
		links : {},
		map : null,
		markers : null,
		conn : null,
		params : {},
		defaultParams : {
			c : ['trail']
			// p : 1
		},
		kmlData : {
			'bikelane' : '/kml/bikelane.kmz',
			'bikeway' : '/kml/bikeway.kmz',
			'cautionary' : '/kml/cautinary.kmz',
			'trails' : '/kml/trails.kmz'
		},
		reverseCatMap : {
			'Reported Crashes' : 'crash',
			'Trail Access' : 'trail',
			'Bike Shops' : 'shop',
			'Landmarks' : 'landmark',
			'Notes' : 'note',
			'Bridges' : 'bridge'
		},
		kml : {},
		loc : null,
		icon : null,
		geo : null,
		
		// Methods
		
		init : function() {
		  $('#shim').css('opacity', 0.5);
		},
		
		initMainIndex : function() {
			// Init the map

			var myOptions = {
				'zoom' : 12,
				'center' : new google.maps.LatLng(40.4406248, -79.9958864),
				'mapTypeId': google.maps.MapTypeId.ROADMAP
			};
			map.map = new google.maps.Map(document.getElementById("map"), myOptions);
			map.markers = new MarkerManager(map.map);
			// map.clusters = new MarkerClusterer(map.map);

			// Parse map params
			
			map.loadMapParams();
			
			// Init nav
			
			map.initNav();
			
			// Init KMLs
			
			map.initKML();
		},
		
		initNav : function() {
			// Init main nav

			$('#nav li a').click(function(e) {
				e.preventDefault();
				$(this).blur();
				
				if ($(this).parents('li').hasClass('selected')) {
					if ($('#nav li.selected').length === 1) {
						return; // Do not allow to unselect last remaining selected category
					}
					$(this).parents('li').removeClass('selected');
				} else {
					$(this).parents('li').addClass('selected');
				}
				
				var lis = $('#nav li.selected');
				var cats = [];
				for (var i=0; i<lis.length; i++) {
					cats[cats.length] = $.trim(lis[i].className.replace('selected', ''));
				}
				map.params.c = cats;
				// map.params.p = 1;
				
				// Update hash and get data

				map.setHash();
			  map.loadData();
			});
			
			// Init pagination
			
			// $('#pag li a').live('click', function(e) {
			// 	e.preventDefault();
			// 	$(this).blur();
			// 	var li = $(this).parents('li');
			// 
			// 	if (li.hasClass('off')) {
			// 		return;
			// 	}
			// 	
			// 	if (li.hasClass('next')) {
			// 		map.params.p = map.params.p + 1;
			// 	} else if (li.hasClass('prev')) {
			// 		map.params.p = map.params.p - 1;
			// 	}
			// 	
			// 	// Update hash and get data
			// 
			// 	map.setHash();
			// 	map.loadData();
			// });
		},
		
		initKML : function() {
			$('#kml input').click(function(e) {
				if ($(this).attr('checked') === true) {
					if (typeof map.kml[$(this).val()] == 'undefined') {
						map.kml[$(this).val()] = new google.maps.KmlLayer(map.links.domain + map.kmlData[$(this).val()], {preserveViewport: true});
					}
					map.kml[$(this).val()].setMap(map.map);
				} else {
					map.kml[$(this).val()].setMap(null);
				}
			});
		},
		
		loadMapParams : function() {
			map.params = $.extend({}, map.defaultParams);

			var hash = window.location.hash;
			if (hash !== '') {
				hash = hash.split('&');
				var k, v, o, cats;
				for (var i=0; i<hash.length; i++) {
					k = hash[i].split('=');
					v = k[1];
					k = k[0].replace('#', '');
					
					// Load category
					
					if (k == 'c') {
						v = v.split(',');
						cats = [];
						for (o=0; o<v.length; o++) {
							if (v[o] == 'crash' || v[o] == 'trail' || v[o] == 'shop' || v[o] == 'landmark' || v[o] == 'note' || v[o] == 'bridge') {
								cats[cats.length] = v[o];
							}
						}
						map.params.c = cats;
					}
					
					// Load page
					
					// if (k == 'p') {
					// 	map.params.p = Math.abs(v*1);
					// }
				}
			}
			
			// Update nav
			
			$('#nav li').removeClass('selected');
			for (i=0; i<map.params.c.length; i++) {
				$('#nav li.' + map.params.c[i]).addClass('selected');
			}
			
			// Update hash and get data
			
			map.setHash();
			setTimeout(function() {
			  map.loadData();
			}, 500);
		},
		
		setHash : function() {
			window.location.hash = map.arr2hash(map.params);
		},
		
		arr2hash : function(arr) {
			var hash = [];
			for (var k in arr) {
				if (typeof arr[k] != 'function') {
					if (k == 'c') {
						hash[hash.length] = k + '=' + arr[k].join(',');
					} else {
						hash[hash.length] = k + '=' + arr[k];
					}
				}
			}
			
			return hash.join('&');
		},
		
		loadData : function() {
			// Show loading visuals
			
			// $('#pag').empty();
			$('#table').html('<p class="loading">Loading...</p>');
			try {
				map.markers.clearMarkers();
				// map.clusters.clearMarkers();
			} catch(e) {}
			
			// Load data
			
			if (map.conn) {
				map.conn.abort();
			}
			
			var params = $.extend(true, {}, map.params);
			params.c = params.c.join(',');

			map.conn = $.getJSON(map.links.apiGet, params, function(data, status) {
				if (status == 'success' && !data.error) {
					map.renderMap(data);
					map.renderHtml(data);
				} else {
					if (data.error) {
						alert(data.errorInfo);
					} else {
						alert('Your request could not be processed right now. Please try again later.');
					}
				}
			});
		},
		
		renderMap : function(data) {
			var total = data.items.length;
			var item, icon, pos, bounds = new google.maps.LatLngBounds();
			
			var e_mover = function() {
				$('#table tr').removeClass('hl');
				$('#table tr.item_' + this._id).addClass('hl');
			};
			var e_mout = function() {
				$('#table tr').removeClass('hl');
			};
			var e_click = function() {
				map.loadDetails(this._id);
			};
			
			var markers = [];
			for (var i=0; i<total; i++) {
				item = data.items[i];
				pos = new google.maps.LatLng(item.loc.lat, item.loc.lon);
				bounds.extend(pos);
				icon = new google.maps.Marker({
					position: pos,
					icon: new google.maps.MarkerImage(
						'/images/map/' + map.reverseCatMap[item.category] + '.png',
						new google.maps.Size(30, 33, 'px', 'px'),
						null,
						new google.maps.Point(2, 23)
					),
					title: item.name
				});
				icon._id = item._id;
				map.markers.addMarker(icon, 3);
				// map.clusters.addMarker(icon, true);
				markers[markers.length] = icon;
				google.maps.event.addListener(icon, 'mouseover', e_mover);
				google.maps.event.addListener(icon, 'mouseout', e_mout);
				google.maps.event.addListener(icon, 'click', e_click);
			}
			map.map.fitBounds(bounds);
			// map.clusters.redraw();
			
			// Ensure that the zoom is not full-on. Zoom out a bit
			
			if (map.map.getZoom() == 20) {
				map.map.setZoom(17);
			}
		},
		
		renderHtml : function(data) {
			$('#table').html(data.table_html);
			// $('#pag').html(data.pagination_html);
		},
		
		loadDetails : function(id) {
			// Show shim

			$('#shim').fadeIn(150);
			$('#shimLoad').css({
				'left' : (($(window).width() - $('#shimLoad').width()) / 2) + 'px',
				'top' : (($(window).height() - $('#shimLoad').height()) / 2) + 'px'
			}).fadeIn(150);
			
			// Get html
			
			$.getJSON(map.links.apiDetails, {'id' : id}, function(data, status) {
				if (status == 'success' && !data.error) {
					$('#popupDetails .popup_content').html(data.html);
					
					// Shim click event
					
					$('#shim').click(function(e) {
						$('#popupDetails').fadeOut(150, function(e) {
							$('#shim').fadeOut(150);
						});
						$('#shim').unbind('click');
						$('#popupDetails a.close').unbind('click');
					});
					$('#shimLoad').css('display', 'none');
					
					// Show popup
					
					$('#popupDetails').css({
						'left' : (($(window).width() - $('#popupDetails').width()) / 2) + 'px',
						'top' : (($(window).height() - $('#popupDetails').height()) / 2) + 'px'
					}).fadeIn(150);
					
					// Popup click event

					$('#popupDetails a.close').live('click', function(e) {
						e.preventDefault();
						$('#popupDetails').fadeOut(150, function(e) {
							$('#shim').fadeOut(150);
						});
						$('#shim').unbind('click');
						$('#popupDetails a.close').unbind('click');
					});
				} else {
					alert(data.errorInfo);
					$('#shim').css('display', 'none');
				}
			});
		},
		
		initMainNewCrash : function() {
			map.geo = new google.maps.Geocoder();
			var latlng = new google.maps.LatLng(40.44178428919212, -80.01283796097412);
			var myOptions = {
				zoom: 16,
				center: latlng,
				mapTypeId: google.maps.MapTypeId.ROADMAP
			};
			map.map = new google.maps.Map(document.getElementById("map2"), myOptions);
			map.icon = new google.maps.Marker({
				'position' : latlng,
				'draggable' : true,
				'map' : map.map
			});
			google.maps.event.addListener(map.icon, 'dragend', function(e) {
				$('#loc_lat').val(e.latLng.lat());
				$('#loc_lon').val(e.latLng.lng());
			});
			$('#loc_lat').val(latlng.lat());
			$('#loc_lon').val(latlng.lng());
			
			// Relocate button
			
			$('button.action-relocate').click(function(e) {
				e.preventDefault();
				if ($('#address').val() === '') {
					$('#address').focus();
				}
				map.geo.geocode({'address':$('#address').val()}, function(data, status) {
					if (status == 'OK' && data.length > 0 && data[0].geometry && data[0].geometry.location) {
						map.map.setCenter(data[0].geometry.location);
						map.icon.setPosition(data[0].geometry.location);
						$('#loc_lat').val(data[0].geometry.location.lat());
						$('#loc_lon').val(data[0].geometry.location.lng());
					}
				});
			});
		}

	};
}();

