function byId(eltId){
    return document.getElementById(eltId);
}

var Nic = {

	Map: {

		// The ID if the element containing the map
		ContentElementID: "",

		// The icon to be used for innovations.
		InnovationIcon: null,

		// The path to the icon to be used for innovations.
		InnovationIconPath: "",

		// The list of innovations to show.
		Innovations: new Array(),

		// The list of markers for the innovations.
		InnovationsMarkers: new Array(),

		// The map
		MapInstance: null,

		// A manager for the markers.
		MapMarkerManager: null,

		// The icon to be used for medical centres
		MedicalCentreIcon: "",

		// The path to the icon to be used for medical centres
		MedicalCentreIconPath: "",

		// The list of medical centres that adopted the item
		MedicalCentresAdopted: new Array(),

		// The list of markers for the medical centres that adopted the item
		MedicalCentresAdoptedMarkers: new Array(),

		// Wheter the medical centres that adopted the item are shown on the map.
		MedicalCentresAdoptedShown: true,

		// The list of all medical centres
		MedicalCentresAll: new Array(),

		// Wheter the medical centres are shown.
		MedicalCentresAllShown: false,

		// The list of markers for all medical centres
		MedicalCentresAllMarkers: new Array(),

		// The id of the element showing the help message.
		MessageHelpElementID: "",

		// The id of the element showing the "working..." message.
		MessageWorkingElementID: "",

		// The id of the element shown above the map.
		OverlayElementID: "",

		// The list of visible markers
		VisibleMarkers: new Array(),

		// Changes an element's text between "show" and "hide"
		ChangeLinkElementText: function(elt, shown) {

			if (elt != null) {

				if (elt.tagName.toLowerCase() == "a") {
					elt = elt.firstChild;
				}

				if (shown) {
					elt.innerHTML = "Hide";
					elt.className = "TMG_controls-hide";
				} else {
					elt.innerHTML = "Show";
					elt.className = "TMG_controls-show";
				}

			}

		},


		// Changes the visibility of a set of markers
		ChangeMarkersVisibility: function (markersList, show) {

			for (var i = 0; i < markersList.length; i++) {
				if (show) {
					markersList[i].show();
				} else {
					markersList[i].hide();
				}
			}

			if (show) {
				Nic.Map.SetAutoZoom(markersList);
			}
		},


		GetInnovationInfoHtml: function(innovation) {
			return "<div class=\"NIC_ShowcaseMapInfo\"><h1><a href=\"" + innovation.Url + "\">" + innovation.Title + "</a></h1>" +
				"<div class=\"contents\"><p style=\"max-width: 200px;\">" + (innovation.Image ? "<img src=\"" + innovation.Image + "\" style=\"width: 56px; height: 56px; float: left; margin-right: 5px; margin-bottom: 5px;\" alt=\"" + innovation.Title + "\" />" : "") +
				innovation.Text.replace(/\n/g, "<br />") + "<br /><a href=\"" + innovation.Url + "\">Read more</a></p></div></div>";
		},


		GetMedicalCentreInfoHtml: function(medCentre) {

			var centreStory = medCentre.Story;
			var centreLink = medCentre.Url;

			if (centreLink != "") {
				centreLink = "<p><a href=\"" + centreLink + "\" target=\"_blank\">" + centreLink.replace(/http[s]?[^\w]+/gi, "") + "</a></p>";
			}

			return "<div class=\"NIC_ShowcaseMapInfo\"><h1>" + medCentre.Title + "</h1>" +
				"<div class=\"contents\"><table><tr><td><label>Address:</label></td><td>" + medCentre.Postcode + "</td></tr>" +
				"<tr><td><label>Adoption date:</label></td><td>" + medCentre.Date + "</td></tr></table>" +
				(centreStory != "" ? "<p>" + centreStory.replace(/\n/g, "<br />") + "</p>" : "") +
				centreLink + "</div></div>";

		},


		// Initialises the map
		Init: function() {

			var contentElt = byId(Nic.Map.ContentElementID);

			if ((contentElt != null) && GBrowserIsCompatible()) {

				Nic.Map.MapInstance = new GMap2(contentElt);
				var geocoder = new GClientGeocoder();
				var customUI = null;

				byId(Nic.Map.MessageHelpElementID).style.display = "none";

				geocoder.getLatLng("UK",
					function(point) {
						if (point) {
							Nic.Map.MapInstance.setCenter(point, (byId(Nic.Map.ContentElementID).offsetWidth <= 300 ? 4 : 5));
						}
					}
				);

				Nic.Map.MapInstance.setUIToDefault();
				Nic.Map.MapInstance.setMapType(G_PHYSICAL_MAP);
				Nic.Map.MapInstance.setUIToDefault();

				// Prepare the icons
				Nic.Map.InnovationIcon = new GIcon(G_DEFAULT_ICON, Nic.Map.InnovationIconPath);
				Nic.Map.MedicalCentreIcon = new GIcon(G_DEFAULT_ICON, Nic.Map.MedicalCentreIconPath);

				Nic.Map.InnovationIcon.iconSize = new GSize(26, 35);
				Nic.Map.MedicalCentreIcon.iconSize = new GSize(26, 36);

				// Load the adopted medical centres
				for (var i = 0; i < Nic.Map.MedicalCentresAdopted.length; i++) {
					eval("new GClientGeocoder().getLatLng(\"" + Nic.Map.MedicalCentresAdopted[i].Postcode + ",UK\", function(point) {" +
						" if (point) {" +
						" var marker = new GMarker(point, Nic.Map.MedicalCentreIcon);" +
						" Nic.Map.MedicalCentresAdoptedMarkers.push(marker);" +
						" Nic.Map.VisibleMarkers.push(marker);" +
						" GEvent.addListener(marker, 'click', function() { marker.openInfoWindowHtml(unescape(\"" + escape(Nic.Map.GetMedicalCentreInfoHtml(Nic.Map.MedicalCentresAdopted[i])) + "\")); });" +
						" Nic.Map.MapInstance.addOverlay(marker); Nic.Map.SetAutoZoom(); } } );");
				}

				Nic.Debug("There are " + Nic.Map.Innovations.length + " innovations");

				// Load the innovations
				for (var i = 0; i < Nic.Map.Innovations.length; i++) {
					eval("new GClientGeocoder().getLatLng(\"" + Nic.Map.Innovations[i].Postcode + ",UK\", function(point) {" +
						" if (point) {" +
						" var marker = new GMarker(point, Nic.Map.InnovationIcon);" +
						" Nic.Map.InnovationsMarkers.push(marker);" +
						" Nic.Map.VisibleMarkers.push(marker);" +
						" GEvent.addListener(marker, 'click', function() { marker.openInfoWindowHtml(unescape(\"" + escape(Nic.Map.GetInnovationInfoHtml(Nic.Map.Innovations[i])) + "\")); });" +
						" Nic.Map.MapInstance.addOverlay(marker); Nic.Map.SetAutoZoom(); } } );");
				}

				// Load all the medical centres
				for (var i = 0; i < Nic.Map.MedicalCentresAll.length; i++) {
					eval("new GClientGeocoder().getLatLng(\"" + Nic.Map.MedicalCentresAll[i].Postcode + ",UK\", function(point) {" +
						" if (point) {" +
						" var marker = new GMarker(point, Nic.Map.MedicalCentreIcon);" +
						" Nic.Map.MedicalCentresAllMarkers.push(marker);" +
						" GEvent.addListener(marker, 'click', function() { marker.openInfoWindowHtml(unescape(\"" + escape(Nic.Map.GetMedicalCentreInfoHtml(Nic.Map.MedicalCentresAll[i])) + "\")); });" +
						" Nic.Map.MapInstance.addOverlay(marker); marker.hide(); } } );");
				}


				GEvent.addListener(Nic.Map.MapInstance, 'load', function() {
						byId(Nic.Map.OverlayElementID).style.display = "none";
					});

			}

		},


		// Sets the zoom automatically, based on a list of markers.
		SetAutoZoom: function(markersList) {

			if (!markersList) {
				var markersList = Nic.Map.VisibleMarkers;
			}

			Nic.Debug("markers list:" + markersList.length);

			if (markersList.length > 0) {

				var bounds = new GLatLngBounds();

				// Reset the map
				Nic.Map.MapInstance.setCenter(new GLatLng(0, 0), (byId(Nic.Map.ContentElementID).offsetWidth <= 300 ? 4 : 5));

				for (var i = 0; i < markersList.length; i++) {
					bounds.extend(markersList[i].getLatLng());
				}

				Nic.Map.MapInstance.setZoom(Nic.Map.MapInstance.getBoundsZoomLevel(bounds) - 1);
				Nic.Map.MapInstance.setCenter(bounds.getCenter());

			} else {
				var geocoder = new GClientGeocoder();
				geocoder.getLatLng("UK",
					function(point) {
						if (point) {
							Nic.Map.MapInstance.setCenter(point, (byId(Nic.Map.ContentElementID).offsetWidth <= 300 ? 4 : 5));
						}
					}
				);
			}

		},


		// Shows or hides the medical centres that adopted the item.
		ToggleMedicalCentresAdoptedVisibility: function(evt) {
			Nic.Map.ChangeMarkersVisibility(Nic.Map.MedicalCentresAdoptedMarkers, !Nic.Map.MedicalCentresAdoptedShown);
			Nic.Map.MedicalCentresAdoptedShown = !Nic.Map.MedicalCentresAdoptedShown;
			Nic.Map.ChangeLinkElementText((evt.srcElement ? evt.srcElement : evt.target), Nic.Map.MedicalCentresAdoptedShown);
		},


		// Shows or hides all the medical centres (leaving out the ones that adopted the item).
		ToggleMedicalCentresAllVisibility: function(evt) {
			Nic.Map.ChangeMarkersVisibility(Nic.Map.MedicalCentresAllMarkers, !Nic.Map.MedicalCentresAllShown);
			Nic.Map.MedicalCentresAllShown = !Nic.Map.MedicalCentresAllShown;
			Nic.Map.ChangeLinkElementText((evt.srcElement ? evt.srcElement : evt.target), Nic.Map.MedicalCentresAllShown);
		}

	},


	Debug: function(message) {

		var debugElt = byId("debug");

		if (debugElt != null) {
			debugElt.innerHTML += message + "<br />";
		}

	},


    //Sets Favorite to a specific browser
	CreateBookmark: function(_title, _url) {
		title = _title; 
        url = _url;
  
	    if (window.sidebar) { // Mozilla Firefox Bookmark
		    window.sidebar.addPanel(title, url,"");
	    } else if( window.external ) { // IE Favorite
		    window.external.AddFavorite( url, title); 
		} else if(window.opera && window.print) { // Opera Hotlist
		    return true; 
		}
	}
};


// The display.
Nic.Map.Display = {

	ListElementID: "",
	MapElementID: "",

	SwitchTo: function(displayMode, evt) {

		var lstElt = byId(Nic.Map.Display.ListElementID);
		var mapElt = byId(Nic.Map.Display.MapElementID);
		var srcElt = (evt.srcElement ? evt.srcElement : evt.target);

		displayMode = displayMode.toLowerCase();

		if (displayMode == "map") {
			lstElt.style.display = "none";
			mapElt.style.display = "";
		} else if (displayMode == "list") {
			lstElt.style.display = "";
			mapElt.style.display = "none";
		}

		if (srcElt != null) {
			var lis = srcElt.parentNode.parentNode.getElementsByTagName("li");
			for (var i = 0; i < lis.length; i++) {
				lis[i].className = "";
			}
			srcElt.parentNode.className = "TMG_active";
		}

	}

}
