var map = null;
var icon = null;
var open_elem = null;
var radius = null;
var cPoint = null;
var IE = document.all? true : false ;
var transport_ref = false;
var marker_cache = new Array;
var currentInfoWindow = null;

function load(){
	//feedback sits underneath the spinning icon
	$('loading-feedback').innerHTML = "Setting up the map";
	

  if (GBrowserIsCompatible()) {
  	//initialise the map
    map = new GMap2(document.getElementById("google-map"),{backgroundColor:"#ffffff"});
    cPoint = new GLatLng(51.33, -1.9); //default centre 51.4516182, -2.5982130
    map.setCenter(cPoint, 9);
    map.enableDoubleClickZoom();
    map.addControl(new GSmallZoomControl());
    
    //setup some event listeners
    GEvent.addListener(map, "dragend", function(){ updateMap(); });
    GEvent.addListener(map, "zoomend", function(old_level, new_level){ if(old_level > new_level) updateMap(); });
    
	$$('form#maplegend input[type=checkbox]').each(function(item){ item.onclick= function(){ updateMap(); }; });
	$$('form#maplegend input[type=submit]').invoke('hide');
		
		//get the first set of markers
		window.setTimeout("updateMap('nofade');", 0);
  }
}

//needed for google maps
Event.observe(window, 'load', load);
Event.observe(window, 'unload', GUnload);

var updateMap = function(e){
	if(transport_ref)
		transport_ref.transport.abort();
	//if this is the first ajax call dont fade in the loader (it's already there)
	if(e!='nofade')
		new Effect.Opacity('spinny', { fps: 18, duration: 0.3, from: 0, to: 0.6, beforeStart: function(){$('spinny').setStyle({left:'0px'});} });
	$('loading-feedback').innerHTML = "Fetching profiles";
	
	
	var map_bounds = map.getBounds();
	var sw_point = map_bounds.getSouthWest();
	var ne_point = map_bounds.getNorthEast();
	var categories = new Array;
	$$('form#maplegend input[type=checkbox]').each(function(c){ if(c.checked){ categories.push(c.value); }});
	//standard query contains just the window bounds
	var query="sw[lat]="+sw_point.lat()+"&sw[lng]="+sw_point.lng()+"&ne[lat]="+ne_point.lat()+"&ne[lng]="+ne_point.lng();
	query += "&categories[]="+categories.join('&categories[]=');
	
	//make the ajax call
	transport_ref = new Ajax.Request('/directory.json', {
							method: 'get',
							parameters: query,
							asynchronous:true,
							onSuccess: setMarkers,
							onFailure: function(){ new Effect.Opacity('spinny', { delay: 0.5, fps: 18, duration: 1, from: 0.6, to: 0, beforeStart: function(){ $('loading-feedback').innerHTML = "Failed to find directory of profiles."; }, afterFinish: function(){ $('spinny').setStyle({left:'-800px'}); } , queue: 'front'}); }
						});

};

//switch the marker icon
var getIcon = function(type){
	var icon = new GIcon();
	switch(type){
		case "o":
			icon.image = "/images/organisation.png";
			break;
		case "v":
				icon.image = "/images/venue.png";
				break;
		case "multi":
			icon.image = "/images/multi.png";
			break;
		case "i":
		default:
			icon.image = "/images/individual.png";
			break;
	}

	icon.iconSize = new GSize(12, 22);
	icon.iconAnchor = new GPoint(6,22); //point at which it touches the map from top left corner of image
	icon.infoWindowAnchor = new GPoint(6,0); //point at which it the info window pointer touches the icon from top left corner of image
 	
 	return icon;
};

var setMarkers = function(response){
	map.clearOverlays();
	var close_info_window = true;

	if(response.responseJSON.length >0){
		$('loading-feedback').innerHTML = "Setting Icons";
		var profiles = response.responseJSON; 	//all profiles
		var profile_buffer = new Array;			//a place to keep profiles with a similar location
		var current_profile = null;
		for(var i=0;i<profiles.length;i++){
			profile = profiles[i];
			if(current_profile && (profile.address.longitude != current_profile.lng || profile.address.latitude != current_profile.lat)){
				setMarker(profile_buffer);
				profile_buffer = new Array();
			}
			profile_buffer.push(profile);
			current_profile = profile;

			if(currentInfoWindow && $A(currentInfoWindow.permalinks).indexOf(profile.permalink)){
				close_info_window = false;
			}
		}
		setMarker(profile_buffer);
	}
	
	if (currentInfoWindow && close_info_window){
		closeAjaxInfoWindow(currentInfoWindow);
	}
	
	new Effect.Opacity('spinny', { delay: 0.5, fps: 18, duration: 0.3, from: 0.6, to: 0, afterFinish: function(){$('spinny').setStyle({left:'-800px'});} , queue: 'front'});
};

var setMarker = function(profiles){
	var type = '';
	var permalinks = new Array;
	var names = new Array();
	profiles.each(function(p){ names.push(p.name); permalinks.push(p.permalink); });
	if(profiles.length >1){
		//multi
		type = 'multi';
	}else{
		//single
		type = profiles[0].type;
	}
	var point = new GLatLng(profiles[0].address.latitude, profiles[0].address.longitude);
	var marker = new GMarker(point, {draggable:false, icon: getIcon(type), title: names.join(', ')});
	marker.permalinks = permalinks;

	window['marker_' + permalinks.join('_').replace(/\-/ig, '_')] = marker;
	map.addOverlay(marker);
	GEvent.addListener(marker, 'click', openAjaxInfoWindow);
};

var openAjaxInfoWindow = function(){
	var prof_ref = window['marker_' + this.permalinks.join('_').replace(/\-/ig, '_')];
	
	
	if(currentInfoWindow == null || prof_ref.permalinks.join() != currentInfoWindow.permalinks.join()){
		//open a window
		if(currentInfoWindow != null)
			closeAjaxInfoWindow(currentInfoWindow);
	
		var query = 'permalinks=' + this.permalinks.join(',');

		if(prof_ref.transport)
			prof_ref.transport.transport.abort();
		
			prof_ref.transport = new Ajax.Request('/directory/map_info.json', {
											method: 'get',
											parameters: query,
											asynchronous:true,
											onSuccess: setInfoWindowContent});
	}else{
		closeAjaxInfoWindow(currentInfoWindow);
	}
	
	return true;
};

var closeAjaxInfoWindow = function(ref){
	var prof_ref = window['marker_' + ref.permalinks.join('_').replace(/\-/ig, '_')];
	map.removeTLabel(ref);
	prof_ref.infoWindow = null;
	currentInfoWindow = null;
};

var setInfoWindowContent = function(response){

	var profiles = response.responseJSON;

	var html = '<ul>';
	var permalinks = new Array;
	
	profiles.each(function(profile){
		permalinks.push(profile.permalink);
	
		html += "<li"+(profile == profiles.last()?' class="last"':'')+"><h3><a href=\"/directory/"+profile.permalink+"\">";
		html += profile.name;
		html += "</a></h3>";

		if(profile.categories && profile.categories.length >0){
			html += "<p>Categories ";
			profile.categories.each(function(cat){ html += cat + ', '; });
			html = html.substring(0, html.length-2);
			html += "</p>";
		}

		html += "</li>";
	});

	html += '</ul><a href="#" class="map-profile-close" onclick="closeAjaxInfoWindow(currentInfoWindow);return false;">X</a>';
	var prof_ref = window['marker_' + permalinks.join('_').replace(/\-/ig, '_')];
	var infoWindow = new TLabel();
	infoWindow.id = 'profile-information-window';
	infoWindow.anchorLatLng = prof_ref.getLatLng();
	
	infoWindow.markerOffset=new GSize(-5,15);
	infoWindow.anchorPoint = 'bottomCenter';
	infoWindow.content = html;
	infoWindow.permalinks = permalinks;
	
	currentInfoWindow = infoWindow;
  prof_ref.infoWindow = infoWindow;
  
	map.addTLabel(infoWindow);

	//calc center point of info window
	offset = ($(infoWindow.id).getHeight()/2);
	p1 = map.fromDivPixelToLatLng(new GPoint(0,0));
	p2 = map.fromDivPixelToLatLng(new GPoint(0,offset));
	p3 = prof_ref.getLatLng();
	lat_offset = (p1.lat() - p2.lat()) + p3.lat();
	//focus map around marker 
	map.panTo(new GLatLng(lat_offset, p3.lng()));
	
	return true;
};



var toggleMapLegend = function(collection, action){
	switch(action){
		case 'all':
			collection.each(function(box){ box.checked = true; });
		break;
		case 'none':
			collection.each(function(box){ box.checked = false; });
		break;
		case 'invert':
			collection.each(function(box){ box.checked = !box.checked; });
		break;
	}
	
	updateMap();
	
	return false;
};