// <![CDATA[

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//	Panoramic Earth 3 - Javascript code
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//	23.06.2010	3.2.0	DJV		currRef is now reset to -1 when the marker goes off screen (and gets deleted).
//	24.06.2010	3.2.1	DJV		Fixed ETour bug by adding altRef.
//	26.07.2010	3.2.2	DJV		Mods for world map smaller pins appearing inthe wrong place.
//	25.08.2010	3.2.3	DJV		Added social sites.
//	08.09.2010	3.3.0	DJV		Converted old newway code into killAjax.
//	21.09.2010	3.3.1	DJV		More to embed code popup.
//	22.09.2010	3.3.2	DJV		Added wmode to KrPano start up to allow the popup to overlay the Flash code.
//	13.10.2010	3.3.3	DJV		Embed popup radio buttons now working ok.
//	15.10.2010	3.3.4	DJV		Removed the reload buttons as the code now reloads itself. Added Select button to
//								highlight the embedded code. Finished paid tour text. Fixed bug where the Play onclick
//								was still responding even after the pano had been displayed.
//	19.10.2010	3.3.5	DJV		Mods for larger image embed code.
//	29.11.2010	3.3.6	DJV		Added personal tour mods.
//	30.11.2010	3.3.7	DJV		Fixed bugs in icon replacement when clicked and mkLevel when not initialised.
//	21.12.2010	3.3.8	DJV		Added loadPMap function as alternative to redoEmbed for P/Maps only.
//	24.03.2011	3.3.9	DJV		Added check for a map that isn't showing any markers and dropping the mkLevel down to
//								zero to force it to redisplay markers.
//	02.05.2011	3.4.0	DJV		Alt display mods (Map Pages).
//	09.05.2011	3.4.1	DJV		More to Map Pages code.
//	19.05.2011	3.4.2	DJV		Fixed problem on Map Pages when destination didn't have an image. Also fixed
//								photographer div not having 'alt' suffix on Map Pages.
//	24.04.2011	3.4.3	DJV		More to mapPages - made box draggable + descriptions now update properly.
//	14.07.2011	3.4.4	DJV		Commercial link now goes somewhere!
//
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

function krpano ()
{
	return $id ("krpanoSWFObject");
}

PE3 = function ()
{
	var	sysCheck,
		docroot,
		iconDir,
		thisHost,
		thisData,

		gMapVer	= "2.225",
		gmap,
		map,
		mapInfo,
		mapCtrlList,
		mapTypes,
		mapPos = -1,
		stdIcon,
		smallIcon,
		tinyIcon,
		mX = 0,
		mY = 0,
		currRef = -1,
		mkLevel = -1,		// -1 = not defined, 0 = locs, 1 = dests/map pins, 2 = region, 3 = country, 4 = continent
		isTour = false,

		embedRef = -1,		// The ID of any previously created
		embedMode = -1,		// The mode of embedding: 0 = free tour, 1 = paid tour, 2 = hotel paid tour,
							// 3 = image only, 4 = personal map tour

		ajax,				// Ajax reference
		destAjax,			// For destination updates
		linkAjax,			// For tour links update
		embedAjax,			// When generating the embedded tour code

		mapPages = false,	// True when we're displaying map pages

		lastZoom = -1,

		tourCost = -1,

		mkList = [],		// List of currently available markers (array of [id, mode, original data])

		lastData = "",		// For heading off any multiple sends of the same data
		lastDestData = "",
		lastLinksData = "",
		lastEmbedData = "",

		enablePMap = false,

		runPath = "",
		rpTm = null,
		popup = null,

		krPano = null,
		fulldescBox,
		xyPos, xyOffset,	// CS positioning for dragging

		killAjax = false;


	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	var dbTxt = "";

	function debug (txt)
	{
		dbTxt += " " + txt;
		$id ("debug").innerHTML = dbTxt;
//		alert (txt);
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// Name popup functions
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	function NamePopup (txt)
	{
		this.txt = txt.replace ("&amp;", "&");
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// Toggle button - button text, x/y position and width, function to call when clicked, initial state (0=grey)
	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	function ToggleButton (txt, x, y, w, func, state, ind)
	{
		this.txt = txt;
		this.x = x;
		this.y = y;
		this.w = w;
		this.func = func;
		this.state = state;
		this.ind = ind;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	var _private =
	{
		////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// Get the appropriate marker level for the specified zoom level
		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		getMkLevel : function (z)
		{
			if (z < 2) return 4;	// Continent
			if (z < 5) return 3;	// Country
			if (z < 9) return 2;	// Region
			if (z < 12) return 1;	// Main Dests
			return 0;				// Locations
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		getIcon : function (pt, sz)
		{
			if (sz == undefined) sz = 0;

			var pins =
			[
				"large-dot-green", 			//  0 = General
				"symbol-underground", 		//  1 = Station (Underground/Tube)
				"large-dot-blue",			//  2 = Attraction
				"symbol-snow",				//  3 = Ski resort
				"symbol-train",				//  4 = Station (Main line)
				"symbol-restaurant",		//  5 = Restaurant/Cafe
				"symbol-airport",			//  6 = Airport
				"symbol-church",			//  7 = Church
				"symbol-forest",			//  8 = Gardens/Parkland
				"symbol-info",				//  9 = Information
				"symbol-museum",			// 10 = Museum
				"symbol-hotel",				// 11 = Hotel
			];

			var pin = "";

			if (pt < 1)
			{
				pin = (sz == 0 ? "large-dot-red" : "plain-green");
			}
			else
			if (pt > pins.length - 1)
			{
				pin = "plain-cyan";
			}
			else
			{
				pin = pins [pt];
			}

			switch (parseInt (sz))
			{
				case 0 : // Normal
					break;

				case 1 : // Small
					pin += "-small";
					break;

				case 2 : // Tiny
					pin += "-tiny";
					break;
			}

			return pin;
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		initNamePopups : function  ()
		{
			NamePopup.prototype = new google.maps.Control ();

			NamePopup.prototype.initialize = function (map)
			{
				var container = document.createElement ("div");

				this.setButtonStyle_ (container);

				var e = document.createElement ("div");
				e.innerHTML = this.txt;
				container.appendChild (document.createTextNode (e.innerHTML));
				map.getContainer ().appendChild (container);
				return container;
			}

			NamePopup.prototype.getDefaultPosition = function ()
			{
				return new google.maps.ControlPosition (G_ANCHOR_TOP_LEFT, new google.maps.Size (mX + 10, mY - 10));
			}

			NamePopup.prototype.setButtonStyle_ = function (button)
			{
				button.style.color = "black";
				button.style.backgroundColor = "#ffe";
				button.style.font = "small Arial";
				button.style.fontSize = "7pt";
				button.style.border = "1px solid black";
				button.style.padding = "1px";
				button.style.marginBottom = "2px";
				button.style.textAlign = "center";
				button.style.cursor = "pointer";
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		initToggleButtons : function  ()
		{
			ToggleButton.prototype = new GControl ();

			ToggleButton.prototype.initialize = function (map)
			{
				var container = document.createElement ("div");

				var btn = document.createElement ("div");
				btn.id = "tglbtn" + this.ind;
				this.setButtonStyle_ (btn);
				container.appendChild (btn);
				btn.appendChild (document.createTextNode (this.txt));

				GEvent.addDomListener (btn, "click", function ()
				{
					_private.toggleChangeState (btn.id);
				});

				GEvent.addDomListener (btn, "mouseover", function ()
				{
					_private.toggleMouse (btn.id, 1);
				});

				GEvent.addDomListener (btn, "mouseout", function ()
				{
					_private.toggleMouse (btn.id, 0);
				});

				map.getContainer ().appendChild (container);
				return container;
			}

			ToggleButton.prototype.getDefaultPosition = function ()
			{
				var x = this.x;
				var anchor = G_ANCHOR_TOP_LEFT;

				if (x < 0)
				{
					x = Math.abs (x);
					anchor = G_ANCHOR_TOP_RIGHT;
				}

				return new GControlPosition (anchor, new GSize (x, this.y));
			}

			ToggleButton.prototype.setButtonStyle_ = function (button)
			{
				button.style.font = "small Arial";
				button.style.border = "1px solid black";
				button.style.padding = "0";
				button.style.marginBottom = "3px";
				button.style.textAlign = "center";
				button.style.width = this.w + "px";
				button.style.height = "17px";
				button.style.cursor = "pointer";

				if (this.state == 1)
				{
					button.style.color = "black";
					button.style.backgroundColor = "white";
					button.style.fontWeight = "bold";
				}
				else
				{
					button.style.color = "#999";
					button.style.backgroundColor = "#ddd";
					button.style.fontWeight = "normal";
				}
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		mouseMove : function (eo)
		{
			if (mapPos < 0) mapPos = DLibUtilities.findPos (gmap);

			mX = null;
			mY = null;

			if (eo != null)
			{
				mX = eo.clientX;
				mY = eo.clientY;
			}
			else
			{
				mX = event.clientX;
				mY = event.clientY;
			}

			mX -= mapPos [0];
			mY -= mapPos [1];
			var os = DLibUtilities.scrollOffset ();

			mX += os[0];
			mY += os[1];
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		mapCtrls : function (ch)
		{
			return (mapCtrlList.indexOf (ch) > -1);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		initMap : function (ctrls)
		{
			mapCtrlList = ctrls;

			map = new google.maps.Map2 (gmap);
			mapPos = DLibUtilities.findPos (gmap);
			mX = mY = 0;
			mapTypes = [G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP, G_SATELLITE_3D_MAP];

			// Set up the main icon sizes (only used for non-Google markers)

			// Normal size

			stdIcon = new google.maps.Icon ();
			stdIcon.iconSize = new google.maps.Size (20, 34);
			stdIcon.shadowSize = new google.maps.Size (37, 34);
			stdIcon.iconAnchor = new google.maps.Point (9, 34);
			stdIcon.infoWindowAnchor = new google.maps.Point (9, 2);
			stdIcon.infoShadowAnchor = new google.maps.Point (18, 25);

			// Small size

			smallIcon = new google.maps.Icon ();
			smallIcon.iconSize = new google.maps.Size (14, 24);
			smallIcon.shadowSize = new google.maps.Size (26, 24);
			smallIcon.iconAnchor = new google.maps.Point (7, 24);
			smallIcon.infoWindowAnchor = new google.maps.Point (6, 2);
			smallIcon.infoShadowAnchor = new google.maps.Point (18, 25);

			// Tiny size

			tinyIcon = new google.maps.Icon ();
			tinyIcon.iconSize = new google.maps.Size (10, 17);
			tinyIcon.shadowSize = new google.maps.Size (18, 17);
			tinyIcon.iconAnchor = new google.maps.Point (4, 17);
			tinyIcon.infoWindowAnchor = new google.maps.Point (4, 1);
			tinyIcon.infoShadowAnchor = new google.maps.Point (18, 25);

			if ($id ("mapinfo")) mapInfo = $id (mapInfoID);

			_private.initNamePopups ();
			_private.initToggleButtons ();

			gmap.onmousemove = _private.mouseMove;

			map.addMapType (G_PHYSICAL_MAP);

//			if (_private.mapUses ("e"))
//			{
//				map.addMapType (G_SATELLITE_3D_MAP);
//			}

			if (_private.mapCtrls ("Z1")) map.addControl (new google.maps.SmallZoomControl ());
			if (_private.mapCtrls ("Z2")) map.addControl (new google.maps.SmallZoomControl3D ());
			if (_private.mapCtrls ("Z3")) map.addControl (new google.maps.SmallMapControl ());
			if (_private.mapCtrls ("Z4")) map.addControl (new google.maps.SmallMapControl3D ());
			if (_private.mapCtrls ("Z5")) map.addControl (new google.maps.LargeMapControl ());
			if (_private.mapCtrls ("Z6")) map.addControl (new google.maps.LargeMapControl3D ());

			if (_private.mapCtrls ("O")) map.addControl (new google.maps.OverviewMapControl ());
			if (_private.mapCtrls ("M")) map.addControl (new google.maps.MenuMapTypeControl ());
			if (_private.mapCtrls ("N")) map.addControl (new google.maps.NavLabelControl ());
			if (_private.mapCtrls ("S")) map.addControl (new google.maps.ScaleControl ());
			if (_private.mapCtrls ("T")) map.addControl (new google.maps.MapTypeControl ());

			if (_private.mapCtrls ("W")) map.enableScrollWheelZoom ();

/*			if (_private.mapUses ("s"))
			{
				var searchControl = new google.search.SearchControl();
				searchControl.addSearcher(new google.search.WebSearch());
				searchControl.addSearcher(new google.search.NewsSearch());
				searchControl.draw($id("searchcontrol"));
			}

			google.maps.Event.addListener (map, "maptypechanged", function ()
			{
				var mt = map.getCurrentMapType ();

				if (mt == G_SATELLITE_3D_MAP) _private.geInit ();
			});
*/
//alert (G_API_VERSION);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		addMarker : function (lat, lng, name, txt, icon, click, ref)
		{
			if (icon == undefined) icon = "";

			var marker;
			var point = new google.maps.LatLng (lat, lng);
			ref = parseInt (ref);

			if (icon != "")
			{
				if (iconDir == null)
				{
					alert ("Marker Image Directory has not been set");
				}
				else
				{
					var mkIcon;

					if (icon.indexOf ("tiny") > -1)
					{
						mkIcon = new google.maps.Icon (tinyIcon);
						mkIcon.shadow = iconDir + "/shadow-tiny.png";
					}
					else
					if (icon.indexOf ("small") > -1)
					{
						mkIcon = new google.maps.Icon (smallIcon);
						mkIcon.shadow = iconDir + "/shadow-small.png";
					}
					else
					{
						mkIcon = new google.maps.Icon (stdIcon);
						mkIcon.shadow = iconDir + "/shadow.png";
					}

					mkIcon.image = iconDir + "/" + icon + ".png";
					marker = new google.maps.Marker (point, mkIcon);
				}
			}
			else
			{
				marker = new google.maps.Marker (point);
			}

			map.addOverlay (marker);

			if (name != "" || txt != "")
			{
				google.maps.Event.addListener (marker, "mouseover", function ()
				{
					var p = map.fromLatLngToContainerPixel (marker.getLatLng ());
					p.x += 10;
					p.y -= 10;
					namepop = new NamePopup (name);
					map.addControl (namepop, new google.maps.ControlPosition (G_ANCHOR_TOP_LEFT,
						new google.maps.Size (p.x, p.y)));
				});

				google.maps.Event.addListener (marker, "mouseout", function ()
				{
					map.removeControl (namepop);
				});
			}

			if (click != "" || ref > 0)
			{
			  	google.maps.Event.addListener (marker, "click", function ()
				{
					map.removeControl (namepop);

					if (ref > 0 && (!killAjax || isTour || mapPages))
					{
						// Replace the image of any previous marker

						if (currRef > -1)
						{
							var dat = mkList [currRef][2];
							var d = dat.split ("^``^");
							map.removeOverlay (mkList [currRef][0]);

							mkList [currRef][0] = _private.addMarker (d[1], d[2], d[3], "",
								_private.getIcon (d[5], 1), d[4], d[0]);
						}

						var zm = map.getZoom ();
						var ml = _private.getMkLevel (zm);

						if (ml == 0)
						{
							map.panTo (marker.getPoint ());
						}
						else
						{
							map.setCenter (marker.getPoint (), 12);
						}

						destAjax = DLibUtilities.initAjax ("/ajax/dest.php?r=" + ref,
							(isTour ? PE3.updateTourPage : PE3.updateDestPage));
					}
					else
					{
						window.location = click;
					}
				});
			}

			return marker;
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		update : function (fld, dat)
		{
//if (dat == undefined) alert ("undef = " + fld);
			if ($id (fld))
			{
				dat = dat.replace (/&amp;/g, "&");
				$id (fld).innerHTML = dat;
			}
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

	var _public =
	{
		////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// Initialise PE3
		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		init : function (host, dr, ka)
		{
			if (ka == undefined) ka = false;

			killAjax = (ka == 1);

			thisHost = host;
			docroot = dr;
			iconDir = "/images/gmmarkers";
			sysCheck = DLibUtilities.systemCheck ();
			DLibUtilities.initAjax ("/ajax/mapload.php");
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		worldMap : function ()
		{
			gmap = $id ("gmap");
			gmap.style.width = "450px";
			gmap.style.height = "310px";

			google.load ("maps", gMapVer);
			google.setOnLoadCallback (PE3.worldMap1);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		worldMap1 : function ()
		{
			_private.initMap ("Z2MW");
			map.setCenter (new google.maps.LatLng (25, 0), 1);
			map.setMapType (G_SATELLITE_MAP);

			var url = "/ajax/groupmarkers.php?mm=0&rx=" + Math.random ();
			ajax = DLibUtilities.initAjax (url, PE3.worldMap2);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		// World map markers call back
		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		worldMap2 : function ()
		{
			if (DLibUtilities.checkAjax (ajax))
			{
				var data = ajax.responseText;
				ajax = null;

				if (data != "" && data != lastData)
				{
					lastData = data;

					var dat = data.split ("\n");

					for (i = 0; i < dat.length; i++)
						if (dat [i].length > 0)
						{
							var d = dat [i].split ("^``^");

							var mk = _private.addMarker (d[1], d[2], d [3] + ": " + d[5], "",
								(d[6] == 0 ? "large-dot-green" : "plain-orange-tiny"), d[4], 0);
						}
				}
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		ccrPage : function (id, mm, lat, lng, level, mt)
		{
			thisData = [id, mm, lat, lng, level, mt];
			gmap = $id ("gmap");
			gmap.style.width = "450px";
			gmap.style.height = "310px";

			google.load ("maps", gMapVer);
			google.setOnLoadCallback (PE3.ccrPage1);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		ccrPage1 : function ()
		{
			_private.initMap ("Z2MW");

			map.setCenter (new google.maps.LatLng (thisData [2], thisData [3]), thisData [4]);
			map.setMapType (mapTypes [thisData [5]]);

			var url = "/ajax/groupmarkers.php?mm=" + thisData [1] + "&ref=" + thisData [0] +
				"&rx=" + Math.random ();
			ajax = DLibUtilities.initAjax (url, PE3.ccrPage2);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		ccrPage2 : function ()
		{
			if (DLibUtilities.checkAjax (ajax))
			{
				var data = ajax.responseText;
				ajax = null;

				if (data != "" && data != lastData)
				{
					lastData = data;

					var dat = data.split ("\n");

					for (i = 0; i < dat.length; i++)
						if (dat [i].length > 0)
						{
							var d = dat [i].split ("^``^");

							if (i == 0)
							{
								var mk = _private.addMarker (d[1], d[2], d [3], "",
									"large-dot-red", d[4], 0);
							}
							else
							{
								var mk = _private.addMarker (d[1], d[2], d [3] + ": " + d[5], "",
									"large-dot-green", d[4], 0);
							}
						}
				}
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		addCCRMarkers : function ()
		{
			if (DLibUtilities.checkAjax (ajax))
			{
				var data = ajax.responseText;
				ajax = null;

				if (data != "" && data != lastData)
				{
					lastData = data;

					for (key in mkList)
					{
						mkList [key][1] = 2;
					}

					var dat = data.split ("\n");

					for (i = 0; i < dat.length; i++)
						if (dat [i].length > 0)
						{
							var d = dat [i].split ("^``^");

							if (!(d [0] in mkList))
							{
								var mk = _private.addMarker (d[1], d[2], d [3] + ": " + d[5], "",
									"small-dot-green", d[4], 0);
								mkList [d[0]] = [mk, 0, dat [i]];
							}
							else
							{
								mkList [d[0]][1] = 0;
							}
						}

					// Remove markers no longer on the screen

					for (key in mkList)
					{
						if (mkList [key][1] == 2)
						{
							map.removeOverlay (mkList [key][0]);
							delete mkList [key];
						}
					}
				}
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		tourPage : function (id, lat, lng, level, maptype, hotel, puser, maph)
		{
			if (maph == undefined) maph = 0;

			thisData = [id, lat, lng, level, maptype, hotel, puser];
			gmap = $id ("gmap");
			gmap.style.height = (maph > 0 ? maph : 200) + "px";

			google.load ("maps", gMapVer);
			google.setOnLoadCallback (PE3.destPage1);
			isTour = true;
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		destPage : function (id, lat, lng, level, maptype, altDisplay)
		{
			if (altDisplay == undefined) altDisplay = false;
			mapPages = altDisplay;
			lastZoom = level;
			thisData = [id, lat, lng, level, maptype, 0, ""];
			gmap = $id ("gmap");
			gmap.style.width = (mapPages ? "600px" : "340px");
			gmap.style.height = "250px";
			mkLevel = 0;

			google.load ("maps", gMapVer);
			google.setOnLoadCallback (PE3.destPage1);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		destPage1 : function ()
		{
			_private.initMap ("Z2MW");
			map.setCenter (new google.maps.LatLng (thisData [1], thisData [2]), thisData [3]);
			map.setMapType (mapTypes [thisData [4]]);

			google.maps.Event.addListener (map, "moveend", function ()
			{
				var zm = map.getZoom ();
				var ml = _private.getMkLevel (zm);

				var	bounds = map.getBounds ();
				var	southWest = bounds.getSouthWest ();
				var	northEast = bounds.getNorthEast ();
				var	lngSpan = northEast.lng () - southWest.lng ();
				var	latSpan = northEast.lat () - southWest.lat ();

				if (mkLevel == -1 || ((lastZoom == zm || lastZoom == -1) && mkLevel == 0 && ml == 1))
				{
					mkLevel = 0;
					ml = 0;
				}
//alert ([lastZoom, zm, ml, mkLevel]);
				if (ml != mkLevel)
				{
					// Remove all existing pins

					currRef = -1;

					for (key in mkList)
					{
						map.removeOverlay (mkList [key][0]);
						delete mkList [key];
					}

					mkLevel = ml;
				}

				// Add the new pins

				if (mkLevel == 0)
				{
					PE3.addDestMarkers ();
				}
				else
				{
					var inc = (mapPages ? 20 : 10);
					var url = "/ajax/groupmarkers.php?mm=" + (mkLevel + inc) + "&l=" + southWest.lng () +
						"&r=" + northEast.lng () + "&t=" + northEast.lat () + "&b=" + southWest.lat () +
						"&h=" + thisData [5] + "&u=" + thisData [6] + "&rx=" + Math.random ();

					ajax = DLibUtilities.initAjax (url, (mkLevel < 2 ? PE3.addDestMarkers2 : PE3.addCCRMarkers));
				}

				lastZoom = zm;
			});

			PE3.addDestMarkers ();
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		addDestMarkers : function ()
		{
			var	bounds = map.getBounds ();
			var	southWest = bounds.getSouthWest ();
			var	northEast = bounds.getNorthEast ();
			var	lngSpan = northEast.lng () - southWest.lng ();
			var	latSpan = northEast.lat () - southWest.lat ();
//			latWidth = latSpan;

			var url = "/ajax/groupmarkers.php?mm=" + (4 + (mapPages ? 20 : 0)) + "&ref=" + thisData [0] +
				"&l=" + southWest.lng () + "&r=" + northEast.lng () + "&t=" + northEast.lat () +
				"&b=" + southWest.lat () + "&h=" + thisData [5] + "&u=" + thisData [6] + "&rx=" + Math.random ();

			ajax = DLibUtilities.initAjax (url, PE3.addDestMarkers2);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		addDestMarkers2 : function ()
		{
			if (DLibUtilities.checkAjax (ajax))
			{
				var data = ajax.responseText;
				ajax = null;

				if (data != "" && data != lastData)
				{
					lastData = data;

					for (key in mkList)
					{
						mkList [key][1] = 2;
					}

					var dat = data.split ("\n");

					for (i = 0; i < dat.length; i++)
						if (dat [i].length > 0)
						{
							var d = dat [i].split ("^``^");

							if (!(d [0] in mkList))
							{
								var mk = _private.addMarker (d[1], d[2], d[3], "",
									_private.getIcon (d[5], d[6]), d[4], d[0]);

								mkList [d[0]] = [mk, 0, dat [i]];

								// Copy the current marker ref

								if (d[6] == 0)
								{
									currRef = d[0];
								}
							}
							else
							{
								mkList [d[0]][1] = 0;
							}
						}

					// Remove markers no longer on the screen

					for (key in mkList)
					{
						if (mkList [key][1] == 2)
						{
							if (key == currRef) currRef = -1;

							map.removeOverlay (mkList [key][0]);
							delete mkList [key];
						}
					}
				}
				else
				if (data == "" && mkLevel == 1)
				{
					mkLevel = 0;
					PE3.addDestMarkers ();
				}
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		logoBackground : function (m, htitle)
		{
			var header = $id ("header").style;
			var headtitle = $id ("headtitle");

			if (m == 0)
			{
				header.background = 'url("/images/site/earth_map_large.jpg") no-repeat white';
//				headtitle.innerHTML = "Panoramic Earth";
			}
			else
			{
				header.background = 'url("/images/site/earth_map_small.jpg") no-repeat white 25px 5px';

				switch (m)
				{
					case 3 : // Destination
//						headtitle.innerHTML = htitle + " - Panoramic Earth Travel Information";
						break;

					case 4 : // Page
//						headtitle.innerHTML = htitle + " - Panoramic Earth";
						break;
				}
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		updateDestPage : function ()
		{
			if (DLibUtilities.checkAjax (destAjax))
			{
				var data = destAjax.responseText;
				destAjax = null;

				if (data != "" && data != lastDestData)
				{
					lastDestData = data;

					var d = data.split ("^``^");

					var	ref				= d[0],
						latitude		= d[1],
						longitude		= d[2],
						usTitle			= d[3],
						title			= d[4],
						pintype			= d[5],
						destLink		= d[6],
						subTitle		= d[7],
						continent		= d[8],
						country			= d[9],
						region			= d[10],
						destination		= d[11],
						description		= d[12],
						comments		= d[13],
						photographer	= d[14],
						panoPath		= d[15],
						playPath		= d[16],
						altRef			= d[17],
						rawDesc			= d[18],
						truncDesc		= d[19];

					// Set up new marker

					currRef = ref;

					var mk = _private.addMarker (latitude, longitude, usTitle, "",
						_private.getIcon (pintype, 0), destLink, ref);

					if (mkList [currRef])
					{
						var dat = mkList [currRef][2];
						var d = dat.split ("^``^");
						map.removeOverlay (mkList [currRef][0]);
						mkList [currRef][0] = mk;
					}
					else
					{
						mkList [currRef] = [mk, 0, d];
					}

					if (mapPages)
					{
						$id ("mappagedesccontent").innerHTML = truncDesc.replace (/&amp;/g, "&");
						$id ("fulldesctitle").innerHTML = title;
						$id ("fulldesccontent").innerHTML = rawDesc.replace (/&amp;/g, "&");
					}
					else
					{
						if ($id ("commentref")) 	// If comments enabled for this user
						{
							$id ("commentref").value = ref;
						}

						_private.update ("ddescription", description);
						_private.update ("dcomments", comments);
						_private.update ("logoname", usTitle);
						_private.update ("logostrapline", subTitle);
					}

					_private.update ("paninfo" + (mapPages ? "alt" : ""),
						"<div id=\"photographer" + (mapPages ? "alt" : "") + "\">" + photographer + "</div>" + title);

					var path = '<ul id="path"><li><a href="/world">Earth</a></li>' +
						'<li> &gt; <a href="/' + continent + '">' + continent + '</a></li>' +
						'<li> &gt; <a href="/' + continent + '/' + country + '">' + country + '</a></li>' +
						'<li> &gt; <a href="/' + continent + '/' + country + '/' + region + '">' +
							region + '</a></li>' +
						'<li> &gt; <a href="/' + continent + '/' + country + '/' + region + '/' +
							destination.replace (/\s/g, "+") + '">' + destination + '</a></li></ul>';

					_private.update ("pathbar", path);
					var panoId = "panpic" + (mapPages ? "alt" : "");
					var panpic = $id (panoId);

//alert (panpic.onclick);
					panpic.style.background = "url('" + playPath + "') no-repeat";
					panpic.style.cursor = "pointer";

//alert (["update", ref, panoPath, panoId]);
					var id = ref;

					if (altRef > 0 && altRef != ref) id = altRef;

					panpic.onclick = new Function ("PE3.displayPan (" + id + ", '" + panoPath + "', '" + panoId + "')");

					if (mapPages)
					{
						panpic.style.backgroundSize = "600px 220px";
						panpic.style.width = "600px";
					}

//alert (panpic.style.background);

//					_private.update ("panembed", );

					_private.update ("panshare", 'Share: &nbsp;' + PE3.socialSites (title, destLink));

					var kr = $id ("krpanoSWFObject");

					if (kr) kr.style.display = "none";

					_private.update ("panlink", '<a href="' + destLink + '" title="The direct link to this location">Link</a>');
					_private.update ("panemail", '<a href="mailto:?subject=Panoramic Image of ' +
						title.replace (/\"/g, "&quot;") + '&body=Dear%0A%0AHere is a panoramic image I found on ' +
						'Panoramic Earth:%0A%0Ahttp://www.panoramicearth.com' + destLink + '%0A%0A" ' +
						'title="Email a friend with a link to this panorama">Email</a>');

					if (mapPages)
					{
						_private.update ("panmappage",  '<a href="' + destLink + '" title="Show location details">Small Map View</a>');
					}
				}
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		socialSites : function (title, destLink)
		{
			var ttl = encodeURI (title),
				url = encodeURI ("http://" + window.location.host + destLink);

			var siteList =
			[
				"facebook",	"www.facebook.com/share.php?u=" + url, "Share this panorama on Facebook",
				"twitter", "twitter.com/home/?status=" + ttl + "+" + url, "Tweet about this panorama",
				"digg", "digg.com/submit?phase=2&url=" + url, "Digg this panorama",
				"stumbleupon", "www.stumbleupon.com/submit?url=" + url + "&title=" + ttl, "Add this panorama to Stumbleupon",
				"delicious", "del.icio.us/post?url=" + url + "&title=" + ttl, "Bookmark this panorama on del.icio.us",
				"reddit", "reddit.com/submit?url=" + url + "&title=" + ttl, "Send this panorama to reddit",
				"slashdot", "slashdot.org/submit.pl?story=" + ttl + "%0D%0D" + url, "Slashdot this panorama"
			];

			var txt = "";

			for (i = 0; i < siteList.length; i += 3)
			{
				var site = siteList [i],
					lnk = siteList [i + 1],
					caption = siteList [i + 2];

				txt += '<a href="http://' + encodeURI (lnk) + '" target="_blank"><img '+
					'src="/images/social/' + site + '.png" border="0" alt="' + caption +
					'" /></a> &nbsp; ';
			}

			return txt;
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		updateTourPage : function ()
		{
			if (DLibUtilities.checkAjax (destAjax))
			{
				var data = destAjax.responseText;
				destAjax = null;

				if (data != "" && data != lastDestData)
				{
					lastDestData = data;

					var d = data.split ("^``^");

					var	ref				= d[0],
						latitude		= d[1],
						longitude		= d[2],
						usTitle			= d[3],
						title			= d[4],
						pintype			= d[5],
						destLink		= d[6],
						subTitle		= d[7],
						continent		= d[8],
						country			= d[9],
						region			= d[10],
						destination		= d[11],
						description		= d[12],
						comments		= d[13],
						photographer	= d[14],
						panoPath		= d[15],
						playPath		= d[16],
						altRef			= d[17];

					// Set up new marker

					currRef = ref;

					var dat;

					if (mkList [currRef])
					{
						dat = mkList [currRef][2];
						var d = dat.split ("^``^");
						map.removeOverlay (mkList [currRef][0]);

						mkList [currRef][0] = _private.addMarker (latitude, longitude, usTitle, "",
							_private.getIcon (pintype, 0), destLink, ref);
					}

					_private.update ("ddescription", description);
					_private.update ("dheader", '<a href="' + destLink + '">' + usTitle + '</a>');
					_private.update ("photographer", photographer);
					_private.update ("dtitle", title);

					var panpic = $id ("panopic");

					panpic.style.background = "url('" + playPath + "') no-repeat";
					panpic.style.cursor = "pointer";
					PE3.displayPan (altRef, panoPath, 'panopic');

					var kr = $id ("krpanoSWFObject");

					linkAjax = DLibUtilities.initAjax ("/ajax/tourlinks.php?r=" + ref + "&h=" +
						thisData [5], PE3.updateTourLinks);
				}
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		updateTourLinks : function ()
		{
			if (DLibUtilities.checkAjax (linkAjax))
			{
				var data = linkAjax.responseText;
				linksAjax = null;

				if (data != "" && data != lastLinksData)
				{
					lastLinksData = data;
					_private.update ("dlinks", data);
				}
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		displayPan : function (id, path, panoFld)
		{
			if (path != "" && path.indexOf ("|") > -1)
				path = "/images/pano/" + path.replace ("|", "/");

			if (deconcept.SWFObjectUtil.getPlayerVersion().major >= 9)
			{
				$id (panoFld).onclick = "";

				if (krPano == null)
				{
					krPano = new SWFObject (path + "/krpano.swf", "krpanoSWFObject", "100%", "100%", "9.0.28", "#000000");
					krPano.addParam ("allowFullScreen", "true");
					krPano.addParam ("allowScriptAccess","sameDomain");
					krPano.addParam ("wmode", "opaque");		// Forces Flash to not be on top!
					krPano.addVariable ("xml", path + "/" + id + ".xml");
					krPano.useExpressInstall("/js/expressinstall.swf");
					if (mapPages) $id (panoFld).style.width = "600px";

					if (krPano.write (panoFld))
						var mousewheelfixes = new SWFkrpanoMouseWheel (krPano);
				}
				else
				{
					// Already set up so just modify the values

					var kr = $id ("krpanoSWFObject");
					kr.style.display = "block";

					if (mapPages) kr.style.width = "600px";
					runPath = path + "/" + id + ".xml";
//alert (["runPath", runPath]);
					rpTm = setTimeout ("PE3.runPano()", 1000);
				}
			}
			else
			{
				$id (panoFld).innerHTML = '<center>ERROR:<br/><br/>Adobe ' +
					'Flash Player 9 needed<br/><br/><a href="http://www.adobe.com/go/' +
					'getflashplayer/" target="_blank"><img src="http://www.macromedia.com/images/' +
					'shared/download_buttons/get_flash_player.gif" border="1"><\/a><br/>...click ' +
					'here to download...<\/center>';
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		runPano : function ()
		{
//alert (["run", runPath]);
			clearTimeout (rpTm);
			krpano().call("loadpano(../../../.." + runPath + ",null,null,NOBLEND)");
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		closePopup : function ()
		{
			popup = $id ("embedpopup");
			pops = popup.style;
			pops.display = "none";
			pops.visibility = "hidden";
			pops.top = "-500px";
			pops.left = "-500px";
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		embedPopup : function (md, panref, thisuser, tourprice, author)
		{
			tourCost = tourprice;

			var xy;

			if ($id ("panpic"))
			{
				xy = DLibUtilities.findPos ($id ("panpic"));
			}
			else
			{
				xy = DLibUtilities.findPos ($id ("panopic"));
			}

			if (!$id ("embedpopup")) return;	// Page not ready yet

			popup = $id ("embedpopup");
			pops = popup.style;

			pops.position = "absolute";
			var top = (xy [1] + 20);

			if (top < 20) top = 20;

			var txt = "<div id=\"embedpoptitle\"><div id=\"embedpopclose\" onclick='PE3.closePopup()' />" +
				"</div>Embed an Image or Tour in Your Website</div>";

			var popupHeight = (thisuser == author ? 260 : 240);

			switch (md)
			{
				case 1 : // Select embed type
					embedRef = -1;

					if (thisuser == '')
					{
						txt += '<p><b>Please note:</b> embedding is only available to registered users.</p>' +
							'<p>Either log in using the <b>LOGIN</b> option above or ' +
							'register with us. Registering with Panoramic Earth also allows you to add ' +
							'your own panoramic images and comment on other people\'s images.</p>' +
							'<br/><center><form method="post" action="/register.php"><input type="submit" ' +
							'value=" Register With Panoramic Earth " /></form></center>';

						popupHeight = 140;
					}
					else
					{
						txt += '<form name="embedform1"><h2>' + radio ("embedstyle[0]", 0,
							"Single Image Embedding", true, false, 'onclick="PE3.setRegTour(0)"') + '</h2>' +
							'<p>For non-commercial sites only, code must be used as supplied. By ' +
							'selecting this you agree to our ' + pophref ("Terms and Conditions",
							"/popup.php?p=TANDC-EMBED-SINGLE") + '. For commercial use ' +
							pophref ("click here", "/popup.php?p=embed-single-vt-commercial") + '.</p><h2>' +
							radio ("embedstyle[0]", 0, "Regional Tour Embedding", false, false,
							'onclick="PE3.setRegTour(1)"') + '</h2>' +
							'<p>Embed a ' + pophref ("virtual tour of whole region", "/popup.php?p=EMBED_TOUR") +
							' with Google map. Available to all sites. ' + pophref ("Terms and Conditions",
							"/popup.php?p=TANDC-EMBED-REGION") + '. The tour will start at the current location.</p>' +
							'<div style="margin-left: 20px; line-height: 1.9em;">' +
							radio ("#tourembedstyle[0]", 0, "Free Tour (Contains Adverts)", true, true) + "<br/>\n" +
							radio ("#tourembedstyle[1]", 0, "Paid Tour £" + DLibNumerical.dec (tourCost, 2) +
								" pa. (Advert Free)", false, true) +
							((thisuser == author && enablePMap) ? "<br/>\n" + radio ("#tourembedstyle[2]", 0,
								"Personal Map Tour (free - shows only your own panoramas)", false, true) + "\n" : "\n") +
							'</div><div id="embedpopupcont"><input type="button" ' +
							'value="Continue" onclick="PE3.embedPopup(2,' + panref + ',\'' +
							thisuser + '\')" /></div></form>';
					}

					break;

				case 2 : // Display the embed code
					// First retrieve the values from the previous form

					var et0 = document.embedform1.embedstyle[0].checked,
						et1 = document.embedform1.embedstyle[1].checked,
						et1a = document.embedform1.tourembedstyle[0].checked,
						et1b = document.embedform1.tourembedstyle[1].checked,
						et1c = false;

					if ($id ("tourembedstyle2"))
					{
						et1c = document.embedform1.tourembedstyle[2].checked;
					}

					var whStyle = ' style="width: 70px; margin-right: 60px;" onchange="PE3.redoEmbed(' +
						panref + ',\'' + thisuser + '\'';

					var width = '<select id="twidth"' + whStyle + ')">',
						height = '<select id="theight"' + whStyle + ')">',
						copyBtn = '<input type="button" value="Select" onclick="PE3.copyCode()" ' +
							'style="margin-left: 20px" />';

					var etCode = '<textarea id="embedtourcode" style="width: 610px; height: 150px;"></textarea>';

					if (et0)	// Single Image Embedding
					{
						popupHeight = 290;
						embedMode = 3;

						for (var i = 250; i <= 600; i += 50)
						{
							if (i > 300)
							{
								width += '<option value="' + i + '"' + (i == 500 ? ' selected="selected"' : "") +
									'>' + i + '</option>';
							}

							if (i < 550)
							{
								height += '<option value="' + i + '"' + (i == 400 ? ' selected="selected"' : "") +
									'>' + i + '</option>';
							}
						}

						width += '</select>';
						height += '</select>';

						txt += '<form name="embedform2"><h2>Single Image Embed &amp; Share Code</h2>' +
							'<p>Copy and paste this code exactly as given below. If you change the width and ' +
							'height of the embedded panorama then please wait for the new code to be ' +
							'reloaded.</p><div style="margin: 10px 0 0 0; text-align: center;"><b>Width</b>: ' +
							width + ' <b>Height</b>: ' + height + copyBtn + '</div>' + etCode + '</form>';
					}
					else		// Regional Tour Embedding
					{
						if (et1a)
						{
							popupHeight = 290;
							embedMode = 0;
						}
						else
						if (et1c)
						{
							popupHeight = 340;
							embedMode = 4;
						}
						else
						{
							popupHeight = 340;
							embedMode = 1;
						}

						for (var i = 450; i <= 1000; i += 50)
						{
							if (i < 800)
							{
								width += '<option value="' + i + '"' + (i == 600 ? ' selected="selected"' : "") +
									'>' + i + '</option>';
							}

							if (i > 500)
							{
								height += '<option value="' + i + '"' + (i == 750 ? ' selected="selected"' : "") +
									'>' + i + '</option>';
							}
						}

						width += '</select>';
						height += '</select>';

						txt += '<form name="embedform2"><h2>Regional Tour Embed &amp; Share Code</h2>' +
							'<p>Copy and paste this code exactly as given below. If you change the width and ' +
							'height of the embedded panorama then please wait for the new code to be ' +
							'reloaded.</p><div style="margin: 10px 0 0 0; text-align: center;"><b>Width</b>: ' +
							width + ' <b>Height</b>: ' + height + copyBtn + '</div>' +
							(et1b ? '<p><b>Paid Tour Selected.</b> Adverts will be removed from Paid Tours ' +
							'once payment has been received. Please check your email for an invoice.</p>' : '') +
							etCode + '</form>';

					}

					txt += '<div id="embedref" style="text-align: right; font-size: 9px; color: #bbb; ' +
						'padding-right: 10px;"></div>';
					break;

				case 3 : // Embedded Tour
					break;
			}

			popup.innerHTML = txt;

			pops.top = top + "px";
			pops.left = (xy [0] + 20) + "px";
			pops.visibility = "visible";
			pops.display = "block";
			pops.width = "630px";
			pops.height = popupHeight + "px";

			var poptitle = $id ("embedpoptitle");

			if (md == 2) PE3.redoEmbed (panref, thisuser);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		setRegTour : function (md)
		{
			$id ("tourembedstyle0").disabled = (md == 0 ? "disabled" : "");
			$id ("tourembedstyle1").disabled = (md == 0 ? "disabled" : "");

			if ($id ("tourembedstyle2"))
			{
				$id ("tourembedstyle2").disabled = (md == 0 ? "disabled" : "");
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		loadPMap : function (thisuser)
		{
			$id ("embedtourcode").innerHTML = "Loading...";

			var w = parseInt ($id ("twidth").value),
				h = parseInt ($id ("theight").value);

			var url = "/ajax/embed.php?r=" + embedRef + "&u=" + thisuser + "&m=4&&w=" + w + "&h=" + h;

			embedAjax = DLibUtilities.initAjax (url, PE3.showEmbedCode);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		redoEmbed : function (panref, thisuser)
		{
			$id ("embedtourcode").innerHTML = "Loading...";

			var w = parseInt ($id ("twidth").value),
				h = parseInt ($id ("theight").value);

			var url = "/ajax/embed.php?d=" + panref + "&u=" + thisuser + "&m=" + embedMode + "&r=" + embedRef +
				"&w=" + w + "&h=" + h;

			embedAjax = DLibUtilities.initAjax (url, PE3.showEmbedCode);
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		showEmbedCode : function ()
		{
			if (DLibUtilities.checkAjax (embedAjax))
			{
				var data = embedAjax.responseText;
				embedAjax = null;

				lastEmbedData = data;
				var d2 = data.split ("^");
				embedRef = d2[0];
				$id ("embedtourcode").innerHTML = d2[1];
				$id ("embedref").innerHTML = embedRef;
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		copyCode : function ()
		{
			var cd = $id ("embedtourcode");
			cd.focus ();
			cd.select ();

			if (cd.createTextRange)
			{
				var rng = cd.createTextRange ();
				rng.execCommand ("Copy");
			}
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		setPMap : function (pmap)
		{
			enablePMap = pmap;
		},

		////////////////////////////////////////////////////////////////////////////////////////////////////////////////

		dragStart : function (e)
		{
			var xyMouse = (document.all ? [window.event.clientX, window.event.clientY] : [e.clientX, e.clientY]);
			fulldescBox = $id ("fulldesc");
			xyPos = DLibUtilities.findPos (fulldescBox);
			xyOffset = [xyMouse [0] - xyPos [0], xyMouse [1] - xyPos [1]];
			document.onmousemove = PE3.dragFullDesc;
			document.onmouseup = PE3.dragEnd;
			DLibUtilities.opacity (fulldescBox, 70);
			return false;
		},

		dragFullDesc : function (e)
		{
			var xyMouse = (document.all ? [window.event.clientX, window.event.clientY] : [e.clientX, e.clientY]);
			fulldescBox.style.left = (xyMouse [0] - xyOffset [0]) + "px";
			fulldescBox.style.top = (xyMouse [1] - xyOffset [1]) + "px";
			return false;
		},

		dragEnd : function (e)
		{
			DLibUtilities.opacity (fulldescBox, 100);
			var xyMouse = (document.all ? [window.event.clientX, window.event.clientY] : [e.clientX, e.clientY]);
			fulldescBox.style.left = (xyMouse [0] - xyOffset [0]) + "px";
			fulldescBox.style.top = (xyMouse [1] - xyOffset [1]) + "px";
			document.onmousemove = document.onmouseup = null;
			return false;
		}
	};

	return _public;
} ();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

// ]]>

