//<![CDATA[

var map;
var geocoder;
var keyboardHandler;
var markerManager;
var loadedDeedMarkers = new Array();
var loadedMarkersCount = 0;
var loadedMarkersLimit = 1000;
var loadedDeedOverlays = new Array();
var maxDisplayZoom = 12;
var maxDisplayZoomEncoded = 'PEEEP';
var defaultInitialZoom = 7;
var defaultSearchZoom = 12;
var displayDeedZoom = 12;
var displayLatLngZoom = 18;
var defaultMapType;
var baseCSIcon;
var baseIcon;
var locatingDeed = false;
var locatingMarker;
var locatingLat;
var locatingLng;

// Open a new window to display a deed link in.
function openWindow(url) {
	window.open( url, 'EarthClaim' );
}

function openHelpWindow(url) {
	var ww = detectWidth();
	var wh = detectHeight();
	window.open( url, '_blank', 'dependent=1,hotkeys=0,location=0,menubar=0,personalbar=0,scrollbars=1,toolbar=0,outerHeight='+wh/2+',outerWidth='+ww/2 );
}

// Open a window with an explaination and let the user hit Yes or No
function explain(func, msg, yesText, noText) {
	var newwin = window.open('','_blank','width=325,height=150,status=0');
	if (!newwin.opener) {
		newwin.opener = self;
	}
	with( newwin.document ) {
		open();
		write('<html>');
		write('<head>');
		write('<title>Earth Claim</title>');
		write('<link href="/css/styles.css" type="text/css" rel="stylesheet">');
		write('</head>');
		write('<body><form name=form><p><span class="normalText">' + msg + '</span></p>');
		write('<p><center><input type=button value="' + yesText +'" onClick="window.opener.' + func + ';window.close()">');
		write('<input type=button value="' + noText +'" onClick="window.close()">');
		write('</center></form></body></html>');
		close();
   }
}

// Initial processing when no map is loaded.
function noMapLoad() {
	swapHeaderImage();
}

// Initial load of the map and setting up the handlers for the event listeners.
function load() {
	swapHeaderImage();
   	if( GBrowserIsCompatible() ) {
		baseCSIcon = new GIcon();
		baseCSIcon.shadow = "/images/flag_shadow2.png";
		baseCSIcon.shadowSize = new GSize(51, 38);
		baseCSIcon.iconAnchor = new GPoint(17, 35);
		baseCSIcon.infoWindowAnchor = new GPoint(5, 20);

		baseFSIcon = new GIcon();
		baseFSIcon.shadow = "/images/flag_for_sale_shadow.png";
		baseFSIcon.shadowSize = new GSize(35, 35);
		baseFSIcon.iconAnchor = new GPoint(12, 35);
		baseFSIcon.infoWindowAnchor = new GPoint(1, 5);
		baseFSIcon.image = "/images/flag_for_sale.png";
		baseFSIcon.iconSize = new GSize(42, 38);
		
		baseIcon = new GIcon();
		baseIcon.shadow = "/images/flag_shadow1.png";
		baseIcon.shadowSize = new GSize(35, 35);
		baseIcon.iconAnchor = new GPoint(2, 35);
		baseIcon.infoWindowAnchor = new GPoint(1, 5);
		
   		geocoder = new GClientGeocoder();
   		defaultMapType = G_HYBRID_MAP;
		var mapDiv = document.getElementById("map");

   		if( mapDiv !== null ) {

    		map = new GMap2(mapDiv);
    		map.addControl(new GLargeMapControl());
			map.addControl(new GMapTypeControl());
			map.addControl(new GScaleControl());
			map.addControl(new GOverviewMapControl());
			map.enableContinuousZoom();
			map.enableScrollWheelZoom();
			keyboardHandler = new GKeyboardHandler(map);
			
			// Centre the map on the last location the user was at, or a default location, if a new user.
			var lat = readCookie('lat');
			var lng = readCookie('lng');
			var zoom = readCookie('zoom') * 1;
			var mapTypeName = readCookie('mapType');
			var mapType;
			if( mapTypeName == 'Map' ) {
				mapType = G_NORMAL_MAP;
			} else if( mapTypeName == 'Satellite' ) {
				mapType = G_SATELLITE_MAP;
			} else {
				mapType = G_HYBRID_MAP;
			}
			if( lat ) {
			} else {
				lat = 51;
				lng = -114;
				zoom = defaultInitialZoom;
				mapType = defaultMapType;
			}
			map.setCenter( new GLatLng( lat, lng ), zoom, mapType );
			savePlace();
			saveZoom();

			// If the user passed a deed identifier or a lat/lng, centre the map on the location.
			// mapCentreForParams is set in index.jsp
			if( mapCentreForParams !== '' ) {
			    var fields = mapCentreForParams.split(',');
			    if( fields.length == 5 ) {
					locatingLat = fields[2];
					locatingLng = fields[3];
					lat = fields[0];
					lng = fields[1];
					if( fields[4] == "Deed" ) {
						zoom = displayDeedZoom;
					} else if( fields[4] == "LatLng" ) {
						zoom = displayLatLngZoom;
					} else {
						zoom = parseInt( fields[4] );
					}
					locatingDeed = true;
					map.setCenter( new GLatLng( lat, lng ), zoom, defaultMapType );
					savePlace();
					saveZoom();
					saveMapType();
				}
			}

			markerManager = new MarkerManager( map, {maxZoom:maxDisplayZoom} );

			// Setup event listeners.
			GEvent.addListener( map, "moveend", moveEndHandler );
			GEvent.addListener( map, "zoomend", zoomHandler );
			GEvent.addListener( map, "click", clickHandler );
			GEvent.addListener( map, "maptypechanged", maptypechangedHandler );
			GEvent.addListener( map, "infowindowclose", function(){map.returnToSavedPosition();} );
			
			GEvent.addListener(map, "mousemove", function(point)
			{
				document.getElementById('center:search:currentLat').innerHTML  = formatLatitude(point.y.toFixed(4),false);
				document.getElementById('center:search:currentLon').innerHTML  = formatLongtitude(point.x.toFixed(4),false);
			});
					
			
			// Monitor the window resize event and let the map know when it occurs
			if (window.attachEvent) {
				window.attachEvent("onresize", resizeMapHandler );
			} else {
				window.addEventListener("resize", resizeMapHandler , false);
			};
			resizeMapHandler();
			// The above resizing throws off the centre. So we need to reset it.
			map.setCenter( new GLatLng( lat, lng ), zoom );
		}
	}
}

// ==================================== Handlers ====================================================

// The map will not resize height without a little JavaScript help.
function resizeMapHandler() {
	document.getElementById("map").style.height = (detectHeight() - 250) + 'px'; 
	this.map.checkResize();
	moveZoomChange(); // Get potentially exposed deeds.
}

// Detect the height of the window.
function detectHeight() {
        var wh = 0;
        // Standard browsers (Mozilla, Safari, etc.)
        if (typeof(window.innerHeight)=="number") {
                wh = window.innerHeight;
        // IE 6
        } else if (document.documentElement && document.documentElement.clientHeight) {
                wh = document.documentElement.clientHeight;
        // IE 5
        } else if (document.body && document.body.clientHeight) {
                wh = document.body.clientHeight;
        }
        return wh;

} 

// Detect the width of the window.
function detectWidth() {
        var ww = 0;
        // Standard browsers (Mozilla, Safari, etc.)
        if (typeof(window.innerWidth)=="number") {
                ww = window.innerWidth;
        // IE 6
        } else if (document.documentElement && document.documentElement.clientWidth) {
                ww = document.documentElement.clientWidth;
        // IE 5
        } else if (document.body && document.body.clientWidth) {
                ww = document.body.clientWidth;
        }
        return ww;

} 

function moveEndHandler() {
	savePlace();
	saveZoom();
	moveZoomChange();
}
function zoomHandler(oldZoom,newZoom) {
	saveZoom();
	moveZoomChange();
}

function clickHandler(overlay,point) {
	if( overlay == null && point != null && purchaseMode ) {
		purchase(point);
	}
}

function maptypechangedHandler() {
	saveMapType();
}

// Show the requested address on the map.
function showAddress( address ) {
	if (geocoder) {
		geocoder.getLatLng(
			address,
			function(point) {
				if (!point) {
					document.getElementById('center:search:error').innerHTML = document.getElementById('center:search:notFound').value;
				} else {
					document.getElementById('center:search:error').innerHTML = "";
					map.setCenter( point, defaultSearchZoom );
					savePlace();
				}
			}
		);
	}
}

function savePlace() {
	var centre = map.getCenter();
	createCookie('lat',centre.lat(), 365);
	createCookie('lng',centre.lng(), 365);
}
function saveZoom() {
	createCookie('zoom',map.getZoom(), 365);
}
function saveMapType() {
	createCookie('mapType',map.getCurrentMapType().getName(), 365);
}
// ================================= Deed Display =========================================================

// Centre the deed on the map.
function locateDeed(centreLat,centreLng,swLat,swLng,msg) {
	if( document.getElementById('displayText') == undefined ) {
		map.setZoom(displayDeedZoom);
		locatingDeed = true;
		locatingLat = swLat;
		locatingLng = swLng;
		map.setCenter(new GLatLng(centreLat,centreLng));
		return true;
	}
	window.alert(msg);
	return false;
}

// Make AJAX call with new map boundaries and update display boundaries.
function moveZoomChange() {
	var bounds = map.getBounds();
    if( map.getZoom() >= maxDisplayZoom ) {
		document.getElementById('center:overlays:neLatitude').value = bounds.getNorthEast().lat();
		document.getElementById('center:overlays:neLongtitude').value = bounds.getNorthEast().lng();
		document.getElementById('center:overlays:swLatitude').value = bounds.getSouthWest().lat();
		document.getElementById('center:overlays:swLongtitude').value = bounds.getSouthWest().lng();
		document.getElementById('center:overlays:requestOverlays').click();
	}
	
	document.getElementById('map').focus();
}

// The AJAX call has returned with the deeds to display. Now display them.
function fetchOverlaysComplete() {
	var jsonObj = eval( '('+document.getElementById('json').value+')' );
	var idx;
	var newMarkers = new Array();
	var newMarker;
	var colour;

	if( jsonObj.overlays.length > 0 ) {

		if( loadedMarkersCount > loadedMarkersLimit ) {
			loadedMarkersCount = 0;
			markerManager.clearMarkers();
		}
		clearUnneededOverlays( jsonObj.overlays );
		
		for( idx = 0; idx<jsonObj.overlays.length; idx++ ) {
			newMarker = displayDeed( jsonObj.overlays[idx] );
			if( newMarker != undefined ) newMarkers.push( newMarker );
			if( locatingDeed && jsonObj.overlays[idx].swLatitude == locatingLat && jsonObj.overlays[idx].swLongtitude == locatingLng ) {
				locatingMarker = newMarker;
			}
		}
		
		if( newMarkers.length > 0 ) {
			markerManager.addMarkers( newMarkers, maxDisplayZoom );
			markerManager.refresh();
		}

		if( locatingDeed && locatingMarker != undefined ) {
			GEvent.trigger( locatingMarker, "click" );
		}
		locatingDeed = false;
		locatingMarker = undefined;
	}
	document.getElementById('map').focus();
}

// Creates a marker and deed boarder at the given point
function displayDeed( overlay ) {
	var colour;
	var marker;

	if( overlay.forSale ) {
		colour = "#FFAA00";
	} else if( overlay.sold ) {
		colour = "#AA0000";
	} else if( overlay.withheld ) {
		colour = "#FFFFFF";
	} else {
		colour = "#FFAA00"; // Must be conditionally sold
	}
	
	if( loadedDeedOverlays[ overlay.swLatitude+","+overlay.swLongtitude+","+overlay.neLatitude+","+overlay.neLongtitude ] == undefined ) {
	
		// Display bounds
		var encodedPolyline = new GPolyline.fromEncoded({
		    color: colour,
		    weight: 2,
		    opacity: 0.7,
		    points: overlay.encodedPolyline,
		    levels: maxDisplayZoomEncoded,
		    zoomFactor: 2,
		    numLevels: 18
		});

		map.addOverlay(encodedPolyline);
		loadedDeedOverlays[ overlay.swLatitude+","+overlay.swLongtitude+","+overlay.neLatitude+","+overlay.neLongtitude ] = encodedPolyline;

	}

	if( loadedDeedMarkers[ overlay.swLatitude+","+overlay.swLongtitude ] == undefined ) {

		// Create the icon for the marker.
		var icon;
		if( overlay.forSale ) {
			icon = new GIcon( baseFSIcon );
		} else if( overlay.mine ) {
			if( overlay.sold ) {
				icon = new GIcon( baseIcon );
				icon.image = "/images/flag_my.png";
				icon.iconSize = new GSize(30, 35);
			} else { // Must be conditionally sold
				icon = new GIcon( baseCSIcon );
				icon.image = "/images/flag_my2.png";
				icon.iconSize = new GSize(42, 38);
			}
		} else if( overlay.sold ) {
			icon = new GIcon( baseIcon );
			icon.image = "/images/flag_sold.png";
			icon.iconSize = new GSize(26, 35);
		} else { // Must be conditionally sold
			icon = new GIcon( baseCSIcon );
			icon.image = "/images/flag_conditionally.png";
			icon.iconSize = new GSize(42, 38);
		}

		// Create marker
		var rectBounds = new GLatLngBounds( new GLatLng(overlay.swLatitude, overlay.swLongtitude), new GLatLng(overlay.neLatitude, overlay.neLongtitude) );
		var point = rectBounds.getCenter();
		marker = new GMarker( point, icon );
		if( (overlay.linksTabContent != undefined && overlay.linksTabContent != "") ||
			(overlay.forSaleTabContent != undefined && overlay.forSaleTabContent != "") ) {
			var tabs = new Array( new GInfoWindowTab( overlay.infoTabLabel, overlay.infoTabContent ) );
			var tabIdx = 0;
			if( overlay.linksTabContent != undefined && overlay.linksTabContent != "" ) {
				tabIdx = tabIdx + 1;
				tabs[tabIdx] = new GInfoWindowTab( overlay.linksTabLabel, overlay.linksTabContent );
			}
			if( overlay.forSaleTabContent != undefined && overlay.forSaleTabContent != "" ) {
				tabIdx = tabIdx + 1;
				tabs[tabIdx] = new GInfoWindowTab( overlay.forSaleTabLabel, overlay.forSaleTabContent );
			}
			GEvent.addListener( marker, "click", function() {
              	          		map.savePosition();
								marker.openInfoWindowTabsHtml( tabs );
								} );
		} else {
			GEvent.addListener( marker, "click", function() {
								map.savePosition();
								marker.openInfoWindowHtml( overlay.infoTabContent );
								} );
		}

		loadedDeedMarkers[ overlay.swLatitude+","+overlay.swLongtitude ] = "loaded";
		loadedMarkersCount = loadedMarkersCount + 1;

	}
	return marker;
}

// Clear the deed boundary overlays that are no longer visible (ie. They are not in the incoming list of deeds).
function clearUnneededOverlays( overlays ) {
	var idx;
	var boundaryIdx;
	var found;
	var deedOverlay;
	var location;
	for( boundaryIdx in loadedDeedOverlays ) {
		found = false;
		location = boundaryIdx.split(",");
		for( idx = 0; idx<overlays.length && !found; idx++ ) {
			deedOverlay = overlays[idx];
			if( location[0] == deedOverlay.swLatitude && location[1] == deedOverlay.swLongtitude &&
				location[2] == deedOverlay.neLatitude && location[3] == deedOverlay.neLongtitude ) found = true;
		}
		if( !found ) {
			if( loadedDeedOverlays[boundaryIdx] != undefined ) {
				map.removeOverlay( loadedDeedOverlays[boundaryIdx] );
				loadedDeedOverlays[boundaryIdx] = undefined;
			}
		}
	}
}

// Format a decimal latitude as a degrees-minutes-seconds display.
function formatLatitude( lat, shortForm ) {
	var signum = lat<0?-1:1;
	var degrees = Math.floor( Math.abs(lat) ) * signum;
	var remainder = Math.abs( lat - degrees );
	var minutes = Math.floor( remainder * 60.0 );
	remainder = remainder*60.0 - minutes;
	var seconds = Math.round( remainder * 60.0 );
	if( seconds == 60 ) {
		minutes = minutes + 1;
		seconds = 0;
	};
	if( minutes == 60 ) {
		degrees = ( Math.abs( degrees ) + 1 ) * signum;
		minutes = 0;
	}
	var direction;
	if( signum < 0 ) {
		direction = south;
	} else {
		direction = north;
	}
	if( shortForm ) 
		return Math.abs(degrees) + "°" + minutes + "'" + direction;
	else {
		degrees = "00" + Math.abs(degrees);
		degrees = degrees.substr( degrees.length-3 );
		minutes = "0" + minutes;
		minutes = minutes.substr( minutes.length-2 );
		seconds = "0" + seconds;
		seconds = seconds.substr( seconds.length-2 );
		return degrees + "° " + minutes + "' " + seconds + '" ' + direction;
	}
}

// Format a decimal longtitude as a degrees-minutes-seconds display.
function formatLongtitude( lng, shortForm ) {
	var signum = lng<0?-1:1;
	var degrees = Math.floor( Math.abs(lng) ) * signum;
	var remainder = Math.abs( lng - degrees );
	var minutes = Math.floor( remainder * 60.0 );
	remainder = remainder*60.0 - minutes;
	var seconds = Math.round( remainder * 60.0 );
	if( seconds == 60 ) {
		minutes = minutes + 1;
		seconds = 0;
	};
	if( minutes == 60 ) {
		degrees = ( Math.abs( degrees ) + 1 ) * signum;
		minutes = 0;
	}
	var direction;
	if( signum < 0 ) {
		direction = west;
	} else {
		direction = east;
	}
	if( shortForm ) 
		return Math.abs(degrees) + "°" + minutes + "'" + direction;
	else {
		degrees = "00" + Math.abs(degrees);
		degrees = degrees.substr( degrees.length-3 );
		minutes = "0" + minutes;
		minutes = minutes.substr( minutes.length-2 );
		seconds = "0" + seconds;
		seconds = seconds.substr( seconds.length-2 );
		return degrees + "° " + minutes + "' " + seconds + '"' + direction;
	}
}

// =========================================== Purchasing ================================================

// Purchase mode is turned on, check if deed is available.
function purchase( point ) {
	document.getElementById('latitude').value = point.lat();
	document.getElementById('longtitude').value = point.lng();
	document.getElementById('center:deedAvailable:latitude').value = point.lat();
	document.getElementById('center:deedAvailable:longtitude').value = point.lng();
	document.getElementById('center:deedAvailable:isDeedAvailable').click();
}

// Deed check has been done, prompt for an optional nick name.
function purchasePrompt() {
    if( document.getElementById('center:deedAvailable:response').value == "true" ) {
		nickNamePrompt(); /* ShoppingCart.jsp */
	}
}

// Nick name has been entered. Add deed clicked on to shopping cart.
function purchaseSubmit( nickName ) {
	document.getElementById('nickName').value = nickName;
	document.getElementById('submitPurchase').click();
}

// =========================================== For Sale ==================================================

// Send the email to the for sale deed owner.
function sendForSaleEmail( certificate ) {
	document.getElementById('center:forSaleEmail:certificate').value = certificate;
	document.getElementById('center:forSaleEmail:emailMessage').value = document.getElementById('emailMessage').value;
	document.getElementById('center:forSaleEmail:sendForSaleEmail').click();
}

function forSaleResults() {
	window.alert( document.getElementById('center:forSaleEmail:response').value );
}

// =========================================== Cookies ===================================================

function createCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function eraseCookie(name) {
	createCookie(name,"",-1);
}

// =================================== Random Header Images =============================================
function swapHeaderImage() {
	var numimages=8;
	headerImages = new Array("../images/header_1.gif","../images/header_2.gif","../images/header_3.gif",
	"../images/header_4.gif","../images/header_5.gif","../images/header_6.gif","../images/header_7.gif","../images/header_8.gif"); 
	logoImages = new Array("../images/logo_1.gif","../images/logo_2.gif","../images/logo_3.gif",
	"../images/logo_4.gif","../images/logo_5.gif","../images/logo_6.gif","../images/logo_7.gif","../images/logo_8.gif"); 
	x=(Math.floor(Math.random()*numimages));
	randomimage=(headerImages[x]);
	randomlogo=(logoImages[x]);
	document.getElementById("header").style.backgroundImage = "url("+ randomimage +")"; 
	document.getElementById("logo").style.backgroundImage = "url("+ randomlogo +")"; 
}

//]]>
