var markers = new Object();
var markerlength = 0;
var map;
var icons = new Array();
var resyncdelay = 0;
var currenticon;
var currentbbox;
var currentzoom;
var plottimer;
var total;
var autodisplay = false;
var startcount = 0;
var firstplot = 1;
var activeOverlays = new String();
var availableOverlays = new Object();
var curfilter = new Object();
var sbcontrol;
var mkopen = 0;
var viewport;

var savedlocation = {lng:-0.1, lat:51.5, zoom:12};
var user = {layers:",eat,drink,tube,train,eventvenue,", jpstart:{}, jpend:{}};

var layerCopyCollection = new GCopyrightCollection('Map');
var layerCopyright = new GCopyright(354, new GLatLngBounds(new GLatLng(-90,-180), new GLatLng(90, 180)),0, "");

var mtypes = {
	eat:{
		onclick:function(mk) {
			$.getJSON("/lib/ajx/getinfo/"+mk.id, function(response) {
				mk.detail = decodeURIComponent(response.detail);
				mk.obj.openInfoWindowHtml('<h4><a href="http://www.thelondonpaper.com/cs/Satellite/london/lcsearch/article/' + mk.id + '?packedargs=suffix%3DArticleController" title="View more details about this venue">' + decodeURIComponent(mk.title) + '</a></h4><div id="poidetail" class="clickable">' + mk.detail + '</div>', {maxWidth:300});
				mkopen = mk.id;
			});
		},
		iconwidth:20,
		iconheight:20,
		iconanchor:[10,10],
		infowindowanchor:[10,10],
		iconfile:'restaurant'
	},
	drink:{
		onclick:function(mk) {
			$.getJSON("/lib/ajx/getinfo/"+mk.id, function(response) {
				mk.detail = decodeURIComponent(response.detail);
				mk.obj.openInfoWindowHtml('<h4><a href="http://www.thelondonpaper.com/cs/Satellite/london/lcsearch/article/' + mk.id + '?packedargs=suffix%3DArticleController" title="View more details about this venue">' + decodeURIComponent(mk.title) + '</a></h4><div id="poidetail" class="clickable">' + mk.detail + '</div>', {maxWidth:300});
				mkopen = mk.id;
			});
		},
		iconwidth:20,
		iconheight:20,
		iconanchor:[10,10],
		infowindowanchor:[10,10],
		iconfile:'barpub'
	},
	eventvenue:{
		onclick:function(mk) {
			$.getJSON("/lib/ajx/getinfo/"+mk.id, function(response) {
				mk.detail = decodeURIComponent(response.detail);
				mk.obj.openInfoWindowHtml('<h4><a href="http://listings.thelondonpaper.com/venue/?pa_id=' + mk.id + '" title="View more details about this venue">' + decodeURIComponent(mk.title) + '</a></h4><div id="poidetail">' + mk.detail + '</div>', {maxWidth:300});
				mkopen = mk.id;
			});
		},
		iconwidth:20,
		iconheight:20,
		iconanchor:[10,10],
		infowindowanchor:[10,10],
		iconfile:'eventvenue'
	},
	train:{
		onclick:function(mk) {
			$.getJSON("/lib/ajx/getinfo/"+mk.id, function(response) {
				mk.detail = decodeURIComponent(response.detail);
				mk.obj.openInfoWindowHtml('<h4>' + decodeURIComponent(mk.title) + '</a></h4><div id="poidetail">' + mk.detail + '</div>', {maxWidth:300});
				mkopen = mk.id;
			});
		},
		iconwidth:20,
		iconheight:20,
		iconanchor:[10,10],
		infowindowanchor:[10,10],
		iconfile:'train'
	},
	cluster:{
		onclick:function(mk) {
			map.setCenter(new GLatLng(mk.lat, mk.lng), (map.getZoom()+1));
		},
		iconwidth:116,
		iconheight:49,
		iconanchor:[58,25],
		infowindowanchor:[0,0],
		iconfile:function(mk) {
			return 'clusters/'+mk.count;
		}
	}
};

function mapMarkerClick(mk) {
	if (mtypes[mk.t].onclick) mtypes[mk.t].onclick(mk);
}

function mapCreateMarker(id) {
	var latlng = new GLatLng(parseFloat(markers[id].lat), parseFloat(markers[id].lng));
	if (typeof mtypes[markers[id].t].iconfile == "function") {
		var iconfile = mtypes[markers[id].t].iconfile(markers[id]);
	} else {
		var iconfile = mtypes[markers[id].t].iconfile;
	}
	if (!icons[iconfile]) {
		var baseicon = mtypes[markers[id].t];
		icons[iconfile] = new GIcon();
		icons[iconfile].image = "/lib/img/markers/"+iconfile+".png";
		icons[iconfile].iconSize = new GSize(baseicon.iconwidth, baseicon.iconheight);
		icons[iconfile].iconAnchor = new GPoint(baseicon.iconanchor[0], baseicon.iconanchor[1]);
		icons[iconfile].infoWindowAnchor = new GPoint(baseicon.infowindowanchor[0], baseicon.infowindowanchor[1]);
	}
	var markerobj = new GMarker(latlng, icons[iconfile]);
	var mark = markers[id];
	GEvent.addListener(markerobj, "click", function() {
		mapMarkerClick(mark);
	});
	markers[id].obj = markerobj;
}

function inMarkerList(theid) {
	if (markers && markers[theid]) return true;
	return false;
}

function mapClearAllMarkers() {
	for (var i in markers) {
		map.removeOverlay(markers[i].obj);
	}
	markerlength = 0;
	markers = new Object();
}

function mapClearMarkersOfType(markertype) {
	for (var i in markers) {
		if (markers[i].t == markertype) {
			map.removeOverlay(markers[i].obj);
			delete(markers[i]);
			markerlength--;
		}
	}
}

function mapClearOverlay(name) {
	map.removeOverlay(availableOverlays[name]);
	var actOverlays = activeOverlays.split(",");
	activeOverlays = "";
	for (var i=0; i<actOverlays.length; i++) {
		if (actOverlays[i]!=name && actOverlays[i].length) {
			activeOverlays += ","+actOverlays[i];
		}
	}
}

// Load a new set of properties
function mapLoadMarkers() {

	// Show waiting message
	$("#waitmsg").html("Refreshing map").show();
	$("#statusline").hide();
	var bounds = map.getBounds();

	// If a plot operation is in progress, cancel it
	if (plottimer) clearTimeout(plottimer);

	// Configure overlays
	var selOverlays = user.layers.split(",");
	for (var i=0; i<selOverlays.length; i++) {
		if (selOverlays[i].length > 0 && availableOverlays[selOverlays[i]]) {
			if (activeOverlays.indexOf(","+selOverlays[i]+",") == -1) {
				activeOverlays += ","+selOverlays[i]+",";
				map.addOverlay(availableOverlays[selOverlays[i]]);
			}
		}
	}
	var actOverlays = activeOverlays.split(",");
	for (var i=0; i<actOverlays.length; i++) {
		if (actOverlays[i].length > 0) {
			if (user.layers.indexOf(actOverlays[i]) == -1) {
				mapClearOverlay(actOverlays[i]);
			}
		}
	}

	// Delete any markers that are now outside the bounding box
	for (var i in markers) {
		if (markers[i].lng < bounds.getSouthWest().lng() || markers[i].lng > bounds.getNorthEast().lng() || markers[i].lat < bounds.getSouthWest().lat() || markers[i].lat > bounds.getNorthEast().lat()) {
			if (markers[i].obj) map.removeOverlay(markers[i].obj);
			delete(markers[i]);
			markerlength--;
		}
	}

	// Set up url to all markers in the current bounding box
	var url = "/lib/ajx/getmarkers?x1=" + bounds.getSouthWest().lng() + "&y1=" + bounds.getSouthWest().lat() + "&x2=" + bounds.getNorthEast().lng() + "&y2=" + bounds.getNorthEast().lat();
		
	// Remember the new bounding box and zoom
	currentbbox = bounds;
	currentzoom = map.getZoom();

	// Add the new centre lat/long and zoom level
	var centre = map.getCenter();
	url += "&xc="+centre.lng()+"&yc="+centre.lat()+"&z="+map.getZoom();

	// Get the new set of markers
 	$.getJSON(url, function(response) {
		total = response.total + markerlength;

		// Add each new marker to the markers array
		var redundantmarkers = new cloneObject(markers);
		if (response.markers) for (var i in response.markers) {
			if (isNaN(i)) continue;
			i = response.markers[i];
			if (!inMarkerList(i.t+i.id)) {
				markers[i.t+i.id] = i;
				markerlength++;
			} else {
				delete redundantmarkers[i.t+i.id];
				total--;
			}
		}
		
		// Remove redundant markers
		for (i in redundantmarkers) {
			if (markers[i].id != mkopen) {
				if (markers[i].obj) map.removeOverlay(markers[i].obj);
				delete(markers[i]);
				markerlength--;
			}
		}

		// Plot the markers
		plottimer = window.setTimeout("mapPlotMarkers(false)", 100);
		allowlayerclear = 1;
	});
}

function mapPlotMarkers(plotfrom) {
	var plotsperiteration = 50;
	var plotsthisiteration = 0;
	var circlerad = 0.00024;
	var zoom = map.getZoom();
	var conflictpx = 20;
	var conflictdistance_lat = conflictpx / Math.pow(2, zoom);
	var conflictdistance_lng = conflictpx / (Math.pow(2, zoom) * 0.77162458338772);
	var newplots = [];
	if (zoom >= 6) for (var i in markers) {
		if (plotfrom) {
			if (i == plotfrom) plotfrom = false;
			plotsperiteration++;
			plotsthisiteration++;
			continue;
		}
		if (!markers[i].obj) {
			delete markers[i].conflictswith;
			var conflicts = false;
			for (var y in markers) {
				if (markers[y].obj && Math.abs(markers[i].lat - markers[y].lat) < conflictdistance_lat && Math.abs(markers[i].lng - markers[y].lng) < conflictdistance_lng) {
					markers[i].conflictswith = y;
					if (markers[y].overlapping) markers[y].overlapping++; else markers[y].overlapping = 1;
					break;
				}
			}
			if (!markers[i].conflictswith) {
				mapCreateMarker(i);
				map.addOverlay(markers[i].obj);

			} else {
				if (zoom > 16) {

					// Plot the marker, but move it slightly:
					var thecircle=1;
					var theang = 6.282/6;
					var theoffset=1;

					if (markers[markers[i].conflictswith].overlapping>6){
						theoffset=7;
						theang = 6.282/12;
						thecircle = 2;
					}

					if (markers[markers[i].conflictswith].overlapping>18){
						theoffset=19;
						theang = 6.282/18;
						thecircle = 3;
					}

					if (markers[markers[i].conflictswith].overlapping>36){
						theoffset=37;
						theang = 6.282/24;
						thecircle = 4;
					}

					theang = (markers[markers[i].conflictswith].overlapping-theoffset) * theang;
					thecircle = thecircle*circlerad;

					dx = thecircle * Math.sin(theang);
					dy = thecircle * Math.cos(theang) * 0.7;

					markers[i].lat = parseFloat(markers[markers[i].conflictswith].lat)+dy;
					markers[i].lng = parseFloat(markers[markers[i].conflictswith].lng)+dx;
					mapCreateMarker(i);
					map.addOverlay(markers[i].obj);
				}
			}
		}
		plotsthisiteration++;
		if (plotsthisiteration >= plotsperiteration) {

			plottimer = window.setTimeout("mapPlotMarkers('"+i+"')", 10);
			return true;
		}
	}

	// If a marker is set to autodisplay, and it has been plotted, highlight it. At the same time,
	// count the number of markers displayed
	var showcount = 0;
	for (var y in markers) {
		if (typeof(markers[y].obj) == "object") {
			showcount++;
			if (markers[y].id==autodisplay) {
				autodisplay = false;
				mapMarkerClick(markers[y]);
			}
		}
	}
	var newsummary = "<strong>"+CommaFormatted(total, ",", "")+" places</strong> &nbsp; "+showcount+" displayed";
	$("#statusline").html(newsummary).show();
	$("#waitmsg").hide();
	firstplot = 0;

	for (var y in markers) {
		if (markers[y]["conflictswith"]) markers[y]["conflictswith"] = NaN;
		if (markers[y]["overlapping"]) markers[y]["overlapping"] = NaN;
	}
}

function mapSyncLocation() {
	resyncdelay = 1;
	map.setCenter(new GLatLng(savedlocation.lat, savedlocation.lng), savedlocation.zoom);
}

function mapNewFilters() {
	mapClearAllMarkers();
	mapLoadMarkers();
}

var allowlayerclear = 1;
function mapMoveEnd(forcereload) {

	// Only load property data if the movement is big enough. Ignore movements of less than 2% of the visible area
	var bounds = map.getBounds();
	var percentmoved_vertically = Math.abs((bounds.getSouthWest().lat()-currentbbox.getSouthWest().lat()) / (currentbbox.getNorthEast().lat()-currentbbox.getSouthWest().lat()));
	var percentmoved_horizontally = Math.abs((bounds.getSouthWest().lng()-currentbbox.getSouthWest().lng()) / (currentbbox.getNorthEast().lng()-currentbbox.getSouthWest().lng()));
	if (percentmoved_vertically < 0.02 && percentmoved_horizontally < 0.02 && map.getZoom() == currentzoom && forcereload!=true) {
		return;
	}
	if (!firstplot) mapLoadMarkers();
}

function mapTLPTileLayer_Tube() {}
mapTLPTileLayer_Tube.prototype = new GTileLayer(layerCopyCollection,11,16);
mapTLPTileLayer_Tube.prototype.isPng = function() { return true; };
mapTLPTileLayer_Tube.prototype.getOpacity = function() { return 1.0 };
mapTLPTileLayer_Tube.prototype.getTileUrl = function(tile,zoom) {
	if (zoom < 11 || zoom > 16) return "";
	return "/lib/img/tm/"+zoom+"/"+tile.x+"/"+((map.getZoom()>=15)?"a":"")+tile.y+".png";
};

function mapControlSpacerTitle() {}
mapControlSpacerTitle.prototype = new GControl();
mapControlSpacerTitle.prototype.initialize = function(map) {
	var container = document.createElement("div");
	container.style.width = "351px";
	container.style.height = "61px";
	map.getContainer().appendChild(container);
	return container;
}
mapControlSpacerTitle.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(20, 0));
}

function mapControlSpacerSidebar() {}
mapControlSpacerSidebar.prototype = new GControl();
mapControlSpacerSidebar.prototype.initialize = function(map) {
	var container = document.createElement("div");
	container.style.width = "254px";
	container.style.height = "297px";
	map.getContainer().appendChild(container);
	return container;
}
mapControlSpacerSidebar.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(0, 30));
}



function mapInit() {

	$("input.hintonblur").each(function(){
		if ($(this).val() == $(this).attr("title")) $(this).css("color", "#aaa");
	});
	$("input.hintonblur").focus(function(){
		if ($(this).val() == $(this).attr("title")) $(this).val("").css("color", "black");
	});
	$("input.hintonblur").blur(function(){
		if ($(this).val() == $(this).attr("title") || !$(this).val()) $(this).val($(this).attr("title")).css("color", "#aaa");
	});

	if (!GBrowserIsCompatible()) {
		//$("#browsernotcompatible").show();
		return;
	}

	if (typeof GMap2 != "function") {
		if (startcount > 10) {
			alert("Loading the map is taking a very long time, which means there is probably a problem.  Try refreshing (press F5 after clicking OK on this message), and if the problem persists, let us know.");
		} else {
			setTimeout(mapInit, 1000);
		}
		startcount++;
		return;
	}

	// Create the GMap
	var m = $("#map").get(0);
	map = new GMap2(m);
	map.addControl(new GLargeMapControl(), new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(10,70)));
	map.addControl(new GScaleControl()); 
	map.addControl(new mapControlSpacerTitle());
	sbcontrol = new mapControlSpacerSidebar();
	map.addControl(sbcontrol);

	map.setCenter(new GLatLng(savedlocation.lat, savedlocation.lng), savedlocation.zoom);
	currentbbox = map.getBounds();

	// Set up tile layers
	layerCopyCollection.addCopyright(layerCopyright);
	availableOverlays["tube"] = new GTileLayerOverlay(new mapTLPTileLayer_Tube());

	// Set up event handlers
	GEvent.addListener(map, "moveend", mapMoveEnd);

	// Set up journey planner sidebar
	if (user.jpstart.id && !user.jpend.id) {
		$("#txtjpstart").val(user.jpstart.postcode);
		$("#txtjpend").val("");
		$("#jpfrom").html(decodeURIComponent(user.jpstart.name));
		$("#jpto").html("Select a destination").css("font-style", "italic");
		$("#frmjp").css("display","block");
	} else if (user.jpend.id) {
		$("#txtjpend").val(user.jpend.postcode);
		if (user.jpstart.id) {
			$("#txtjpstart").val(user.jpstart.postcode);
			$("#jpfrom").html(decodeURIComponent(user.jpstart.name));
		} else {
			$("#txtjpstart").val("");
			$("#jpfrom").html("&nbsp;");
		}
		$("#jpto").html(decodeURIComponent(user.jpend.name)).css("font-style", "normal");
		$("#frmjp").css("display","block");
	}
	if ($("#txtjpend").val() && $("#txtjpstart").val()) {
		$("#lnkjpgo").css("display","inline");
	} else {
		$("#lnkjpgo").css("display","none");
	}

	$("div.filterdialog option").each(function() {
		var filtername = this.parentNode.id;
		if (!curfilter[filtername]) curfilter[filtername] = new Object();
		var fieldname = this.value;
		if (typeof(curfilter[filtername][fieldname]) == "undefined") {
			curfilter[filtername][fieldname] = this.selected;
		}
	});

	resizeHandler();

	mapLoadMarkers();
}

$(document).ready(mapInit);

window.onunload=GUnload;





function togglesidebar() {
	if ($("#sidebarcontainer").outerWidth() > 200) {
		$("#sidebarcontainer").animate({width:27}, "slow");
		$("#lnkclosesidebar").css("display","none");
		$("#lnkopensidebar").css("display", "inline");
		map.removeControl(sbcontrol);
	} else {
		$("#sidebarcontainer").animate({width:254}, "medium");
		$("#lnkclosesidebar").css("display", "inline");
		$("#lnkopensidebar").css("display","none");
		map.addControl(sbcontrol);
	}
	$("#lnkclosesidebar").get(0).blur();
}

function updatelayers() {
	var layers = new Array();
	$("#frmlayers .layerselect input").each(function() {
		if (this.checked) layers[layers.length] = this.name;
	});
	var newlayers = ","+layers.join(",")+","
	if (newlayers != user.layers) {
		user.layers = newlayers;
		$.post("/lib/ajx/setlayers", {layers:layers.join(",")}, mapLoadMarkers);
	}
}

function showFilter(filname) {
	closefilterdialogs();
	$("#dlgfil"+filname).show();
	var st = window.pageYOffset | document.body.scrollTop;
	$("#modalbg").css("display", "block").css("top", st+"px");
	centreDialog($("#dlgfil"+filname));
}

function centreDialog(jqo) {
	jqo.css("left", ((viewport.width-jqo.outerWidth())/2)+"px").css("top", Math.max(5, $(document).scrollTop()+((viewport.height-jqo.outerHeight())/2))+"px");
}

function updatefilters() {
	var filters = new Object();
	$(".filterdialog input").each(function() {
		var n = this.name;
		if (!filters[n]) filters[n] = new Array();
		if (this.checked && this.value) filters[n][filters[n].length] = this.value;
	});
	for (var i in filters) filters[i] = filters[i].join(",");
	filters.eventtype = new Array();
	$("#eventtypefilters input").each(function() {
		if (this.checked && this.value) filters.eventtype[filters.eventtype.length] = this.value;
	});
	filters.eventtype = filters.eventtype.join(",");
	$.getJSON("/lib/ajx/setfilters", filters, function(response) {
		for (i in response) $("#fil"+i).html(decodeURIComponent(response[i]));
		mapLoadMarkers();
	});
	closefilterdialogs();
}

function filterchange(el) {
	var filtername = el.name;
	if (el.checked && el.value=="all") {
		$("#dlgfil"+filtername+" input").each(function() {
			if (this.value != "all") this.checked = false;
		});
	} else if (el.checked && el.value != "all") {
		$("#opt"+filtername+"all").get(0).checked = false;
	}
}

function closefilterdialogs() {
	$(".filterdialog").hide();
	$("#modalbg").css("display", "none");
}

function dosearch(p) {
	if (isNaN(p)) p = 1;
	var q = $("#txtsearch").val();
	if (!q || q=='venue or street name') {
		alert("Please enter something to search for");
		$("#txtsearch").get(0).focus();
	}
	$.getJSON("/lib/ajx/search?q="+encodeURIComponent(q)+"&p="+p, function(response) {
		if (!response.count && p==1) {
			alert("Sorry, we couldn't find that location");
			$("#txtsearch").get(0).focus();
		} else if (!response.count) {
			alert("There are no more results");
			$("#txtsearch").get(0).focus();
		} else if (response.count == 1) {
			clearsearch();
			var coords = decodeURIComponent(response.results[0].p).split(",");
			mapGoto(coords[0],coords[1],17,decodeURIComponent(response.results[0].id),decodeURIComponent(response.results[0].t));
		} else {
			var html = "Search results:<ol class=\"searchresults\" start=\""+(((p-1)*7)+1)+"\">";
			for (r in response.results) {
				if (response.results[r].p) {
					html += "<li><a href=\"javascript:void(0)\" onclick=\"mapGoto("+decodeURIComponent(response.results[r].p)+", 17, '"+decodeURIComponent(response.results[r].id)+"', '"+decodeURIComponent(response.results[r].t)+"')\">"+decodeURIComponent(response.results[r].n)+"</a><br/>"+decodeURIComponent(response.results[r].a)+"</li>";
				}
			}
			html += "</ol>";
			if (p>1) html += "<a href=\"javascript:void(0)\" onclick=\"dosearch("+(p-1)+")\">&lt; Previous</a> &nbsp;";
			if (response.count==7) html += "<a href=\"javascript:void(0)\" onclick=\"dosearch("+(p+1)+")\">Next &gt;</a> &nbsp;";
			html += "<a href=\"javascript:void(0)\" onclick=\"clearsearch()\">Clear search</a>";
			$("#sbsearchresults").html(html).show();
			$("#sbnormal").hide();
		}
	});
}

function mapGoto(lng, lat, zm, id, t) {
	if (id) autodisplay = id;
	if (t && user.layers.indexOf(","+t+",") == -1) {
		$("#chk"+t).check();
		updatelayers();
	}
	setTimeout("map.setCenter(new GLatLng("+lat+", "+lng+"), "+zm+");", 100);
}

function clearsearch() {
	$("#sbsearchresults").hide();
	$("#sbnormal").show();
}

function addJPwaypoint(id, linkobj, type) {
	$(linkobj).get(0).blur();
	$.getJSON("/lib/ajx/addwaypoint?id="+encodeURIComponent(id)+"&type="+encodeURIComponent(type), function(response) {
		if (response.msg) {
			alert(msg);
		} else {
			$("#frmjp").css("display","block");
			var txfrtarget = ($("#sidebarcontainer").outerWidth() > 200) ? "frmjp" : "lnkopensidebar";
			$(linkobj).TransferTo({className:'transferer',to:txfrtarget,duration:600,complete:function(to) { 
				if (response.type == "start") {
					user.jpstart = response.waypoint;
					$("#txtjpstart").val(user.jpstart.postcode);
					$("#jpfrom").html(decodeURIComponent(user.jpstart.name));
				} else {
					user.jpend = response.waypoint;
					$("#txtjpend").val(user.jpend.postcode);
					$("#jpto").html(decodeURIComponent(user.jpend.name)).css("font-style", "normal");
					$("#lnkjpgo").css("display","inline");
				}
				if ($("#txtjpend").val() && $("#txtjpstart").val()) {
					$("#lnkjpgo").css("display","inline");
				} else {
					$("#lnkjpgo").css("display","none");
				}
			}});
		}
	});
}
function clearJProute() {
	$.get("/lib/ajx/clearwaypoints");
	user.jpstart = {};
	user.jpend = {};
	$("#frmjp").css("display","none");
	$("#jpfrom").html("&nbsp;");
	$("#jpto").html("&nbsp;");
	$("#txtjpend").val("");
	$("#txtjpstart").val("");
}
function showJProute() {
	$("#frmjp").get(0).submit();
}

function resizeHandler() {
	var e = document.documentElement || {},
		b = document.body || {},
		w = window;

	viewport = {
		width: min( e.clientWidth, b.clientWidth, w.innerWidth ),
		height: min( e.clientHeight, b.clientHeight, w.innerHeight )
	};
	
	function min() {
		var v = Infinity;
		for( var i = 0;  i < arguments.length;  i++ ) {
			var n = arguments[i];
			if( n && n < v ) v = n;
		}
		return v;
	}
}

function CommaFormatted(amount, delimiter, symbol) {
	var amountstr = amount+"";
	var a = amountstr.split('.',2);
	var i = parseInt(a[0]);
	if(isNaN(i)) { return ''; }
	var minus = '';
	if(i < 0) { minus = '-'; }
	i = Math.abs(i);
	var n = new String(i);
	var b = [];
	while(n.length > 3) {
		var nn = n.substr(n.length-3);
		b.unshift(nn);
		n = n.substr(0,n.length-3);
	}
	if(n.length > 0) { b.unshift(n); }
	n = b.join(delimiter);
	if (a.length == 1) { amount = n; }
	else { amount = n + '.' + a[1]; }
	amount = minus + symbol + amount;
	return amount;
}

function cloneObject(what) {
    for (i in what) {
        this[i] = what[i];
    }
}

jQuery.fn.extend({
	check: function(shouldcheck) {
		if (typeof(shouldcheck) == "undefined") shouldcheck = true;
		return this.each(function() { this.checked = shouldcheck; });
	},
	uncheck: function() {
		return this.each(function() { this.checked = false; });
	}
});

$(window).resize(resizeHandler);

