// Initialise the map variable for IE.
var map;

var Cookie = {
  set: function(name, value, daysToExpire) {
    var expire = '';
    if (daysToExpire != undefined) {
      var d = new Date();
      d.setTime(d.getTime() + (86400000 * parseFloat(daysToExpire)));
      expire = '; expires=' + d.toGMTString();
    }
    return (document.cookie = escape(name) + '=' + escape(value || '') + expire);
  },
  get: function(name) {
    var cookie = document.cookie.match(new RegExp('(^|;)\\s*' + escape(name) + '=([^;\\s]*)'));
    return (cookie ? unescape(cookie[2]) : null);
  },
  erase: function(name) {
    var cookie = Cookie.get(name) || true;
    Cookie.set(name, '', -1);
    return cookie;
  },
  accept: function() {
    if (typeof navigator.cookieEnabled == 'boolean') {
      return navigator.cookieEnabled;
    }
    Cookie.set('_test', '1');
	return (Cookie.erase('_test') === '1');
	}
};

/**
* Loads the live data from the server.
*/
function loadData() {
	$('found').toggle();
	$('spinner').toggle();

	// Remember the map coordinates.
	if(!$('rememberPostcode').checked)
	{
		var mapCenter = map.getCenter();
		Cookie.set('lat', mapCenter.lat(), 600);
		Cookie.set('lng', mapCenter.lng(), 600);
	}

    // Get live heatmap.
    var live = new Ajax.Request("/incidents/live/" + getMapBounds(), {
        requestheaders: {
            Accept: 'application/json'
        },
        onSuccess: function(transport) {
			filters = new Array();
			filters['severity'] = new Array();
			
			jsonTraffic = transport.responseText.evalJSON();

			$('found').innerHTML = "Found " + jsonTraffic.length + " incidents";

			showTagCloud(jsonTraffic);
			addPins(jsonTraffic, filters);

			$('found').toggle();
			$('spinner').toggle();
		}
	});
}

/**
 * Returns a string that can be used as part of a URL.
 * @returns string
 */
function getMapBounds()
 {
    var sw = map.getBounds().getSouthWest();
    var ne = map.getBounds().getNorthEast();

	return ne.lat() + "/" + ne.lng() + "/" + sw.lat() + "/" + sw.lng();
}

/**
* onLoad event handler for the page.
*/
function load() {
	var mapEl = $('map');
    map = new GMap2(mapEl);
    GEvent.addListener(map, "load", loadData);

    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());

	var lat = Cookie.get('lat');
	var lng = Cookie.get('lng');

	if(lat && lng)
	{
		map.setCenter(new GLatLng(lat, lng), 10);
	} else {
		map.setCenter(new GLatLng(53.379233, -1.456032), 10);
	}

    map.setMapType(G_NORMAL_MAP);

    GEvent.addListener(map, "moveend", loadData);
	$('getIncidents').observe('click', getPostcode);
	$('rememberPostcode').observe('change', savePosition);
}

function savePosition()
{
	var location = map.getCenter();
	
	Cookie.set('lat', location.lat());
	Cookie.set('lng', location.lng());
}

/**
 * Look up the postcode and recenter the map on that position
 * @param {string} Postcode
 */
function getPostcode(postcode) {
    var live = new Ajax.Request("/postcode/get/" + escape($('postCode').value), {
        requestheaders: {
            Accept: 'application/json'
        },
        onSuccess: function(transport) {
            var json = transport.responseText.evalJSON();
            if (json != false)
            {
                map.setCenter(new GLatLng(json['lat'], json['lng']), 10);
				if($('rememberPostcode').checked)
				{
					Cookie.set('lat', json['lat']);
					Cookie.set('lng', json['lng']);
				}
            } else {
                alert(postcode + " is not a valid postcode");
            }
        }
    });
}

/**
 *
 */
function showTagCloud(jsonTraffic)
{
	var cloud = new Array();
	cloud['severity'] = new Array();
	// Show the different levels of severity.
	jsonTraffic.each(function(i) {
		if(cloud['severity'][i.severity] == null)
		{
			cloud['severity'][i.severity] = 1;
		} else {
			cloud['severity'][i.severity]++;
		}
	});
	
	// Sort the severity tags into order.
	cloud['severity'].sort(function(a, b) {
		return a[0] - b[0];
	});
	
	var elSeverity = document.createElement('ol');
	elSeverity.setAttribute('id', 'cloudSeverity');
	
	if(cloud['severity']['very slight'])
	{
		var elTag = document.createElement('li');
		elTag.setAttribute('class', 'very_slight');
		elSeverity.appendChild(elTag);
		var tagLink = document.createElement('a');
		tagLink.setAttribute('href', '#');
		tagLink.innerHTML = 'Very Slight (' + cloud['severity']['very slight'] + ')';
		elTag.appendChild(tagLink);
		$(tagLink).observe('click', toggleFilter);
	}

	if(cloud['severity']['slight'])
	{
		var elTag = document.createElement('li');
		elTag.setAttribute('class', 'slight');
		elSeverity.appendChild(elTag);
		var tagLink = document.createElement('a');
		tagLink.setAttribute('href', '#');
		tagLink.innerHTML = 'Slight (' + cloud['severity']['slight'] + ')';
		elTag.appendChild(tagLink);
		$(tagLink).observe('click', toggleFilter);
	}
	
	if(cloud['severity']['medium'])
	{
		var elTag = document.createElement('li');
		elTag.setAttribute('class', 'medium');
		elSeverity.appendChild(elTag);
		var tagLink = document.createElement('a');
		tagLink.setAttribute('href', '#');
		tagLink.innerHTML = 'Medium (' + cloud['severity']['medium'] + ')';
		elTag.appendChild(tagLink);
		$(tagLink).observe('click', toggleFilter);
	}
	
	if(cloud['severity']['severe'])
	{
		var elTag = document.createElement('li');
		elTag.setAttribute('class', 'severe');
		elSeverity.appendChild(elTag);
		var tagLink = document.createElement('a');
		tagLink.setAttribute('href', '#');
		tagLink.innerHTML = 'Severe (' + cloud['severity']['severe'] + ')';
		elTag.appendChild(tagLink);
		$(tagLink).observe('click', toggleFilter);
	}

	if(cloud['severity']['very severe'])
	{
		var elTag = document.createElement('li');
		elTag.setAttribute('class', 'very_severe');
		elSeverity.appendChild(elTag);
		var tagLink = document.createElement('a');
		tagLink.setAttribute('href', '#');
		tagLink.innerHTML = 'Very Severe (' + cloud['severity']['very severe'] + ')';
		elTag.appendChild(tagLink);
		$(tagLink).observe('click', toggleFilter);
	}

	var s = $('cloudSeverity');
	if(s != null)
	{
		s.parentNode.removeChild(s);
	}
	$('map').parentNode.appendChild(elSeverity);
}

function toggleFilter(e) {
	if(e.target.parentNode.hasClassName('very_slight')) {
		filters['severity']['very slight'] = filters['severity']['very slight'] != 0 ? 0 : 1;
		$$('li.very_slight').each ( function(e) { var op = 0.5 + filters['severity']['very slight']; e.setOpacity(op) });
	}
	if(e.target.parentNode.hasClassName('slight')) {
		filters['severity']['slight'] = filters['severity']['slight'] != 0 ? 0 : 1;
		$$('li.slight').each ( function(e) { var op = 0.5 + filters['severity']['slight']; e.setOpacity(op) });
	}
	if(e.target.parentNode.hasClassName('medium')) {
		filters['severity']['medium'] = filters['severity']['medium'] != 0 ? 0 : 1;
		$$('li.medium').each ( function(e) { var op = 0.5 + filters['severity']['medium']; e.setOpacity(op) });
	}
	if(e.target.parentNode.hasClassName('severe')) {
		filters['severity']['severe'] = filters['severity']['severe'] != 0 ? 0 : 1;
		$$('li.severe').each ( function(e) { var op = 0.5 + filters['severity']['severe']; e.setOpacity(op) ;	});
	}
	if(e.target.parentNode.hasClassName('very_severe')) {
		filters['severity']['very severe'] = filters['severity']['very severe'] != 0 ? 0 : 1;
		$$('li.very_severe').each ( function(e) { var op = 0.5 + filters['severity']['very severe']; e.setOpacity(op) ;	});
	}
	
	addPins(jsonTraffic, filters);
}

/**
 * Adds pins to the map.
 */
function addPins(points, filters)
 {
	map.clearOverlays();
	
    var zoom = map.getZoom();

    var MarkerManager = new GMarkerManager(map);

    var count = 0;

    var lat;
    var lng;
    var severity;

    var pins = Array();

    // Create an icon for each of the different severitys
    var baseIcon = new GIcon();
    baseIcon.shadow = "/images/flag_shadow.png";
    baseIcon.iconSize = new GSize(16, 16);
    baseIcon.shadowSize = new GSize(27, 15);
    baseIcon.iconAnchor = new GPoint(12, 14);
    baseIcon.shadowAnchor = new GPoint(9, 14);
    baseIcon.infoWindowAnchor = new GPoint(12, 14);
    baseIcon.infoShadowAnchor = new GPoint(12, 14);

    points.each(function(i)
    {
		if(filters['severity'][i['severity']] != 0)
		{
	        var icon = new GIcon(baseIcon);
	        icon.image = i['icon'];

			i['point'].each(function(point)
			{
		        var marker = new GMarker(new GLatLng(point.lat, point.lng), icon);
	
		        GEvent.addListener(marker, "click", 
		        function() {
		            // Suspend the load data event on map movement.
		            GEvent.clearListeners(map, "moveend");
					map.savePosition();

		            // Open a new info window, and enable the scrolling data loader when the
		            // window is closed.
		            var infoNode = document.createElement('div');
		            infoNode.setAttribute('style', 'color: black');
		            infoNode.appendChild(document.createTextNode(i['description']));
		            var startNode = document.createElement('div');
		            var startStrong = document.createElement('strong');
		            startStrong.appendChild(document.createTextNode('Start: '));
		            startNode.appendChild(startStrong);
		            startNode.appendChild(document.createTextNode(i['start_time']));
		            infoNode.appendChild(startNode);
		            var endNode = document.createElement('div');
		            var endStrong = document.createElement('strong');
		            endStrong.appendChild(document.createTextNode('Est. End: '));
		            endNode.appendChild(endStrong);
		            endNode.appendChild(document.createTextNode(i['stop_time']));
		            infoNode.appendChild(endNode);

					// Show a link between the two points of this incident.
					var directions = new GDirections(map);
					if(i['point'].length > 1)
					{
						directions.loadFromWaypoints([[i['point'][0].lat, i['point'][0].lng], [i['point'][1].lat, i['point'][1].lng]]);
					}
					
		            map.openInfoWindowHtml(
		            marker.getPoint(), 
		            infoNode, 
		            {
		                maxWidth: 250,
		                onCloseFn: function() {
							directions.clear();
							map.returnToSavedPosition();
		                    GEvent.addListener(map, "moveend", loadData);
		                }
		            });
		        });
	        	map.addOverlay(marker);
			});
		}
    });
}

var jsonTraffic;
var filters = new Array();
filters['severity'] = new Array();

Event.observe(window, 'load', load);