// GP GeoForum - https://sourceforge.net/projects/geoforum
// $RCSfile: gp.js,v $
// $Author: evilc $
// $Revision: 1.213 $
// $Date: 2006/04/18 11:53:03 $

// Main Javascript functions file.

browsercrap=false;	// set to 1 if non-compliant browser (ie IE)
widestyle=false;	// holds string to make something 100% wide if a compliant browser

// ================================== INIT GLOBALS START ==============================
pointlist=false;	// holds sidebar html for points list
searchlist=false;	// holds sidebar HTML for search list
last_overlay=false;	// copy of overlay if it needs to go global

// UID Variables - Used to enable discarding of old AJAX replies
mainUID = 0;		// holds ID for main AJAX request. 
infoUID = 0;		// holds ID for infowindow AJAX request.
editUID = 0;		// holds ID for click icon in edit mode AJAX request.

// ============ MARKERS, LINES & ICONS ===============
markers = new Array();		// markers array - an array of GMarkers
// If a line is to be drawn, a marker is plotted too.
// markers[x].polyline is a index value for the polyline array
polylines = new Array();		// polylines array - an array of GPolylines
icons = new Array();	// holds the main icons
// icon array can be accessed like:
//icons[0].loc.point.edit;
//icons[0]['loc']['point']['edit']
addmarker = false;	// global var holds marker object of point being added / edited
endmarker=false;		// endmarker of the line being edited
editPoly=false;		// global var holds polyline object for edit line
regrabPoly=false;	// holds the re-grab (green) box
cachePoly=false;	// holds the cache (red) box

// Edit location items
selected_location=false;	// set to the location_id (db index) of the existing location being edited

editpath=new Array();	// editpath is an important variable, it holds the point(s) of anything being edited
// It holds arrays of coordinats, so editpath[0][0] is the lng of the first item, editpath[0][1] is the lat of the first item
// in point mode, index 0 will be the original location, index 1 the proposed new one
// in line mode, index 0 is the first point of the proposed new line, index 1 the second, etc...
hiddenEditMarker = false;	// If editing a marker, a copy of the markers entry in the markers[] array is put in here.

regionmoline=false;		// GPolyline object of the region mouseover currently being displayed.

// ====================== VIEW HISTORY RELATED GLOBALS ===================
view_history = [];	// view history is an array of previous locations. Sort of like a browser history
zoomThrough=false;	// set to name of a region if you zoom through it. For view history


// ========================= STATE INDICATING GLOBALS ==================
aplisten=false;	// holds pointer to map click listener for edit mode. Used to remove listener when leaving edit mode
valid_region=0;	// set to 1 if user has rights to add a point in currently selected region in Edit mode.
infoOpened = false;	// set to true when an info window is opened. If opened and map moves as a result, re-render is not called.
sideheader_on=false;
sidefooter_on=false;
currentcategory=0;	// holds the current category
mistatus=false;	// whether the mouse is "in" or "out"
// because mouseover can be fetched by AJAX, the mouse could be out again before we need to plot...

currentmode=0;	// current GP mode. Will be set to one of the following constants:
GP_VIEW_MODE = 1;
GP_EDIT_MODE = 2;
GP_PROFILE_MODE = 3;
GP_SETTINGS_MODE = 4;

GP_POINT_TYPE = 0;
GP_LINE_TYPE = 1;

currentviewmode = 0;	// current sub-mode within view mode. Will be set to one of the following constants.
GP_VIEW_HELP_MODE = 1;
GP_VIEW_POINTLIST_MODE = 2;
GP_VIEW_SEARCH_MODE = 3;

// ========================= DIV HOLDING GLOBALS ========================
edit_html=[];	//	contains HTML for edit box.


// ========================== COORDINATE HOLDING GLOBALS ===================
last_center=false;	// last centre of the map. used to determine if map actually moved during mapmoved event. Clicking will call mapmoved as well as dragging...
last_bounds=false;	// The bounds the last time the map was dragged. If we get up to 2 screens away, then when map is dragged, if new map centre
					// is within these bounds, no real need to grab points again. Saves on server traffic.
					// todo: Plot a polyline showing the last_bounds box in green and the edged of the cached area (2 screens away) as red
					// then the user knows if they drag inside the green box no refresh is needed. and they will also know no points will be showing
					// outside the red box.
last_zoom=false;	// the last zoom level
cacheBounds=false;	// holds the bounds to pull points from
grabBounds=false;	// if the center moves outside these bounds, re-grab
grabScale=1.0;	// grab area as a factor of the bounds area
cacheScale=1.5;	// how many screens worth to grab (0= just what is on screen, 1 = one extra screen, 2 = 2 extra screens)

// ============================= BUTTONS ====================================
// set up button arrays. index [0] is the element to program, index [1] is the button html
add_button=['document.getElementById("div_add_button").innerHTML','<input type="button" class="button" value="'+gp_lang['add']+'" name="PointSubmit" onclick="pointSubmit();">'];
edit_button=['document.getElementById("div_edit_button").innerHTML','<input type="button" class="button" value="'+gp_lang['edit']+'" name="PointUpdate" onclick="pointUpdate();">'];
delete_button=['document.getElementById("div_delete_button").innerHTML','<input type="button" class="button" value="'+gp_lang['delete']+'" name="PointDelete" onclick="pointDelete();">'];
reset_button=['document.getElementById("div_reset_button").innerHTML','<input type="reset" class="button" value="'+gp_lang['reset']+'" name="PointReset" onclick="pointReset();">'];

// ================================== INIT GLOBALS END ==============================


// ************************************** FUNCTIONS START *********************************************

function loadingPane(channel,message){
	if (!isset(messages)){
		var messages = new Array();		// init array for loading messages
	}
	
	messages[channel]=message;
	// init any vars that aren't set to make comparisons easier
	if (!messages['init']){
		messages['init']='';
	}
	if (!messages['plot']){
		messages['plot']='';
	}
	var tmpstr = '';
	if (messages['init'] != ''){	// if there is an initialising message
		tmpstr += messages['init']+"<br>";
	}
	if (messages['plot'] != ''){	// if there is an plotting message
		tmpstr += messages['plot']+"<br>";
	}
	document.getElementById("div_loading").innerHTML = '<div style="width: 200px align:left" class="forumline gen"><b>'+tmpstr+'</b></div>';
	if (messages['init'] != '' || messages['plot'] != ''){
		document.getElementById("div_loading").style.visibility="visible";
	} else {
		document.getElementById("div_loading").style.visibility="hidden";
	}
}

// ====================================================== initMap() ======================
// initialises the map
function initMap(){
	var btemp = navigator.appName;
	if (btemp == "Microsoft Internet Explorer"){
		browsercrap = 1;
		widestyle = "";
	} else if (btemp == "Netscape"){
		browsercrap = 0;
		widestyle = ' style="width:100%" ';
	} else {
		browsercrap = 1;
		widestyle = "";
	}

	// find out if it is new (post 2.35 API)
	// this version uses .x instead of .latDegrees...
	// and uses map.closeInfoWindow() not closeInfoWindow() to close IWs
	newapi=false;
	if (apiver == "2"){
		newapi=true;
	} else {
		var tmp = apiver.split(".");
		if (tmp[0] == "2"){
			if (tmp[1] >= "36"){
				newapi=true;
			}
		} else if (tmp[0] > 2){
			newapi=true;
		}
	}
	
	// process stuff coming from PHP
	
	// set user level
	if (userdata['user_level'] == 1){
		isAdmin=true;
	} else {
		isAdmin=false;
	}
	
	// set geospatial extensions
	if (isset(settings['mysql_41_geo'])){
		mge_enabled = settings['mysql_41_geo'];
	} else {
		mge_enabled = 1;
	}
	
	// set subquery mode
	if (isset(settings['use_subqueries'])){
		use_subqueries = settings['use_subqueries'];
	} else {
		use_subqueries = 1;
	}
	
	// set sql big selects mode
	if (isset(settings['big_selects'])){
		big_selects = settings['big_selects'];
	} else {
		big_selects = 0;
	}

	// Assemble standard options for use in query strings
	queryOptions = "geo="+mge_enabled+"&subq="+use_subqueries+"&bigsel="+big_selects;
		
	// Set profile vars to blank if unset
	if (!isset(profile['default_lng'])){
		profile['default_lng']="";
	}
	if (!isset(profile['default_lat'])){
		profile['default_lat']="";
	}
	if (!isset(profile['default_zoom'])){
		profile['default_zoom']="";
	}
	if (!isset(profile['default_region'])){
		profile['default_region']="";
	}
	
	// Set up DIVs
	document.getElementById("div_region_cont").innerHTML = '<center><div style="width:90%">'+gp_lang['region_filter']+':&nbsp<form name="form_regionselect"><div id="div_regions"></div></form></div></center>';
	document.getElementById("div_category_cont").innerHTML = '<center><div style="width:90%">'+gp_lang['category_filter']+':&nbsp<form name="form_categoryselect"><div id="div_categories"></div></form></div></center>';
	document.getElementById("div_mode_cont").innerHTML = '<center>'+gp_lang['mode']+':&nbsp</center><div id="div_modeselect"></div>';
	document.getElementById("div_sidepanel_cont").innerHTML = '<div id="div_sideheader"></div><div id="div_sidepanel" class="bodyline gensmall" style="width: 100%; height: 100%; overflow:auto"></div><div id="div_sidefooter" class="gensmall"></div>';

	// Init Map
	decho ("Entering initMap");
	if (!isset(GMap)) {
		maploaded=false;
	} else {
		//map = new GMap(document.getElementById("div_map")); // create map
		var mapload='map = new '+gmaptype+'(document.getElementById("div_map"))';
		eval(mapload);
		map.addControl(new GLargeMapControl());	// zoom control
		map.addControl(new GMapTypeControl());	// map / satellite buttons
		map.addControl(new GScaleControl());	// scale bar
		maploaded=true;
	}
	if (no_map==1){
		maploaded=false;	// do not load map and plot markers - let user get to settings mode
	}
	window.onresize= winResize;
	winResize();

	// set up loading pane
	var tip = document.createElement("div");
	tip.setAttribute("id","div_loading");
	// move it to the map div
	document.getElementById("div_map").appendChild(tip);
	var pos = new GControlPosition(G_ANCHOR_BOTTOM_LEFT, new GSize((map.getSize().width/2)-100,map.getSize().height/2));
	pos.apply(document.getElementById("div_loading"));
	// hide it
	tip.style.visibility="hidden";
	
	loadingPane('init',gp_lang['loading_initialising']);
	
	// set up search window
	searchlist = '<table border=1 cellpadding=0 cellspacing=0 width="100%"><tr><td class="row2"><center><font size=3><b>'+gp_lang['viewmode']+" : "+gp_lang['search']+'</b></font><br></td></tr></table>';
	
	// start location search form
	searchlist += '<form name="form_search_gp" action="javascript:searchLocs(document.form_search_gp.words.value)">';
	searchlist += '<table width="100%" border=0 cellpadding=0 cellspacing=0 class="gensmall">';
	searchlist += '<th colspan=3>'+gp_lang['search_gp']+'&nbsp;&nbsp';
	searchlist += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'search_loc_help\')">';
	searchlist += '</th>';
	searchlist += '<tr><td colspan=3><div class="row2" style="display:none" id="search_loc_help"><i>'+gp_lang['search_loc_help']+'</i></div></tr></td>';
	searchlist += '<tr><td width="70%"><input type="text" name="words" class="input"/></td>';
	searchlist += '<td width="30" align="right"><input type="submit" class="button" value="'+gp_lang['search']+'"></td></tr>';
	//searchlist += '<tr><td colspan=3><div id="div_geocode"></div></td></tr>';
	//searchlist += '<tr><td colspan=3>';
	searchlist += '</table></form>';


	// Start Geocoder Search form
	searchlist += '<form name="form_search_geo" action="javascript:searchGeo(document.form_search_geo.select_geocode_search.value,document.form_search_geo.txt_geocode_words.value);">';
	searchlist += '<table width="100%" border=0 cellpadding=0 cellspacing=0 class="gensmall">';
	searchlist += '<th colspan=3>'+gp_lang['search_geocode']+'&nbsp;&nbsp';
	searchlist += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'search_geo_help\')">';
	searchlist += '</th>';
	searchlist += '<tr><td colspan=3><div class="row2" style="display:none" id="search_geo_help"><i>'+gp_lang['search_geo_help']+'</i></div></tr></td>';
	
	searchlist += '<select name="select_geocode_search" '+widestyle+'>';
	searchlist += '<option value="ws.geonames.org-fulltext">ws.geonames.org - Worldwide locations - Full Text';
	searchlist += '<option value="ws.geonames.org-postcodes">ws.geonames.org - Worldwide Postal Codes';
	searchlist += '</select>';
		
	searchlist += '<table border=0 width="100%">';
	searchlist += '<tr><td>';
	searchlist += '<input type="text" class="input" name="txt_geocode_words"/>';
	searchlist += '</td><td align="right">';
	searchlist += '<input type="button" class="button" value="'+gp_lang['search']+'" onClick="searchGeo(document.form_search_geo.select_geocode_search.value,document.form_search_geo.txt_geocode_words.value);"/>';		
	searchlist += '</td></tr>';
	searchlist += '</table>';
	
	searchlist += '</td></tr>';
	searchlist += '</table></form>';
	searchlist += '<div id="div_results"></div>';
	
	if (maploaded){
		map.setCenter(new GLatLng(0,0),0);	// map needs to be somewhere else stuff fails
		//	Init Globals
		if (last_bounds==false){	// initialise last_bounds
			last_bounds=map.getBounds();
		}
		if (last_center==false){	// initialise last_center
			last_center = map.getCenter();
		}
		if (last_zoom == false){
			last_zoom=map.getZoom();
		}
		
		// set up marker mouseover tooltip
		tooltip = document.createElement("div");
		tooltip.setAttribute("id","div_marker_tooltip");
		// move it to the map div
		map.getPane(G_MAP_FLOAT_PANE).appendChild(tooltip);
		tooltip.align="left";
		// hide it
		tooltip.style.visibility="hidden";

		
		// Create Icons
		// set up main icons
		var baseIcon = new GIcon();
		baseIcon.iconSize = new GSize(21, 28);
		baseIcon.shadowSize = new GSize(36, 28);
		baseIcon.iconAnchor = new GPoint(11, 28);
		baseIcon.infoWindowAnchor = new GPoint(9, 2);
		baseIcon.infoShadowAnchor = new GPoint(18, 25);
		//baseIcon.image = "images/gp/icons/base/marker-error.png";	// default marker to see if any of them arent working.
		//baseIcon.shadow = "images/gp/icons/base/marker-shadow.png";
		
		// populate icons array
		for (var i=0;i<categories.length;i++){
			//baseIcon.image = "images/gp/icons/"+categories[i][2];
			var icondir = "images/gp/icons/"+categories[i][2]+"/";
			var cattmp=new Array('loc','bunch');
			// loc tree
			var icontmp = new Array('point','line');	// array of icons for bunch points
			icontmp.line = new Array ('noedit','edit');
			icontmp.point = new Array ('noedit','edit');
			icontmp.line.edit=new GIcon(baseIcon);
			icontmp.line.edit.image = icondir+"marker-l-e1.png";
			icontmp.line.edit.shadow = icondir+"marker-shadow.png";
			icontmp.line.noedit=new GIcon(baseIcon);
			icontmp.line.noedit.image = icondir+"marker-l-e0.png";
			icontmp.line.noedit.shadow = icondir+"marker-shadow.png";
			icontmp.point.edit=new GIcon(baseIcon);
			icontmp.point.edit.image = icondir+"marker-p-e1.png";
			icontmp.point.edit.shadow = icondir+"marker-shadow.png";
			icontmp.point.noedit=new GIcon(baseIcon);
			icontmp.point.noedit.image = icondir+"marker-p-e0.png";
			icontmp.point.noedit.shadow = icondir+"marker-shadow.png";
			cattmp.loc=icontmp;
			
			// bunch tree
			icontmp = new Array('nochild','child');	// array of icons for bunch points
			icontmp.child = new Array ('noedit','edit');
			icontmp.nochild = new Array ('noedit','edit');
			icontmp.child.edit=new GIcon(baseIcon);
			icontmp.child.edit.image = icondir+"marker-b1-e1.png";
			icontmp.child.edit.shadow = icondir+"marker-shadow.png";
			icontmp.child.noedit=new GIcon(baseIcon);
			icontmp.child.noedit.image = icondir+"marker-b1-e0.png";
			icontmp.child.noedit.shadow = icondir+"marker-shadow.png";
			icontmp.nochild.edit=new GIcon(baseIcon);
			icontmp.nochild.edit.image = icondir+"marker-b0-e1.png";
			icontmp.nochild.edit.shadow = icondir+"marker-shadow.png";
			icontmp.nochild.noedit=new GIcon(baseIcon);
			icontmp.nochild.noedit.image = icondir+"marker-b0-e0.png";
			icontmp.nochild.noedit.shadow = icondir+"marker-shadow.png";
			cattmp.bunch=icontmp;
	
			icons[i]=cattmp;	// add to main array
		}
		
		// set up "temp" icons - icons used when adding or editing points
		var tempIcon = new GIcon();
		tempIcon.shadow = "images/gp/icons/base/shadow-temp.png";
		tempIcon.iconSize = new GSize(13, 20);
		tempIcon.shadowSize = new GSize(36, 20);
		tempIcon.iconAnchor = new GPoint(7, 19);
		tempIcon.infoWindowAnchor = new GPoint(9, 2);
		tempIcon.infoShadowAnchor = new GPoint(18, 25);
		
		start_icon=new GIcon(tempIcon);
		start_icon.image="images/gp/icons/base/marker-t0.png";
		
		end_icon=new GIcon(tempIcon);
		end_icon.image="images/gp/icons/base/marker-t1.png";
		// set up the mode select (View / Edit) buttons
		//var modebuttons='<form name="form_modeselect"><table class="gensmall" border=0><tr><td>';
		var modebuttons='<form name="form_modeselect">';
		// Add settings button if admin
		if (isAdmin){	// phpBB admin
			modebuttons+='<input type="radio" name="radio_modebutton" value="Settings" onclick="viewMode('+GP_SETTINGS_MODE+');">'+gp_lang['settings'];
		}
		// add view button
		modebuttons+='<input type="radio" name="radio_modebutton" id="radio_modebutton" class="input" value="View" onclick="viewMode('+GP_VIEW_MODE+');" checked>'+gp_lang['view']+'&nbsp;&nbsp;';
		if (userdata['session_logged_in']==1){	// logged in - regular edit button
			modebuttons+='<input type="radio" name="radio_modebutton" value="Edit" onclick="viewMode('+GP_EDIT_MODE+');" >'+gp_lang['edit'];
			modebuttons+='&nbsp;&nbsp;<input type="radio" name="radio_modebutton" value="Profile" onclick="viewMode('+GP_PROFILE_MODE+');">'+gp_lang['profile'];
		} else {	// not logged in - disabled edit button
			modebuttons+='<input type="radio" name="radio_modebutton" value="Edit" onclick="document.form_modeselect.radio_modebutton[0].checked=true;userMessage(\''+gp_lang['log_in_to_edit']+'\');" >'+gp_lang['edit'];
		}
		modebuttons+='</form>';
		document.getElementById("div_modeselect").innerHTML = modebuttons;
		
		// set default view mode sub-mode
		if (settings['showhelp_status'] == 1){
			currentviewmode = GP_VIEW_HELP_MODE;
		} else {
			currentviewmode = GP_VIEW_POINTLIST_MODE;
		}
		
		//var infoOpened = false;	// set to true when an info window is opened. If opened and map moves as a result, re-render is not called.
		// ================= click LISTENER ===========
		GEvent.addListener(map, "click", function(overlay, point) {
			if (overlay) {		// MARKER CLICKED
				if (currentmode == GP_VIEW_MODE){
					if (!overlay.temp){// if a proper marker not a temp one
						infowindowMain(overlay.markerindex);	// load infowidow if needed and display
				    }
		    	} else if (currentmode == GP_EDIT_MODE){
					if (overlay.temp){
						clickTempMarker(overlay);
					} else {
						clickLocMarker(overlay);
					}
				} else if (currentmode == GP_SETTINGS_MODE){
					infowindowMain(overlay.markerindex);
				}
			} else if ((point)) {	// BACKGROUND CLICKED
				if (currentmode == GP_EDIT_MODE){
					clickBackground(point);
				}
			}
		});      
		// ================= infoOpened LISTENER ===========		
		GEvent.addListener(map, "infowindowopen", function() {
			infoOpened = true;	// set infoOpened to true to stop map move re-rendering view
			//infoOpened = false;	// set infoOpened to true to stop map move re-rendering view
		});
		/*
		// ================= infoClosed LISTENER ===========
		GEvent.addListener(map, "infowindowclose", function() {
			infoOpened = false;	// set infoOpened to false
		});
		*/
		
		// ================= mapMoved LISTENER =============
		GEvent.addListener(map, "move", function () {
			// remove any region mouseovers that may have got "stuck"
			if (regionmoline.length){
				for (var i=0;i<regionmoline.length;i++){
					map.removeOverlay(regionmoline[i]);
				}
			}
					
			// Hide tooltip that may have gotten "stuck"
			tooltip.style.visibility="hidden"
		});
		
		// ================= moveEND LISTENER =============
		// Called at the END of a move.
		GEvent.addListener(map, "moveend", function () {
			var center = map.getCenter();
			bounds = map.getBounds();
			var zoom = map.getZoom();
			var tc=new Array();
			if (isset(center.lngDegrees)){
				tc.lngDegrees=center.lngDegrees;
				tc.latDegrees=center.latDegrees;
			} else {
				tc.lngDegrees=center.x;
				tc.latDegrees=center.y;
			}
			center=tc;
			if (!(center.lngDegrees == last_center.lngDegrees && center.latDegrees == last_center.latDegrees && zoom == last_zoom)){	// view changed, even just a little bit
				if (!infoOpened){	// don't add to history if the infowindow is openeing - it's an involuntary move
					var div_history=gp_lang['move_history']+': ';
					if (view_history.length > 10){
						view_history.shift();
					}
					if (zoomThrough != false){
						var tag = zoomThrough;
						zoomThrough = false;
					} else {
						if (view_history.length==0){
							var tag = "Start";
						} else {
							var tag = "move";
						}
					}
					view_history[view_history.length]=new Array(center.lngDegrees,center.latDegrees,zoom,tag);
					for (var j=0; j < view_history.length-1; j++){
						if (j){
							div_history += " -> ";
						}
						div_history += '<a href="javascript:goHistory('+j+');">'+view_history[j][3]+'</a>';
					}
					div_history += '';
					document.getElementById("div_history").innerHTML = div_history;
				} else {
					//decho ("mapMoved ? setting infoopened to false");
					//infoOpened=false;
				}
				
				document.getElementById("msg_coords").innerHTML = sprintf(gp_lang['map_center_output'],['<a  target="_blank" href="?action=seek&seekmode=coords&lng='+rndVar(center.lngDegrees)+'&lat='+rndVar(center.latDegrees)+'&zoom='+zoom+'">','</a>',rndVar(center.lngDegrees),rndVar(center.latDegrees),zoom]); // do it the first time
				//!scaleBounds(last_bounds,grabScale).contains(map.getCenter())
				if (!last_bounds.contains(map.getCenter()) || zoom != last_zoom ){
					// translation: TRUE IF: The new centre is not within the old bounds, OR the zoom level changed
					if( infoOpened == true ) {
						infoOpened = false; 
						decho ("plotting aborted due to infoOpened being true");
						//return; 
					} else {
						//beep();
						plotVisibleMarkers();
					}
				}
			}
			last_center=center;
			//last_bounds=bounds;	// reset inside plot VisibleMarkers NOT here.
			last_zoom=zoom;
		});
		// set view mode
		if (no_map == 1){	// map not showing
			if (isAdmin){	// phpBB admin ?
				viewMode(GP_SETTINGS_MODE);	// force to settings mode.
			}
		} else {
			viewMode(GP_VIEW_MODE);
		}
		
		// Seek to wherever has been asked (default setting, user profile setting)
		// Does not handle URL seeking, that is handled elsewhere.
		// Avoids changing region if URL seek set
		
		var default_view_set=0;
		var default_region_set=0;
		if (seek_id == 0){	// seek_id > 0 means seeking a location, -1 means seeking coords, 0 means no seek
			// check if user has preferred view
			if (!isempty(profile['default_lat']) && !isempty(profile['default_lng']) && !isempty(profile['default_zoom'])){
				default_view_set=1;
				seek_lat=+profile['default_lat'];
				seek_lng=+profile['default_lng'];
				seek_zoom=+profile['default_zoom'];
			// if not, check if admin set default view
			} else if (!isempty(settings['default_lat']) && !isempty(settings['default_lng']) && !isempty(settings['default_zoom'])){
				default_view_set=1;
				seek_lat=+settings['default_lat'];
				seek_lng=+settings['default_lng'];
				seek_zoom=+settings['default_zoom'];
			}
			
			// check if user has preferred region		
			if (!isempty(profile['default_region'])){
				default_region_set=1;
				seek_region=+profile['default_region'];
			// if not, check if admin set default region
			} else if (!isempty(settings['default_region'])){
				default_region_set=1;
				seek_region=+settings['default_region'];
			}
		} else { // seek by URL
			if (!isempty(seek_lat) && !isempty(seek_lng) && !isempty(seek_zoom)){
				default_view_set=1;
				seek_lat=+seek_lat;
				seek_lng=+seek_lng;
				seek_zoom=+seek_zoom;
			}
			
			if (!isempty(seek_region)){
				default_region_set=1;
			}
		}
		if (isempty(seek_region)){
			seek_region=0;
		}

		// seek to default location if specified.
		if (default_view_set==1){
			map.setCenter(new GLatLng(seek_lat,seek_lng),seek_zoom);
			var regionmode=2;	// do not seek on region load
		} else {
			var regionmode=1;	// seek on region load
		}
		// populate regions box
		if (seek_id != 0){	// if link specified
			getRegions(-1,2,"form_regionselect","select_regionselect","div_regions",'');	// do not centre on region
			plotVisibleMarkers();	// will open infowindow etc.
		} else {
			//getRegions(-1,1,"form_regionselect","select_regionselect","div_regions",'');	// centre on region
			getRegions(seek_region,regionmode,"form_regionselect","select_regionselect","div_regions",'');	// centre on region
		}
		getCategories(0,2,1,"form_categoryselect","select_categoryselect","div_categories");
		decho ("Exiting initMap");
	} else {
		if (isAdmin){
			window.location="gp_admin.php";	// redirect to admin settings page
			//viewMode(GP_SETTINGS_MODE);
		} else {
			userMessage (gp_lang['incorrect_config']);
		}
	}
	loadingPane('init',"");
}

// Does a search on an online geocoding engine
function searchGeo(site, words){
	//this
	if (site == "ws.geonames.org-fulltext"){
		var urlstr = 'http://ws.geonames.org/search?q='+escapePlus(words)+'&maxRows=10';
	} else if (site == "ws.geonames.org-postcodes"){
		var urlstr = 'http://ws.geonames.org/postalCodeSearch?postalcode='+escapePlus(words)+'&maxRows=10';
	}
	var urlstr='gp_read.php?action=geocode&ajaxpassthru='+escapePlus(urlstr);	// yes, words is escaped twice !
	//alert ("address: "+address);
	var request = GXmlHttp.create();
	//var urlstr='gp_read.php?action=geocode';
	
	request.open('GET', urlstr , true);	// request XML from PHP with AJAX call
	request.onreadystatechange = function () {
		if (request.readyState == 4) {
			searchGeoResults(site,request.responseXML);
		}
	}
	request.send(null);
}

// parses the results from a GeoCoder search
function searchGeoResults(site,xmlDoc){
	if (site=="ws.geonames.org-fulltext"){
		var results = xmlDoc.documentElement.getElementsByTagName("geoname");
	} else if (site=="ws.geonames.org-postcodes"){
		var results = xmlDoc.documentElement.getElementsByTagName("code");
	}
	document.getElementById("div_results").innerHTML = '<table width="100%"><th>'+gp_lang['results']+'</th><tr><td class="gensmall"><div id="div_results_body"></div></td></tr></table>';
	if (results.length){
		html = '<table width="100%" border=1 cellspacing=0 cellpadding=2>';
		var rowtype = 1
		html += '<b><tr class="gen"><td width="1px">'+gp_lang['rank']+'</td><td width="1px">'+gp_lang['location']+'</td><td>'+gp_lang['country']+'</td></b>';
		for (var i=0;i<results.length;i++, rowtype++){
			if  (rowtype==4){
				rowtype=1;
			}
			html += '<tr class="gensmall">';
			html += '<td class="row'+rowtype+'"><center>'+(i+1)+'</center></td>';
			html += '<td class="row'+rowtype+'">';
			html += '<a href="javascript:map.setCenter(new GLatLng('+results[i].getElementsByTagName("lat")[0].firstChild.nodeValue+','+results[i].getElementsByTagName("lng")[0].firstChild.nodeValue+'),15)">';
			html += results[i].getElementsByTagName("name")[0].firstChild.nodeValue;
			html += '</a>'
			html += '</td>';
			html += '<td class="row'+rowtype+'">'+results[i].getElementsByTagName("countryCode")[0].firstChild.nodeValue;
			html += '</td>';
			html += '</tr>';
		}
		html += '</table>';
		document.getElementById("div_results_body").innerHTML = html;
	} else {
		document.getElementById("div_results_body").innerHTML = '<center>'+gp_lang['no_match']+'</center>';
	}
}


function searchLocs(words){
	if (isset(document.form_search_gp)){	// form is drawn
		// draw results table
		document.getElementById("div_results").innerHTML = '<table width="100%"><th>'+gp_lang['results']+'</th><tr><td class="gensmall"><div id="div_results_body"></div></td></tr></table>';
		
		document.getElementById("div_results_body").innerHTML = gp_lang['searching']+'...';
		
		var request = GXmlHttp.create();
		var urlstr="gp_read.php?action=search&words="+escape(words)+"&"+queryOptions;
		request.open('GET', urlstr , true);	// request XML from PHP with AJAX call
		request.onreadystatechange = function () {
			if (request.readyState == 4) {
				var xmlDoc = request.responseXML;
				var results = xmlDoc.documentElement.getElementsByTagName("result");
				if (results.length){
					html = '<table width="100%" border=1 cellspacing=0 cellpadding=2>';
					var rowtype = 1
					html += '<b><tr class="gen"><td width="1px">'+gp_lang['rank']+'</td><td width="1px">'+gp_lang['score']+'</td><td>'+gp_lang['location']+'</td></b>';
					for (var i=0;i<results.length;i++, rowtype++){
						if  (rowtype==4){
							rowtype=1;
						}
						html += '<tr class="gensmall">';
						html += '<td class="row'+rowtype+'"><center>'+results[i].getAttribute("rank")+'</center></td>';
						html += '<td class="row'+rowtype+'"><center>'+results[i].getAttribute("score")+'</center></td>';
						html += '<td class="row'+rowtype+'">'
						var coords = results[i].getAttribute("geometry");
						coords=coords.split(",");	// seperate into points if a polyline
						coords=coords[0];	// take first point
						coords=coords.split(" ");	// split into lng, lat pairs
							html += '<a href="javascript:';
							html += 'seekLocationId('+results[i].getAttribute("location_id")+','+coords[1]+','+coords[0]+','+results[i].getAttribute("zoom")+')';
							html += '">'+results[i].getAttribute("name")+'</a>';
						html +='</td>';
						html += '</tr>';
					}
					html += '</table>';
					document.getElementById("div_results_body").innerHTML = html;
				} else {
					document.getElementById("div_results_body").innerHTML = '<center>'+gp_lang['no_match']+'</center>';
				}
				searchlist = document.getElementById("div_sidepanel").innerHTML;	// preserve contents of this window
			}
		}
		request.send(null);
	}
}

// moves to a location and opens the infowindow of a marker by location_id
function seekLocationId(id,lat,lng,zoom){
	var tmpvar=infowindowMainById(id);
	if (tmpvar == false){	// if it fails to open it, it is not in the cache
		seek_id = id;
		zoom_through = 0;
		// Move the map to the location specified
		// should call PVM - if it does it should open the infowindow because seek_id is set.
		// if it doesn't, we are already here, why did infowindowMainById() fail ??
		map.setCenter(new GLatLng(lat,lng),zoom);
	}
}

// tries to open an infowindow by location_id
// If fails, returns false
function infowindowMainById(id){
	for (var i=0;i<markers.length;i++){
		if (markers[i].id == id){
			infowindowMain(markers[i].markerindex);
			return (markers[i].markerindex);
		}
	}
	return(false);
}

// Increment the uniqueid for the main AJAX points request
function incMainUID(){
	mainUID++;
	if (mainUID == 1001){
		mainUID = 0;
	}
}

// Increment the uniqueid for the infowindow AJAX points request
function incInfoUID(){
	infoUID++;
	if (infoUID == 1001){
		infoUID = 0;
	}
}

// Increment the uniqueid for the click location in edit point AJAX points request
function incEditUID(){
	editUID++;
	if (editUID == 1001){
		editUID = 0;
	}
}

// returns a geometry type given an SQL geometry string
function geometryType(geom){
	geom=geom.split(",");
	if (geom.length > 1){
		return ("LINESTRING");
	} else {
		return ("POINT");
	}
}

// returns the lat and lng of the first node in a geometry string
function firstNode(geom){
	var ret=[];
	geom=geom.split(",");
	geom=geom[0].split(" ");
	return (geom);
}


// Configures a marker in the markers array
// appends various properties to the marker which are useful when the overlay is clicked
// various other properties can get added to a marker during it's life, eg on mouseover or click.
function configureMarker(i,data){
	markers[i].fulldata=false;	// tells UI if we have full data loaded for this location - only partial data loaded by default
	markers[i].temp=false;	// not a temporary marker
	markers[i].markertype="loc";
	markers[i].markerindex=i;	// the index in the markers array, so we know what it is when we click it.
	markers[i].id=data.getAttribute("id");	// the location ID, so we can edit it in the DB

	markers[i].geometry=data.getAttribute("geometry");
	markers[i].geometrytype=geometryType(markers[i].geometry);
	//markers[i].infowindow=unescape(data.getAttribute("infowindow"));
	//markers[i].lng=rndVar(data.getAttribute("lng"));	// the location ID, so we can edit it in the DB
	//markers[i].lat=rndVar(data.getAttribute("lat"));	// the location ID, so we can edit it in the DB
	var coords = geomToArray(markers[i].geometry);
	if (coords.length){
		coords=coords[0][0];	// convert from 2D to 1D
	}
	if (isset(coords.lngDegrees)){
		markers[i].lng=rndVar(coords.lngDegrees);	// the location ID, so we can edit it in the DB
		markers[i].lat=rndVar(coords.latDegrees);	// the location ID, so we can edit it in the DB
	} else {
		markers[i].lng=rndVar(coords.x);	// the location ID, so we can edit it in the DB
		markers[i].lat=rndVar(coords.y);	// the location ID, so we can edit it in the DB
	}
	
	markers[i].name=data.getAttribute("name");
	var mouseovr=data.getAttribute("name");	// assemble mouseover text
	if (data.getAttribute("represents_region") > 0){	// if a bunch point add number of children in brackets
		mouseovr+=" ("+data.getAttribute("childcount")+")";
	}
	markers[i].tooltip = mouseovr;
	//markers[i].topic_id=data.getAttribute("topic_id");
	
	// Add "To Here" infowindow
	markers[i].infowindowTo=''+
	'<font size=2><b>'+gp_lang['directions2']+':</b></font><form action="http://maps.google.com/maps" method="get"" target="_blank">' +
	'<input type="text" SIZE=40 MAXLENGTH=40 name="saddr" id="saddr" value="" /><br>' +
	'<br><font size=2><b>'+gp_lang['directions3']+'</b></font><br><br>' +
	'<font size=2><b>'+gp_lang['directions4']+'</b></font><br>' +
	''+markers[i].name+' ( '+markers[i].lng+', '+markers[i].lat+' )<br>' +
	'<br><INPUT value="'+gp_lang['directions5']+'" TYPE="SUBMIT"><br>' +
	'<input type="hidden" name="daddr" value="' +
	markers[i].lat + ',' + markers[i].lng + "(" + markers[i].name + ")" + '"/><br>';
	markers[i].infowindowTo += sprintf (gp_lang['directions6'],['<a href="javascript:infowindowMain('+i+')">','</a><br>']);
	markers[i].infowindowTo += sprintf (gp_lang['directions1'],['','', '<a href="javascript:infowindowFrom('+i+')">','</a>']);
	
	// Add "From Here" infowindow
	markers[i].infowindowFrom=''+
	'<font size=2><b>'+gp_lang['directions2']+'</b></font><br>' +
	''+markers[i].name+' ( '+markers[i].lng+', '+markers[i].lat+' )<br>' +
	'<br><font size=2><b>'+gp_lang['directions3']+'</b></font><br><br>' +
	'<font size=2><b>'+gp_lang['directions4']+'</b></font><form action="http://maps.google.com/maps" method="get"" target="_blank">' +
	'<input type="text" SIZE=40 MAXLENGTH=40 name="daddr" id="daddr" value="" /><br>' +
	'<br><INPUT value="'+gp_lang['directions5']+'" TYPE="SUBMIT"><br>' +
	'<input type="hidden" name="saddr" value="' +
	markers[i].lat + ',' + markers[i].lng + "(" + markers[i].name + ")" + '"/><br>';
	markers[i].infowindowFrom += sprintf (gp_lang['directions6'],['<a href="javascript:infowindowMain('+i+')">','</a><br>']);
	markers[i].infowindowFrom += sprintf (gp_lang['directions1'],['<a href="javascript:infowindowTo('+i+')">','</a>','','']);
	
	markers[i].represents_region=data.getAttribute("represents_region");
	markers[i].category=data.getAttribute("category_id");
	markers[i].childcount=data.getAttribute("childcount");
	
	markers[i].region=data.getAttribute("region_id");
	markers[i].rr_zoom=data.getAttribute("rr_zoom");	// zoom value of region it represents (or null)

	/* No longer in main pull
	//markers[i].pointowner=data.getAttribute("pointowner");
	//markers[i].rp_zoom=data.getAttribute("rp_zoom");	// zoom value of parent region
	//markers[i].rc_zoom=data.getAttribute("rc_zoom");	// highest zoom value of any child region (or null)
	//markers[i].bunch_mo=data.getAttribute("bunch_mo");	// mouseover polygon for bunch point.
	//markers[i].rr_userlist=data.getAttribute("rr_userlist");
	//markers[i].rr_grouplist=data.getAttribute("rr_grouplist");
	//markers[i].pointimport=data.getAttribute("import");
	*/
	markers[i].editable=data.getAttribute("editable");
	// if it is a line, create the polyline and add the overlay
	// =====================   END ADD TO MARKERS ARRAY ========================
	
	// ===================== BEGIN MOUSEOVER LISTENERS =========================
	GEvent.addListener(markers[i], 'mouseover', function (){	// add mouseover function to draw bunch zone
		mistatus=true;
		if (this.bunch_mo != '' && this.bunch_mo != null){	// if there is a bunch point mouseover to be shown
			showMoLines(this.bunch_mo);
		} else if (!isset(this.bunch_mo)){
			var request = GXmlHttp.create();
			var urlstr="gp_read.php?action=bunch_mo&locid="+this.id+"&"+queryOptions;
			request.open('GET', urlstr , true);	// request XML from PHP with AJAX call
			request.onreadystatechange = function () {
				if (request.readyState == 4) {
					var xmlDoc = request.responseXML;
					var bunch_mo = xmlDoc.documentElement.getElementsByTagName("location");
					bunch_mo=bunch_mo[0].getAttribute("bunch_mo");
					//markers[i].bunch_mo=bunch_mo;	// add mouseover line to marker so we don't have to get it again for this zoom
					if (mistatus == true){ // is the mouse still in ?
						showMoLines(bunch_mo);
					}
				}
			}
			request.send(null);
		}
		
		// Show tooltip
		tooltip.innerHTML = '<div class="forumline gen"><b>'+this.tooltip+'</b></div>';
		var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
		var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(this.getPoint(),map.getZoom());
		var anchor=this.getIcon().iconAnchor;
		var width=this.getIcon().iconSize.width;
		var height=tooltip.clientHeight;
		var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width, offset.y - point.y -anchor.y -height)); 
		pos.apply(tooltip);
		tooltip.style.visibility="visible";
		
	});
	GEvent.addListener(markers[i], 'mouseout', function (){
		mistatus=false;
		for (var j=0;j<regionmoline.length;j++){
			map.removeOverlay(regionmoline[j]);
		}
		//regionmoline=false;
		
		// Hide tooltip
		tooltip.style.visibility="hidden"

	});
	// ===================== END MOUSEOVER LISTENERS =========================
}

// Create a location marker
function createMarker(i,point,icon, data){
	// create marker object and assign additional data to it so that when it is clicked we have all available data
	markers[i] = new GMarker(point,icon);
	// =====================   START ADD TO MARKERS ARRAY ========================
}

function showMoLines(line){
	var polyarray = [];
	var polytmp = [];
	polyarray=geomToArray(line);	// polyarray could be multidimensional
	// clear old line
	if (regionmoline.length){
		for (var j=0;j < regionmoline.length;j++){
			map.removeOverlay(regionmoline[j]);
		}
	}
	regionmoline=[];
	// end clear
	for (var j=0;j<polyarray.length;j++){
		polytmp=polyarray[j];	// polytmp is an array within the array
		if (polytmp.length){
			//if  (!( (polytmp[0].lngDegrees == polytmp[polytmp.length-1].lngDegrees) && ( polytmp[0].latDegrees == polytmp[polytmp.length-1].latDegrees ) )){
				// end doesn't match start - close the poly
				polytmp.push(polytmp[0]);
			//}
			regionmoline[j]=new GPolyline(polytmp, "#FF0000", 3, 0.5);
			map.addOverlay(regionmoline[j]);	// draw polyline - addoverlay method
		}
	}
}

// ================================== PLOTVISIBLEMARKERS ============= PVM =============================
// Plots markers it gets from a call to gp_read.php?action=points
// todo: Write code to just plot markers from the array in memory (refresh from cache)
function plotVisibleMarkers() {
	decho ("Entering PVM");
	if (newapi){
		map.closeInfoWindow();
	}
	document.getElementById("msg_output2").innerHTML = "Markers:";	// clear the marker count div
	var urlstr="gp_read.php?action=points&"+queryOptions;	// start building URL string
	/*
	if (!document.form_modeselect[0].checked){	// stops this code running and crashing when user isnt logged in
		if( currentmode == GP_EDIT_MODE ){	// Edit Mode
			urlstr+="&editmode=1";
		} else {
			urlstr+="&editmode=0";
		}
	}
	*/
	// add the selected region to the query
	var regstr="";	// regstr is for generating the regions debug link
	if (document.form_regionselect){	// form exists ?
		if (document.form_regionselect.select_regionselect){
			urlstr += "&region=" + escapePlus(document.form_regionselect.select_regionselect.value);	// set urlstr to region_id of current region
			regstr += document.form_regionselect.select_regionselect.value;
		}
	}
	if (regstr == ""){	// no form - root ?
		regstr = "0";
	}
	regstr="gp_read.php?action=regions&"+queryOptions+"&regid="+regstr;
	
	// add the selected category to the query
	urlstr += "&category=" + currentcategory;
	
	// generate unique ID for request
	incMainUID();
	urlstr += "&uid="+mainUID;
	
	// add zoom factor
	var zoom = map.getZoom()
	urlstr += "&zoom=" + zoom;
	
	// assemble bounds part of URL
	var bounds=map.getBounds();
	
	// Fix vor V2 API being screwy at zooms 0-2
	var tmpzoom = map.getZoom();
	if (tmpzoom <= 2){
		var minx=-180;
		var maxx=180;
		var miny=-90;
		var maxy=90;
	} else {
		var minx=boundsToCoords(scaleBounds(bounds,cacheScale)).west;
		var maxx=boundsToCoords(scaleBounds(bounds,cacheScale)).east;
		var miny=boundsToCoords(scaleBounds(bounds,cacheScale)).south;
		var maxy=boundsToCoords(scaleBounds(bounds,cacheScale)).north;
	}
	// end fix
	
	//urlstr += "&zoom=" + map.getZoom() + "&minx=" + (+bounds.minX-tmpx)+ "&maxx=" + (+bounds.maxX+tmpx) + "&miny=" + (+bounds.minY-tmpy) + "&maxy=" + (+bounds.maxY+tmpy);
	//urlstr += "&zoom=" + map.getZoom() + "&minx=0&maxx=0&miny=0&maxy=0";
	//urlstr += "&minx="+boundsToCoords(scaleBounds(bounds,cacheScale)).west+"&maxx="+boundsToCoords(scaleBounds(bounds,cacheScale)).east+"&miny="+boundsToCoords(scaleBounds(bounds,cacheScale)).south+"&maxy="+boundsToCoords(scaleBounds(bounds,cacheScale)).north;
	urlstr += "&minx="+minx+"&maxx="+maxx+"&miny="+miny+"&maxy="+maxy;

	// clear old markers
	for (var i=0 ; i < markers.length ; i++){ 
		map.removeOverlay(markers[i]);	
	}
	// remove any region mouseovers that may have got "stuck"
	if (regionmoline.length){
		for (var i=0;i<regionmoline.length;i++){
			map.removeOverlay(regionmoline[i]);
		}
	}
			
	// Hide tooltip that may have gotten "stuck"
	tooltip.style.visibility="hidden"
	
	// put a link to the PHP call in a div as a link to help debugging - click on the link to open the call in a new window to see what this script is getting returned to it.
	//form_regionselect","select_regionselect","div_regions"
	document.getElementById("msg_output").innerHTML = 'XML:&nbsp&nbsp&nbsp<a target="_blank" href="' + urlstr + '">points</a>&nbsp<a target="_blank" href="'+urlstr+'&noxml=1">+</a>&nbsp&nbsp&nbsp<a target="_blank" href="'+regstr+'">regions</a>&nbsp<a target="_blank" href="'+regstr+'&noxml=1">+</a>';
	var request = GXmlHttp.create();
	loadingPane('plot',gp_lang['loading_requesting']);
	decho ('Sending AJAX request for location data <a target="_blank" href="'+urlstr+'">(link)</a>');
	request.open('GET', urlstr , true);	// request XML from PHP with AJAX call
	request.onreadystatechange = function () {
		if (request.readyState == 4) {
			decho ("Received AJAX reply with point data");
			var xmlDoc = request.responseXML;
			var uniqueid = xmlDoc.documentElement.getElementsByTagName("request");
			uniqueid=uniqueid[0].getAttribute("uniqueid");	// find the uid of the request
			if (uniqueid == mainUID){	// only process if not an old one
				locations = xmlDoc.documentElement.getElementsByTagName("location");
				map.getInfoWindow().hide();	// needed for V2 to close open infowindow on re-plot.
				// V2 map.clearoverlays does not seem to work right
				// this loop replaces it.
				for (var i=0 ; i < polylines.length ; i++){
					map.removeOverlay(polylines[i]);	
				}
				map.removeOverlay(regrabPoly);
				map.removeOverlay(cachePoly);
				
				markers = [];
				polylines=[];
				loadingPane('plot',gp_lang['loading_plotting']);
				document.getElementById("msg_output2").innerHTML = 'Markers: ' + locations.length + ''; // output marker count debug message
				if (locations.length){	// if there are markers to plot
					//var overlays=[];	// addoverlayS method
					pointlist='<table border=1 cellpadding=0 cellspacing=0 width="100%"><tr><td class="row2"><center><font size=3><b>'+gp_lang['viewmode']+" : "+gp_lang['pointlist']+'</b></font><br></td></tr></table>';
					pointlist += '<table border=1 cellpadding=2 cellspacing=0 width="100%" class="gensmall">';
					pointlist += '<tr><th width="80%" align="left">'+gp_lang['name']+'</th><th width="20%">'+gp_lang['children']+'</th></tr>';
					var rowtype=1;
					for (var i = 0; i < locations.length; i++, rowtype++) { // cycle thru locations
					
						// used to detect if we need to delete hiddenEditMarker
						// if we plot all the points but find no match, we should delete it to stop...
						// ... things thinking there is a marker hidden they can "unhide"
						var clear_hem = true;
						
						if  (rowtype==4){
							rowtype=1;
						}
						
						// =================== SET UP ICON START ==========================
						if (currentmode == GP_EDIT_MODE){	// in edit mode
							if (locations[i].getAttribute("editable")==1){
								var tmpeditable='edit'
							} else {
								var tmpeditable='noedit'
							}
						} else {	// not edit mode
							var tmpeditable='edit';		// force to editable (normal border)
						}
						if (locations[i].getAttribute("represents_region") > 0){	// is a bunch point
							var tmptype='bunch';
							if (locations[i].getAttribute("childcount")>0){		// has children
								var tmpsubtype = 'child';
							} else {	// no children
								var tmpsubtype = 'nochild';
							}
						} else {		// not a bunch point
							var tmptype='loc';
							if (geometryType(locations[i].getAttribute("geometry"))=="POINT"){	// point
								var tmpsubtype = 'point';
							} else {		// line
								var tmpsubtype = 'line';
							}
						}
						// pull icon from icon array.
						var icon=icons[categoryIdToIndex(locations[i].getAttribute("category_id"))][tmptype][tmpsubtype][tmpeditable];
						
						// =================== SET UP ICON END ==========================
						//markers[i] = new GMarker(new GLatLng(locations[i].getAttribute("lat"),locations[i].getAttribute("lng")),icon);
						var coords=firstNode(locations[i].getAttribute("geometry"));
						//createMarker(i,new GLatLng(locations[i].getAttribute("lat"),locations[i].getAttribute("lng")),icon);
						createMarker(i,new GLatLng(coords[1],coords[0]),icon);
						configureMarker(i,locations[i]);
						// add the point marker. even if it is a line - lines have a marker at the start to select them
						map.addOverlay(markers[i]);	// addoverlay method
						// Add the line if it is a line
						if (markers[i].geometrytype=="LINESTRING"){
							var polytmp=geomToArray(markers[i].geometry);
							if (polytmp.length){
								polytmp=polytmp[0];	// convert from 2D array to 1D
								if (polytmp.length){
									markers[i].polyline=polylines.length;
									polylines.push(new GPolyline(polytmp, "#0000FF", 2, 1));
									if (markers[i].id != hiddenEditMarker.id){	// if not editing this line, show it.
										map.addOverlay(polylines[markers[i].polyline]);	// draw polyline - addoverlay method
									}
								}
							}
						}
						if (markers[i].id==hiddenEditMarker.id){	// Marker being plotted is the one being edited
							markerDisplay(markers[i],false);	// hide this overlay if editing this location in edit mode
							clear_hem = false; // found hiddenEditMarker - don't clear it.
							//infowindowMain(i);	// open the infowindow
						}
						if (seek_id > 0 && zoom_through==0){	// only do this if on first pass after a link was specified and not if we zoomed through the bunch
							if (markers[i].id==seek_id){	// if this marker is the one specified in the link
								seek_id=0;
								infoOpened = true;	// info is gonna open and map may move, set it 1 to be safe else you get intermittend flicking out to zoom 16
								infowindowMain(i);
							}
						}
						pointlist += '<tr><td class="row'+rowtype+'"><a href="javascript:infowindowMain('+i+')">'+markers[i].name+'</a></td><td class="row'+rowtype+'">';
						if (markers[i].represents_region !=0){	// is a bunch
							if (markers[i].geometrytype=="LINESTRING"){		// line bunch
								var linetmp=markers[i].geometry.split(",");	// split into lng lat pairs (native format is lng lat,lng lat)
								if (linetmp.length){
									var coords=linetmp[linetmp.length-1].split(" ");
									var mx=coords[0];
									var my=coords[1];
								}
							} else {	// point bunch
								var mx=markers[i].lng;
								var my=markers[i].lat;
							}
							var mz=markers[i].rr_zoom;
							pointlist +='<center><a href="javascript:infoOpened=false;zoomThrough='+"'"+markers[i].name+"'"+';map.setCenter(new GLatLng('+my+','+mx+'),'+mz+');">'+markers[i].childcount+'</a></center>';
						} else {
							pointlist += '&nbsp';
						}
						pointlist += '</td></tr>';
						//overlays.push(markers[i]);	// addoverlayS method
					}
					if (clear_hem){
						hiddenEditMarker=false;
					}
					pointlist += '</table>';
					if (currentmode == GP_VIEW_MODE){	// if in view mode
						showSidePanel();
					}
					//map.addOverlays(overlays);	// addoverlayS method
					//overlays=[];
				}
				loadingPane('plot','');
				var bounds=map.getBounds();
				last_bounds=bounds;
				regrabPoly = new GPolyline(boundsToPolyLine(scaleBounds(bounds,grabScale)), "#00FF00", 2, 0.5);
				map.addOverlay(regrabPoly);
				
				cacheBounds = scaleBounds(bounds,cacheScale);
				cachePoly = new GPolyline(boundsToPolyLine(cacheBounds), "#FF0000", 2, 0.5);
				map.addOverlay(cachePoly);
	
				if (seek_id > 0){	// did it plot all the points but not find the seeked marker ?
					seek_id=0;	// disable seeked
				}
			}
		}
	}
	decho ("Exiting PVM");

	request.send(null);
}	

// Scales a bounds object
function scaleBounds(tmpBounds,scale){
	var tmpCoords = boundsToCoords(tmpBounds);
	var midLat = (tmpCoords.north+tmpCoords.south)/2; 
	var midLng = (tmpCoords.east+tmpCoords.west)/2;
	tmpCoords.north = midLat + (tmpCoords.north - midLat)*scale; 
	tmpCoords.south = midLat + (tmpCoords.south - midLat)*scale; 
	tmpCoords.east  = midLng + (tmpCoords.east -  midLng)*scale; 
	tmpCoords.west  = midLng + (tmpCoords.west -  midLng)*scale; 
	if (tmpCoords.north > 85.932567920988){
		tmpCoords.north = 85.932567920988
	}
	if (tmpCoords.east > 180){
		tmpCoords.east = +180
	}
	if (tmpCoords.south < -128.8235826668448){
		tmpCoords.south = -128.8235826668448
	}
	if (tmpCoords.west < -180){
		tmpCoords.west = -180
	}
	var newBounds = new GLatLngBounds(new GLatLng(tmpCoords.south, tmpCoords.west), new GLatLng(tmpCoords.north, tmpCoords.east));
	return (newBounds);
}

// Convert bounds to polyline (for drawing bounds boxes etc)
function boundsToPolyLine(tmpBounds){
	var tmpCoords = boundsToCoords(tmpBounds);
	
	var points = [];
	points.push(tmpBounds.getNorthEast());
	points.push(new GLatLng(tmpCoords.south,tmpCoords.east));
	points.push(tmpBounds.getSouthWest());
	points.push(new GLatLng(tmpCoords.north,tmpCoords.west));
	points.push(tmpBounds.getNorthEast());
	
	return points;
}

// converts a bounds to coordinates, sort of V1 minx, maxx... style
function boundsToCoords(tmpBounds){
	if (!isset(tmpBounds.getNorthEast().latDegrees)){
		var north=tmpBounds.getNorthEast().y;
		var east=tmpBounds.getNorthEast().x;
		var south=tmpBounds.getSouthWest().y;
		var west=tmpBounds.getSouthWest().x;
	} else {
		var north=tmpBounds.getNorthEast().latDegrees;
		var east=tmpBounds.getNorthEast().lngDegrees;
		var south=tmpBounds.getSouthWest().latDegrees;
		var west=tmpBounds.getSouthWest().lngDegrees;
	}
	return {north : north, east : east, west : west, south : south};
}

// ====================================================== geomToArray ======================
// converts mySQL Geometry type linestrings into arrays of GLatLngs (for a Polyline)
// Input format is x y,x y
// Can also handle multiple polylines separated by a : for the input.
// eg: x y,x y:x y,x y
// In this case, it will return a multidimensional array
// multi-lines are mainly used for region mouseovers
function geomToArray(geom){
	if (geom != ''){
		var polyout=[];
		var chunks=geom.split(":");	// split into seperate polylines
		for (var i=0;i<chunks.length;i++){
			var polytmp=[];
			var linetmp=chunks[i].split(",");	// split into lng lat pairs (native format is lng lat,lng lat)
			if (linetmp.length){	// any results ?
				//var polytmp=[];
				// cycle through coordinates appending them to the end of polytmp.
				for (var j = 0; j < linetmp.length;j++){
					var coords=linetmp[j].split(" ");
					polytmp.push(new GLatLng(coords[1],coords[0]));
				}
			}
			polyout[i]=polytmp;
		}
		//polyout=polyout[0];
		return (polyout);
	}
	return (geom);	// return empty array
}

// ====================================================== arrayToGeom ======================
// converts arrays of GLatLngs (for a Polyline) into mySQL Geometry type linestrings
function arrayToGeom(polytmp){
	var tmpstr='';
	for (var i=0;i<polytmp.length;i++){
		if (i > 0){	// not first line ?
			tmpstr += ":";	// add line separator
		}
		tmparray=polytmp[i];
		if (tmparray != ''){
			if (tmparray.length){
				for (var x=0;x<tmparray.length;x++){
					if (x != 0){	// not first entry ?
						tmpstr += ",";	// add comma separator
					}
					if (isset(tmparray[x].lngDegrees)){
						tmpstr+=rndVar(tmparray[x].lngDegrees)+" "+rndVar(tmparray[x].latDegrees);
					} else {
						tmpstr+=rndVar(tmparray[x].x)+" "+rndVar(tmparray[x].y);
					}
				}
			}
		}
	}
	return (tmpstr);
}

// ====================================================== goHistory ======================
// goes to a certain place in the view history
function goHistory(i){
	var x=view_history[i][0];
	var y=view_history[i][1];
	var z=view_history[i][2];
	view_history=view_history.splice(0,i);
	map.setCenter(new GLatLng(y,x),z);
}

// ====================================================== infowindowTo ======================
// opens the "To Here" page in the infowindow over marker i
function infowindowTo(i) {
	markers[i].openInfoWindowHtml(renderInfowindow(markers[i].infowindowTo));
}

// ====================================================== infowindowFrom ======================
// opens the "From Here" page in the infowindow over marker i
function infowindowFrom(i) {
	markers[i].openInfoWindowHtml(renderInfowindow(markers[i].infowindowFrom));
}

// ====================================================== infowindowMain ======================
// opens the main (user set) page in the infowindow over marker i
function infowindowMain(i) {
	infoOpened=true;

	if (!isset(markers[i].infowindow)){		// infowindow data not present - load it
		var request = GXmlHttp.create();
		incInfoUID();
		var urlstr="gp_read.php?action=infowindow&locid="+markers[i].id+"&uid="+infoUID+"&"+queryOptions;
		request.open('GET', urlstr, true);	// request XML from PHP with SJAX call
		request.onreadystatechange = function () {
			if (request.readyState == 4) {
				var xmlDoc = request.responseXML;
				var uniqueid = xmlDoc.documentElement.getElementsByTagName("request");
				uniqueid=uniqueid[0].getAttribute("uniqueid");	// find the uid of the request
				var location = xmlDoc.documentElement.getElementsByTagName("location");
				markers[i].infowindow=unescape(location[0].getAttribute("infowindow"));	// add mouseover line to marker so we don't have to get it again for this zoom
				markers[i].pointowner=location[0].getAttribute("pointowner");
				markers[i].topic_id=location[0].getAttribute("topic_id");

				if (infoUID==uniqueid){	// only if this is the latest request
					markers[i].openInfoWindowHtml(renderInfowindow(padMainInfowindow(i)));
				}
			}
		}
		request.send(null);
	} else {	// infowindow data loaded - show it
		markers[i].openInfoWindowHtml(renderInfowindow(padMainInfowindow(i)));
	}

	//infoOpened=false;
}

// ====================================================== padMainInfowindow ======================
// adds header and footer to the infowindow (owner, links etc)
function padMainInfowindow(i){
	if (!isset(markers[i].infowindow)){	// infowindow HTML not yet loaded.
		infowindow=gp_lang['loading'];
	} else {	// infowindow HTML loaded
		infowindow=markers[i].infowindow;
	}
	var html='<center><b><font size=3>'+markers[i].name+'</font></b><br />';
	
	// Set up "Zoom Through" button if it is a bunch
	if (markers[i].represents_region !=0){	// is a bunch
		if (markers[i].geometrytype=="LINESTRING"){		// line bunch
			var linetmp=markers[i].geometry.split(",");	// split into lng lat pairs (native format is lng lat,lng lat)
			if (linetmp.length){
				var coords=linetmp[linetmp.length-1].split(" ");
				var mx=coords[0];
				var my=coords[1];
			}
		} else {	// point bunch
			var mx=markers[i].lng;
			var my=markers[i].lat;
		}
		var mz=markers[i].rr_zoom;
		// show zoom through link
		html +='<br />';
		html += sprintf (gp_lang['child_locations'],[markers[i].childcount,'<a href="javascript:zoomThrough=\''+markers[i].name+'\';infoOpened=false;map.setCenter(new GLatLng('+my+','+mx+'),'+mz+');">','</a>']);
	} else {
		var mx=markers[i].lng;
		var my=markers[i].lat;
		var mz=GP_MAX_ZOOM-1;
	}
	html += sprintf (gp_lang['zoom_to'],['<br /><a href="javascript:infoOpened=false;map.setCenter(new GLatLng('+my+','+mx+'),'+(+mz-1)+');">','</a> ']);
	html+='</center><br /><hr>'+infowindow+'<br><br><hr><i>';
	
	html += sprintf (gp_lang['created_by'],['<a target="_blank" href="profile.php?mode=viewprofile&u='+markers[i].pointowner+'">'+markers[i].pointowner+'</a><br>']);
	
	html += sprintf (gp_lang['links'],['<a href="gp.php?action=seek&seekmode=location&location_id='+markers[i].id+'">','</a>']);
	if (markers[i].represents_region != 0){
		html += sprintf (gp_lang['links2'],['<a href="gp.php?action=seek&seekmode=location&location_id='+markers[i].id+'&zoom_through=1">','</a>']);
	}
	html += '<br />';
	html += sprintf (gp_lang['directions1'],['<a href="javascript:infowindowTo('+i+');">','</a>','<a href="javascript:infowindowFrom('+i+');">','</a>']);
	if (markers[i].topic_id > 0){
		html += '<hr>'+gp_lang['discussion1']+'<a target="_blank" href="viewtopic.php?t='+markers[i].topic_id+'">'+gp_lang['discussion2']+'</a>.';
	} else {
		if (userdata['session_logged_in']==1){
			html += '<hr>'+gp_lang['discussion1']+'<a href="javascript:addPost('+markers[i].id+','+markers[i].markerindex+');">'+gp_lang['discussion3']+'</a>.';
		} else {
			html += '<hr>'+gp_lang['discussion1']+'<u>'+gp_lang['discussion3']+'</u>'+gp_lang['discussion4']+'';
		}
	}
	html +='</i>';
	return (html);
}

// ====================================================== renderInfowindow ======================
// adds the div around infowindow HTML
function renderInfowindow(html) {
	html='<div style="width: 300px; height: 175px; overflow:auto" align="left" class="gensmall">'+html+'</div>';
	return (html);
}

// called when changing category in the main filter box
// called with the index to the categories array that has been selected.
//categories[category][0] holds the ID for this in the DB
function setCategories(category,replot,update){
	if (update==1){
		if (category == 0){	// "All"
			currentcategory=0;
		} else {
			currentcategory=categories[category][0];	// pull category_id from categories[] array
		}
		if (replot==1){
			plotVisibleMarkers();
		}
	}
}

// converts a category_id to to an index to the categories array
function categoryIdToIndex(category){
	for (var i=0;i<categories.length;i++){
		if (categories[i][0]==category){
			return (i);
		}
	}
}

// populates the categories listbox, called on change.
function getCategories(selected, replot, update, form, select, div){
	// selected = the category_id of the record being selected
	// replot: 0 - Don't replot markers
	// replot: 1 - Replot markers and make menu generated replot them too
	// replot: 2 - Don't replot the markers, but the generated menu does.
	// update: 0 for don't update the current category mode, 1 for do.
	// form: the name of the form the selectbox is to be in, eg form_pointform
	// select: the name of the select box to make, eg select_categoryselect
	// div: the name of the div to write it to, eg div_regions
	
	var noreplot=0;
	if (replot==2){
		noreplot=1;
		replot=1;
	}
	if (eval("document."+form)){	// if form exists
		var menu = '<select name="'+select+'" '+widestyle+'class="select" onChange="setCategories(selectedIndex,'+replot+', '+update+')">';
		categories[0][0]=0;	// just to be safe :)
		for (i=0;i<categories.length;i++){
			menu += '<option value='+categories[i][0];
			if (selected==categories[i][0]){	// this id was selected
				menu += ' selected';
			}
			if (i==0){
				menu += '>'+gp_lang['all'];
			} else {
				menu += '>'+categories[i][1];
			}
		}
		menu += '</select>';
		document.getElementById(div).innerHTML = menu;	// write the menu to the div
	}
	// set the category and maybe replot
	if (update==1){	// only if we are updating with this menu
		if (noreplot==1){
			setCategories(selected,0,update);
		} else {
			setCategories(selected,replot,update);
		}
	}
}

// ========================================= getRegions ============================================
// populates the region listbox and associated buttons / prompts for the map. Replot map on change
// make a form and put a div in the form, then call getRegions to populate it with regions from the db.
function getRegions(mode, replot, form, select, div, postexeccommand, postexecparam){
	// mode -1 = Navigate down the tree (to document.form_regionselect.select_regionselect.value)
	// mode x = Go "up" to region that has a parent_id of x
	// replot: 0 - Don't replot markers
	// replot: 1 - Replot markers and make menu generated replot them too
	// replot: 2 - Don't replot the markers, but the generated menu does.
	// form: the name of the form the selectbox is to be in, eg form_pointform
	// select: the name of the select box to make, eg select_categoryselect
	// div: the name of the div to write it to, eg div_regions
	// postexeccommand: (optional) A command to execute once populated.
	// postexecparam: The parameter from the selected region to pass to postexeccommand
	
	var noreplot=0;
	if (replot==2){
		noreplot=1;
		replot=1;
	}
	var request = GXmlHttp.create();
	
	// Start building the call to the PHP script
	var urlstr="gp_read.php?action=regions&"+queryOptions+"&regid="
	
	if (eval("document."+form)){	// If form exists...
		if (mode >= 0){	// go back selected - mode holds region to go back to
			urlstr += mode;
		} else {
			if (eval("document."+form+"."+select)){
				urlstr += eval("document."+form+"."+select+"."+"value");	// set urlstr to region_id of listbox selection
			}
		}
	} else {	// If form doesn't exist. - Probably at load time - set region parent to default of 0;
		urlstr = urlstr + '0';
	}
	document.getElementById(div).innerHTML = gp_lang['loading'];	// set loading message until AJAX returns
	decho ('Sending AJAX request for region data <a target="_blank" href="'+urlstr+'">(link)</a>');
	request.open('GET', urlstr , true);
	request.onreadystatechange = function () {
		var zoom=map.getZoom();
		if (request.readyState == 4) {
			//var menu = '<table><th>
			var menu='<table border=0 width="100%" cellspacing=0 cellpadding=0><tr><td>';
			decho ("Received AJAX reply with region data");
			var xmlDoc = request.responseXML;
			// region holds the XML tags for the region info
			var regions = xmlDoc.documentElement.getElementsByTagName("region");
			// regheading holds the XML tags for the region heading info
			var regheading = xmlDoc.documentElement.getElementsByTagName("heading");
			// start building new menu
			menu += '<select name="'+select+'" '+widestyle+'class="select" onChange="getRegions(-1,'+replot+",'"+form+"','"+select+"','"+div+"'";
			if (postexeccommand){
				menu += ",'"+postexeccommand+"','"+postexecparam+"'";
			}
			menu += ');">';
			if (regions.length){ // if sub menu items found
				if (regheading[0].getAttribute("parent_id")){	// if there is a parent region
					var defaultselection=regheading[0].getAttribute("region_id");	// set the value of the "All" option to it's id
				} else {
					var defaultselection='0';	// no parent - must be root of region tree
				}
				menu +='<option value="'+defaultselection+'" SELECTED >';	// add entry for default option but don't name it yet
			}
			if (regions[0].getAttribute("id") == regheading[0].getAttribute("region_id")){ // does the regions "id" tag match the regheading "region_id" tag ?
				menu += unescape(regions[0].getAttribute("name"));	// yes - this is a "leaf" node - set menu to a one item entry
			} else {	// no - this is a branch node - it has children
				menu += unescape(regheading[0].getAttribute("name")); // set default option to "All"
				for (var i = 0; i < regions.length; i++) {	// populate menu
					menu += '<option value="'+regions[i].getAttribute("id")+'">'+unescape(regions[i].getAttribute("name"))+" ("+regions[i].getAttribute("childcount")+")";
				}
			}
			var regbuttons='</td><td width="60px" align="right"><input type="button" name="Button" class="button" value="'+gp_lang['up']+'" onclick="getRegions(';	// make the up button
			regbuttons += regheading[0].getAttribute("parent_id");	// make it point to the region_id of the parent
			regbuttons +=','+replot+",'"+form+"','"+select+"','"+div+"'";
			if (postexeccommand){
				regbuttons += ",'"+postexeccommand+"','"+postexecparam+"'";
			}
			regbuttons += ');">';	// close the menu
			
			menu += '</select>'+regbuttons;	// close menu
			menu += '</td></tr></table>';
			document.getElementById(div).innerHTML = menu;	// write the menu to the div
			if (replot == 1 && noreplot==0){	// if replot is set and noreplot isnt
				last_zoom=zoom;
				zoom=regheading[0].getAttribute("zoom");
				if (seek_id != 0){	// if we seeked on page load and do not want to move here. NOTE: 0 is no seek, not unset. -1 means seeked to coords not a location
					//seek_id=0;	// reset
				} else {
					//beep();
					map.setCenter(new GLatLng(regheading[0].getAttribute("lat"),regheading[0].getAttribute("lng")),(+zoom)); // centre there
				}
			} else {
				if (regheading[0].getAttribute('admin')=="1"){
					valid_region=1;
					//EditClick(,);
				} else {
					valid_region=0;
				}
				if (selected_location==false && currentmode == GP_EDIT_MODE){	// only try to redraw edit box if point is not being edited.
					editShowHide(valid_region);
				} else if (currentmode == GP_EDIT_MODE){	// location being edited - set buttons on or off depending on edit rights.
					if (valid_region==1){
						eval(edit_button[0]+"='"+edit_button[1]+"'");		// edit on
						eval(delete_button[0]+"='"+delete_button[1]+"'");	// delete on
					} else {
						eval(edit_button[0]+"=''");		// edit off
						eval(delete_button[0]+"=''");	// delete off
					}
				}
			}
			if (!isempty(postexeccommand)){	// command to execute specified
				if (isempty(postexecparam)){
					eval(postexeccommand+"()");
				} else {
					eval(postexeccommand+"(regheading[0].getAttribute('"+postexecparam+"'))");
				}
			}
		}
	}
	request.send(null);
}



// ================================================== editZoomRange =========================================
// creates the zoom selection box for regions.
// only makes needed entries
function editZoomRange(zchild,zparent){
	if (zchild=='' || zchild == null){
		zchild=GP_MAX_ZOOM+1;
	}
	if (zparent=='' || zparent == null){
		zparent=GP_MIN_ZOOM-1;
	}
	zparent = +zparent + 1;
	zchild = +zchild - 1;
	
	var html = '<select size="1" name="PointZoom" class="select">';
	for (var i=zparent;i <= zchild;i++){
		html += '<option value="'+i+'">'+i+'</option>';
	}
	html += '</select>';
	document.getElementById("div_edit_zoom").innerHTML = html;
}

// used to set the value of a select box
// Will not try and select something that doesn't exist.
function selectOption(option,set){
	if (option){
		for (var i = 0;i < option.length;i++){
			if (option.options[i].value==set){
				option.selectedIndex=i;
			}
		}
	}
}


// ================================================== editShowHide =========================================
// shows or hides the edit box.
function editShowHide(state){
	if (state){
		if (edit_html[2]==0){	// only if currently inactive
			document.getElementById(edit_html[0]).innerHTML=edit_html[1];
			edit_html[2]=1;	// set as active
			if (settings['htmlarea'] == 1){		// init HTMLArea WYSIWYG box
				var htmlarea_config = new HTMLArea.Config();
				htmlarea_config.toolbar=[];
				var lines=settings['htmlarea_buttons'].split(";");
				for (var i=0;i < lines.length;i++){
					htmlarea_config.toolbar[i]=lines[i].split(",");
					htmlarea_config.toolbar[i].push("linebreak");
				}
				htmlarea_config.width	= '100px';
				PointInfowindow_editor = new HTMLArea('PointInfowindow',htmlarea_config);
				PointInfowindow_editor.generate();
			}
			// init the categories box.
			getCategories(0,0,0,"form_pointform","select_categoryselect","div_loc_categories");
		} 

	} else {
		removeTempMarkers();
		document.getElementById(edit_html[0]).innerHTML=gp_lang['no_region_rights']+'<hr>';
		edit_html[2]=0;	// set as active

	}
}

// ================================================== setSidePanel =========================================
// sets the different sidepanel types
function setSidePanel(type){
	currentviewmode=type;
	// set the button to the same state as indicated by type:
	if (type==GP_VIEW_HELP_MODE){
		document.frm_helpform.rad_showhelp[0].checked=true;
	} else if (type==GP_VIEW_POINTLIST_MODE){
		document.frm_helpform.rad_showhelp[1].checked=true;
	} else if (type==GP_VIEW_SEARCH_MODE){
		document.frm_helpform.rad_showhelp[2].checked=true;
	}
	showSidePanel();
}

// ================================================== showSidePanel =========================================
// draws the sidepanel in view mode
function showSidePanel(){
	var html = "";
	if (currentviewmode==GP_VIEW_HELP_MODE){
		if (isset(settings['welcome_html'])){
			html = '<table border=1 cellpadding=0 cellspacing=0 width="100%"><tr><td class="row2"><center><font size=3><b>'+gp_lang['viewmode']+" : "+gp_lang['help']+'</b></font><br></td></tr></table>';
			html += settings['welcome_html'];
		}
	} else if (currentviewmode==GP_VIEW_POINTLIST_MODE){
		if (isset(pointlist) && pointlist != false){
			html = pointlist;
		}
	} else if (currentviewmode==GP_VIEW_SEARCH_MODE){
		if (isnf(searchlist)){
			html = searchlist;
		}
	}
	document.getElementById("div_sidepanel").innerHTML = html
}

// ==================================================== pointSubmit ========================================
// submits a point to the back end php database
function pointSubmit(){
	// perform checks
	if (isempty(document.form_pointform.PointName.value)){
		// No name
		userMessage(gp_lang['no_name_error']);
	} else {
		// submit location
		if (newapi){
			map.closeInfoWindow();
		}
		if (settings['htmlarea'] == 1){
			document.form_pointform.PointInfowindow.value=PointInfowindow_editor.getHTML();
		}
		if (document.form_pointform.PointImport.value.match(/http:\/\//)){	// URL in import
			document.form_pointform.PointImport.value=""; // clear it
		}
		request = GXmlHttp.create();
		var sendstr = 'PointName=' + escapePlus(document.form_pointform.PointName.value);
		sendstr += '&PointImport=' + escapePlus(document.form_pointform.PointImport.value);
		sendstr += '&PointInfowindow=' + escapePlus(document.form_pointform.PointInfowindow.value);
		sendstr += '&PointRegion=' + document.form_pointform.select_regionselect.value;
		sendstr += '&PointCategory=' + escapePlus(document.form_pointform.select_categoryselect.value);
		sendstr += '&PointBunch=' + document.form_pointform.PointBunch.checked;
		if (getLocationMode()==GP_POINT_TYPE){ // Point
			var urlstr="gp_write.php?action=addpoint&"+queryOptions;
			sendstr += '&PointLat=' + escapePlus(document.form_pointform.PointLat.value);
			sendstr += '&PointLng=' + escapePlus(document.form_pointform.PointLng.value);
		} else if (getLocationMode()==GP_LINE_TYPE){	// Line
			var urlstr="gp_write.php?action=addline&"+queryOptions;
			var linetmp=textToWkt(document.form_pointform.PointLine.value);	// convert to internal format if needed
			sendstr += '&PointLine=' + escapePlus(linetmp);
		}
		request.open('POST', urlstr , true);
		request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
		request.onreadystatechange = function () {
			if (request.readyState == 4) {
				var xmlDoc = request.responseXML;
				replies = xmlDoc.documentElement.getElementsByTagName("reply");
				if (replies[0].getAttribute("id")==1){
					//userMessage (gp_lang['setting_ok']+gp_lang['please_refresh']);
				} else {
					userMessage ("ERROR: "+replies[0].getAttribute("message"));
				}
				//request.setRequestHeader("Connection","close");	// help: needed ?
				edit_html[2]=0;	// set edit box inactive so it redraws
				map.setCenter(new GLatLng(document.form_pointform.PointLat.value,document.form_pointform.PointLng.value),+map.getZoom());
				
				hiddenEditMarker=false;		// stop old version of marker showing again
				pointReset();				// clear temp markers and such
				plotVisibleMarkers();
			}
		}
		request.send(sendstr);
	}
}

// ==================================================== pointUpdate =========================================
// Updates an existing point in the database
function pointUpdate(){
	// perform checks
	if (isempty(document.form_pointform.PointName.value)){
		// No name
		userMessage(gp_lang['no_name_error']);
	} else {
		// update location
		if (newapi){
			map.closeInfoWindow();
		}
		if (settings['htmlarea'] == 1){
			document.form_pointform.PointInfowindow.value=PointInfowindow_editor.getHTML();
		}
		if (document.form_pointform.PointImport.value.match(/http:\/\//)){	// URL in import
			document.form_pointform.PointImport.value=""; // clear it
		}
		request = GXmlHttp.create();
		sendstr = 'update_id='+selected_location;
		sendstr += '&PointName=' + escapePlus(document.form_pointform.PointName.value);
		sendstr += '&PointImport=' + escapePlus(document.form_pointform.PointImport.value);
		sendstr += '&PointInfowindow='+escapePlus(document.form_pointform.PointInfowindow.value);
		sendstr += '&PointRegion=' + escapePlus(document.form_pointform.select_regionselect.value);
		sendstr += '&PointCategory=' + escapePlus(document.form_pointform.select_categoryselect.value);
		sendstr += '&PointBunch=' + document.form_pointform.PointBunch.checked;
		sendstr += '&PointRrZoom=' + document.form_pointform.PointZoom.value;
		if (getLocationMode()==GP_POINT_TYPE){ // Point
			var urlstr="gp_write.php?action=editpoint&"+queryOptions;
			sendstr += '&PointLat=' + escapePlus(document.form_pointform.PointLat.value) + '&PointLng=' + escapePlus(document.form_pointform.PointLng.value);
		} else if (getLocationMode()==GP_LINE_TYPE){	// Line
			var urlstr="gp_write.php?action=editline&"+queryOptions;
			var linetmp=textToWkt(document.form_pointform.PointLine.value);	// convert to internal format if needed
			sendstr += '&PointLine=' + escapePlus(linetmp);
		}
		if (document.form_pointform.PointBunch.checked==true){	// bunch point
			// clean bunch_mo to decimal places dependant on zoom
			var polytmp=geomToArray(document.form_pointform.PointBunchMo.value);
			polytmp=arrayToGeom(polytmp);
			sendstr += '&PointBunchMo='+polytmp;
			// Build user and group lists from option list
			sendstr += '&PointRrUsers=';
			for (var i=0;i < document.form_pointform.PointBunchUsers.length;i++){
				if (i>0){
					sendstr += ",";
				}
				sendstr += document.form_pointform.PointBunchUsers.options[i].value;
			}
			sendstr += '&PointRrGroups=';
			for (var i=0;i < document.form_pointform.PointBunchGroups.length;i++){
				if (i>0){
					sendstr += ",";
				}
				sendstr += document.form_pointform.PointBunchGroups.options[i].value;
			}
		}
		request.open('POST', urlstr , true);
		request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
		request.onreadystatechange = function () {
			if (request.readyState == 4) {
				var xmlDoc = request.responseXML;
				replies = xmlDoc.documentElement.getElementsByTagName("reply");
				if (replies[0].getAttribute("id")==1){
					//userMessage (gp_lang['setting_ok']+gp_lang['please_refresh']);
				} else {
					userMessage ("ERROR: "+replies[0].getAttribute("message"));
				}
				edit_html[2]=0;	// set edit box inactive so it redraws
				// refresh the main region select, but don't replot the map
				getRegions(document.form_regionselect.select_regionselect.value,2,"form_regionselect","select_regionselect","div_regions",'');
				// centre on the new location
				map.setCenter(new GLatLng(document.form_pointform.PointLat.value,document.form_pointform.PointLng.value),+map.getZoom());
				
				hiddenEditMarker=false;		// stop old version of marker showing again
				pointReset();				// clear temp markers and such
				plotVisibleMarkers();
			}
		}
		request.send(sendstr);
	}
}

// Send a message to the user.
// literally a replacement for alert() at the moment
// but means I can be sure any alert() statement other than the one in here is for debugging
function userMessage(msg){
	alert (msg);
}

// ==================================================== pointDelete =========================================
// Deletes an existing point in the database
function pointDelete(){
	if (newapi){
		map.closeInfoWindow();
	}
	var request = GXmlHttp.create();
	var urlstr="gp_write.php?action=delpoint&"+queryOptions;
	var sendstr='update_id='+selected_location;
	request.open('POST', urlstr , true);
	request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
	request.onreadystatechange = function () {
		if (request.readyState == 4) {
			var xmlDoc = request.responseXML;
			replies = xmlDoc.documentElement.getElementsByTagName("reply");
			if (replies[0].getAttribute("id")==1){
				//userMessage (gp_lang['setting_ok']+gp_lang['please_refresh']);
			} else {
				userMessage ("ERROR: "+replies[0].getAttribute("message"));
			}
			edit_html[2]=0;	// set edit box inactive so it redraws
			
			hiddenEditMarker=false;		// stop old version of marker showing again
			pointReset();				// clear temp markers and such
			// shouldn't need to plotVisibleMarkers, everything should be gone
		}
	}
	request.send(sendstr);
}

// ==================================================== removeTempMarkers =========================================
// removes all temporary overlays from the map
function removeTempMarkers(){
	if (addmarker){
		map.removeOverlay(addmarker);
		addmarker = false;
	}
	if (endmarker){
		map.removeOverlay(endmarker);
		endmarker=false;
	}
	if (editPoly){
		map.removeOverlay(editPoly);
		editPoly=false;
	}
}

// ==================================================== pointReset =========================================
// resets the point edit form
function pointReset(){
	if (newapi){
		map.closeInfoWindow();
	}
	removeTempMarkers();
	editpath=[];
	edit_html[2]=0;	// set edit box inactive so it redraws
	viewMode(GP_EDIT_MODE);
}

// ==================================================== editProfile =========================================
// edits a user profile setting in the DB via an AJAX call
function editProfile(set_key, set_value){
	decho ("Adding setting to phpBB db start");
	// Get setting from form
	switch (set_key){
		case "default_view":	// set default lng, lat and zoom
			set_value = document.form_profile.txt_default_lng.value+",";
			set_value += document.form_profile.txt_default_lat.value+",";
			set_value += document.form_profile.txt_default_zoom.value;
			break;
		case "default_region":
			if (set_value != ""){	// if it hasn't been set to blank to clear the setting
				set_value=eval ('document.form_profile.'+set_value+'.value');
			}
			break;
		default:
			return (0);
	}

	var urlstr="gp_write.php?action=profile&"+queryOptions;
	var sendstr="setting="+set_key+"&value="+set_value;
	var usermessage=gp_lang['setting_ok']+gp_lang['please_refresh'];

	var request = GXmlHttp.create();
	request.open('POST', urlstr , true);
	request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
	request.onreadystatechange = function () {
		if (request.readyState == 4) {
			var xmlDoc = request.responseXML;
			replies = xmlDoc.documentElement.getElementsByTagName("reply");
			if (replies[0].getAttribute("id")==1){
				profile[set_key]=unescape(set_value);
				userMessage (usermessage);
			} else {
				userMessage ("ERROR: "+replies[0].getAttribute("message"));
			}
		}
		decho ("Adding setting to phpBB db end");
		return(true);
	}
	request.send(sendstr);
}

// ==================================================== editSetting =========================================
// edits a default setting in the DB via an AJAX call
function editSetting(set_key, set_value){
	decho ("Adding setting to phpBB db start");
	// Get setting from form
	switch (set_key){
		case "debug_mode":
			set_value=eval ('document.form_settings.'+set_value+'.value');
			break;
		case "htmlarea_buttons":
			set_value=eval ('document.form_settings.'+set_value+'.value');
			break;
		case "htmlarea_file":
			set_value=eval ('document.form_settings.'+set_value+'.value');
			break;
		case "htmlarea":
			set_value=eval ('document.form_settings.'+set_value+'.value');
			break;
		case "showhelp_status":
			set_value=eval ('document.form_settings.'+set_value+'.value');
			break;
		case "default_view":	// aka default_lat, recalls editSetting with values for default_lng and default_zoom
			editSetting("default_lng",set_value+'lng');
			editSetting("default_zoom",set_value+'zoom');
			set_key="default_lat";	// re-write set_key for this run to lat
			set_value=set_value+"lat"	// re-write set_value for this run to that for lat
			set_value=eval ('document.form_settings.'+set_value+'.value');
			break;
		case "default_lng":
			set_value=eval ('document.form_settings.'+set_value+'.value');
			break;
		case "default_zoom":
			set_value=eval ('document.form_settings.'+set_value+'.value');
			break;
		case "default_region":
			set_value=eval ('document.form_settings.'+set_value+'.value');
			break;
		case "welcome_html":
			if (settings['htmlarea'] == 1){
				document.form_settings.txt_welcome_html.value=WelcomeHtml_editor.getHTML();
			}
			set_value=eval ('document.form_settings.'+set_value+'.value');
			set_value=escapePlus(set_value);
			break;
		case "root_permissions":
			var root_users = '';
			var root_groups = '';
			for (var i=0;i<document.form_settings.RootUsers.options.length;i++){
				if (i > 0){
					root_users += ",";
				}
				root_users += document.form_settings.RootUsers.options[i].value;
			}
			for (var i=0;i<document.form_settings.RootGroups.options.length;i++){
				if (i > 0){
					root_groups += ",";
				}
				root_groups += document.form_settings.RootGroups.options[i].value;
			}
			
			break;
		default:
			return (0);
	}

	if (set_key=="root_permissions"){
		var urlstr="gp_write.php?action=root_permissions&"+queryOptions;
		var sendstr="PointRrUsers="+root_users+"&PointRrGroups="+root_groups;
		var usermessage=gp_lang['setting_ok'];
	} else {
		var urlstr="gp_write.php?action=settings&"+queryOptions;
		var sendstr="setting="+set_key+"&value="+set_value;
		var usermessage=gp_lang['setting_ok']+gp_lang['please_refresh'];
	}
	var request = GXmlHttp.create();
	request.open('POST', urlstr , true);
	request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
	request.onreadystatechange = function () {
		if (request.readyState == 4) {
			var xmlDoc = request.responseXML;
			replies = xmlDoc.documentElement.getElementsByTagName("reply");
			if (replies[0].getAttribute("id")==1){
				if (set_key != "default_lng" && set_key != "default_lat"){	// mask these values as 3 are made at once
					settings[set_key]=unescape(set_value);
					userMessage (usermessage);
				}
			} else {
				userMessage ("ERROR: "+replies[0].getAttribute("message"));
			}
			decho ("Adding setting to phpBB db end");
			return(true);
		}
	}
	request.send(sendstr);
}

// ==================================================== addPost =========================================
// Adds a post to phpBB
function addPost(location_id, marker_id){
	decho ("Adding post to phpBB start");
	var request = GXmlHttp.create();
	var urlstr="gp_write.php?action=addpost&"+queryOptions;
	var sendstr="update_id="+location_id;
	
	request.open('POST', urlstr , true);	// request XML from PHP with AJAX call
	request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	request.onreadystatechange = function () {
		if (request.readyState == 4) {
			var xmlDoc = request.responseXML;
			replies = xmlDoc.documentElement.getElementsByTagName("reply");
			if (replies[0].getAttribute("id")==1){
				decho ("Received AJAX reply - post added OK");
				// refresh the infowindow
				markers[marker_id].topic_id=replies[0].getAttribute("topic_id");
				infowindowMain(marker_id);
			} else {
				decho ("Received AJAX reply - post add FAILED");
				userMessage ("ERROR: "+replies[0].getAttribute("message"));
			}
			decho ("Adding post to phpBB end");
		}
	}
	request.send(sendstr);
}

// ==================================================== textToWkt =========================================
// converts point / line data from various formats into the WKT-like format.
// Will just output the point / line data and NOT the linestring() or point() wrapper.
function textToWkt(linetmp){
	if (linetmp.match(new RegExp("^Date,Longitude,Latitude,Altitude"))){	// chtiGPS format trace detected.
		linetmp=linetmp.split("\n");
		var lineout="";
		var coords="";
		for (var i = 1; i < linetmp.length;i++){	// cycle through lines
			if (linetmp[i]){	// if not a blank line
				if (i>1){			// if not first iteration ...
					lineout += ",";	// add a comma after end of existing string
				}
				//linetmp[i]=linetmp[i].replace (/,/g, '.' )	// replace , with .
				coords=linetmp[i].split(",");				// split on the fields
				lineout+= (coords[1]+" "+coords[2]);	// assemble linestring in standard format
			}
		}
	} else {	// no specific format detected - return what was passed
		lineout=linetmp;
	}
	return (lineout);
}

// ==================================================== rndVar =========================================
// rounds something to 6 decimal places
function rndVar(rndvar,places){
	if (!places){
		places=6;	// default # of decimal places
	}
	places=Math.pow(10,places);
	return (Math.round(rndvar*places)/places);
}

// ==================================================== escapePlus =========================================
// escapes characters to % values for transmission via HTTP POST
// functionally the same as escape() except it encodes + to %2B to avoid confusion with space going to +
function escapePlus(html){
	html = escape(html);
	html = html.replace ('+','%2B');
	return (html);
}
	
// ==================================================== plotTempMarkers  =========================================
// plots temp markers and lines. used when editing stuff
// be careful, can get called outside edit mode (ie document.form_pointform doesn't exist)
function plotTempMarkers(){
	removeTempMarkers();
	//alert ("PTM");
	// Build line
	if (!editpath.length){	// editpath empty - take path from form
		if (document.form_pointform){
			if (getLocationMode()==GP_POINT_TYPE){		// POINT
				if (document.form_pointform.PointLng.value != '' && document.form_pointform.PointLat.value != ''){
					if (document.form_pointform){
						editpath[0]=new Array(document.form_pointform.PointLng.value,document.form_pointform.PointLat.value);
					}
				}
			} else {		// LINE
				if (document.form_pointform.PointLine){
					if (document.form_pointform.PointLine.value != ''){
						var polytmp=geomToArray(document.form_pointform.PointLine.value);
						tmparray=polytmp[0];	// convert from 2D to 1D (multi-line to single line)
						for (var x=0;x<tmparray.length;x++){
							if (isset(tmparray[x].lngDegrees)){
								var tmplng=tmparray[x].lngDegrees;
								var tmplat=tmparray[x].latDegrees;
							} else {
								var tmplng=tmparray[x].x;
								var tmplat=tmparray[x].y;
							}
							tmplng=rndVar(tmplng);
							tmplat=rndVar(tmplat);
							if (x==0){
								document.form_pointform.PointLng.value=tmplng;
								document.form_pointform.PointLat.value=tmplat;
							}
							editpath[editpath.length]=new Array(tmplng,tmplat);
						}
					}
				}
			}
		}
	}
	var points = [];	// build polyline to output in here
	var tmpgeom='';	// holds output for geometry field
	if (editpath.length){	// path in editpath - draw it
		for (var i=0;i<editpath.length;i++){
			points.push(new GLatLng (editpath[i][1],editpath[i][0]));
			if (i==0){	// first iteration ?
				addmarker=new GMarker(new GLatLng (editpath[i][1],editpath[i][0]), start_icon);
				map.addOverlay(addmarker);	// show it
				addmarker.temp=true;
				addmarker.markertype="add";
			} else {
				tmpgeom += ",";	// subsequent iteration
			}
			if (getLocationMode()==GP_LINE_TYPE){	// line type, add node to geometry field
				tmpgeom += editpath[i][0]+" "+editpath[i][1];
			} else {	// point type - only want to add end to feild
				if (i==editpath.length-1){	// last iteration
					tmpgeom = editpath[i][0]+" "+editpath[i][1];
				}
				
			}

		}
		i--;
		editPoly=new GPolyline(points, "#FF0000", 2, 1);	// create overlay
		map.addOverlay(editPoly);	// add line
		if (i > 0){	// if at least one segment, draw red end marker
			endmarker=new GMarker(new GLatLng (editpath[i][1],editpath[i][0]), end_icon);
			map.addOverlay(endmarker);	// show it
			endmarker.temp=true;
			endmarker.markertype="end";
		} else {
			endmarker=false;
		}
		var tmpstr = add_button[0].split(".innerHTML");
		tmpstr=tmpstr[0];
		if (eval(tmpstr)){	// if add / edit buttons exist
			if (editpath.length) {	// point or line passed
				if (selected_location == false){	// Add mode
					eval(add_button[0]+"='"+add_button[1]+"'");	// insert add button
				} else { //	edit mode
					eval(edit_button[0]+"='"+edit_button[1]+"'");	// insert edit button
				}
			} else {	// nothing passed
				eval(add_button[0]+"=''");	// remove add button
				eval(edit_button[0]+"=''");	// remove edit button
			}
		}
		if (document.form_pointform){	// if pointform exists
			document.form_pointform.PointLine.value=tmpgeom;
		}
	}
}

// ==================================================== locationType =========================================
// Called when user changes between point and path mode
function locationType(type){
	if (type == GP_POINT_TYPE){	// Point Type selected
		document.form_pointform.PointLng.disabled=false;
		document.form_pointform.PointLat.disabled=false;
		if (endmarker){
			map.removeOverlay (endmarker);
			endmarker=false;
		}
		if (editPoly){
			map.removeOverlay (editPoly);
			editPoly=false;
		}
		editpath=[];
		document.form_pointform.PointLine.value='';
	} else {	// Path Type
		map.removeOverlay(editPoly);
		editPoly=false;
		
		if (selected_location || addmarker ){	// in edit mode or come from point add mode with point selected
			editpath[editpath.length]=new Array(document.form_pointform.PointLng.value,document.form_pointform.PointLat.value);
		} else {
			editpath=[];
		}
		
		document.form_pointform.PointLng.disabled=true;
		document.form_pointform.PointLat.disabled=true;
		plotTempMarkers();
	}
}

// ==================================================== clickImport =========================================
// Import routine
function clickImport(){
	var doneSomething=false;
	if (getLocationMode()==GP_POINT_TYPE){	// ****************** POINT ******************
		if (document.form_pointform.PointImport.value){	// check Point / Path box for a URL
			var linetmp=document.form_pointform.PointImport.value;
			var url=linetmp.split("?");	// split to before and after end of address
			linetmp=url[0].split("/");
			if (linetmp[0]=="http:"){	// is a URL
				linetmp=linetmp[2].split(".");	// is 2 not 1 as http:// is used not http:/
				if (linetmp[0]=="maps" && linetmp[1]=="google"){	// http://maps.google.*
					linetmp=url[1].split("&");
					var tmpstr="";
					for (var j=0;j < linetmp.length;j++){
						tmpstr=linetmp[j].split("=");
						if (tmpstr[0]=="ll"){
							tmpstr=tmpstr[1].split(",");
							document.form_pointform.PointLat.value=rndVar(tmpstr[0]);
							document.form_pointform.PointLng.value=rndVar(tmpstr[1]);
							doneSomething=true;
							break;
						}
					}
				} else if ( (linetmp[0]=="www" && linetmp[1]=="multimap" && linetmp[2]=="com") || (linetmp[0]=="multimap" && linetmp[1]=="com") ){	// http://www.multimap.com or http://multimap.com
					linetmp=url[1].split("&");
					var tmpstr="";
					for (var j=0;j < linetmp.length;j++){
						tmpstr=linetmp[j].split("=");
						if (tmpstr[0]=="lat"){
							document.form_pointform.PointLat.value=rndVar(tmpstr[1]);
							j++;
							tmpstr=linetmp[j].split("=");
							document.form_pointform.PointLng.value=rndVar(tmpstr[1]);
							doneSomething=true;
							break;
						}
					}
				}
			}
		}
		// If we got co-ordinates, then add the marker and centre
		if (doneSomething && document.form_pointform.PointLng.value!="" && document.form_pointform.PointLat.value!=""){ // as long as boxes arent empty
			document.form_pointform.PointLine.value="";
			editpath=[];
			plotTempMarkers();

			map.setCenter(new GLatLng(document.form_pointform.PointLat.value,document.form_pointform.PointLng.value),GP_MAX_ZOOM-1); // centre there
		}
		
	} else {	// ****************************************************************** LINE ********************
		var linetmp=textToWkt(document.form_pointform.PointImport.value);
		var tmp1=linetmp.split("\n");
		document.form_pointform.PointLine.value=linetmp;
		editpath=[];
		//this
		plotTempMarkers();
		doneSomething=true;

	}
	if (selected_location == false && doneSomething){	// if add mode, insert add button when "Import" clicked.
		eval(add_button[0]+"='"+add_button[1]+"'");	// insert add button
	}
}

function getCenter(lng_box,lat_box,zoom_box){
	var center = map.getCenter();
	if (isset(center.x)){	// v <= 2.35
		var xattr="x";
		var yattr="y";
	} else {
		var xattr="lngDegrees";
		var yattr="latDegrees";
	}
	if (!isempty(lng_box) && !isempty(lat_box)){
		eval(lng_box+".value=rndVar(center."+xattr+")");
		eval(lat_box+".value=rndVar(center."+yattr+")");
	}
	if (!isempty(zoom_box)){
		eval (zoom_box+".value=map.getZoom()");
	}
}

// =======================================================================================================
// =============================================== viewMode START ========================================
// =======================================================================================================
// Called when mode is switched. Holds all the stuff for the sidepanel.
function viewMode(mode){
	if (!(mode>=0)){	// if unset
		mode=GP_VIEW_MODE;		// set mode to default of 1
	}
	
	// Start clean up of junk that may be left over from previous mode
	if (aplisten){
		GEvent.removeListener(aplisten); 	// Remove click listener
		aplisten=false;
	}
	editpath=[];
	if (hiddenEditMarker != false){
		markerDisplay(hiddenEditMarker,true);
	}
	//if (mode != GP_EDIT_MODE){
		//hiddenEditMarker=false;	// if we were editing a marker in Edit mode, make sure we clear it from hiddenEditMarker so PVM does not hide it
	//}
	
	if (document.form_pointform){
		document.form_pointform.PointLine.value='';
		plotTempMarkers();
	}
	
	if(currentmode != mode && document.form_regionselect && document.getElementById("div_sidepanel").innerHTML){
		plotVisibleMarkers(); // re-draw - maybe were in edit (seeing only your points) and now in view (see all)
	}
	
	currentmode=mode;
	removeTempMarkers();
	editpath = [];
	selected_location=false;
	// If the sidepanel has something in it (ie, not first call of viewmode) then re-plot markers
	// used to stop viewmode calling plot visiblemarkers on startup

	if (mode != GP_EDIT_MODE){
		edit_html[2]=0;	// set edit_html[2] to 0 to cause edit boxes to be redrawn next time it goes into edit mode.
	}
	
	switch (mode){
		case GP_VIEW_MODE:		// View
			var sideheader='<form name="frm_helpform"><table align="center" class="gen">';
			sideheader += '<tr><td>'+gp_lang['help'];
			sideheader += '<input type="radio" name="rad_showhelp" onclick="setSidePanel('+GP_VIEW_HELP_MODE+')"></td>';
			sideheader += '<td>&nbsp&nbsp&nbsp</td><td>'+gp_lang['pointlist'];
			sideheader += '<input type="radio" name="rad_showhelp" onclick="setSidePanel('+GP_VIEW_POINTLIST_MODE+')"></td>';
			sideheader += '<td>&nbsp&nbsp&nbsp</td><td>'+gp_lang['search'];
			sideheader += '<input type="radio" name="rad_showhelp" onclick="setSidePanel('+GP_VIEW_SEARCH_MODE+')"></td></tr>';
			sideheader += '</table></form>';
			document.getElementById("div_sideheader").innerHTML = sideheader;
			sideheader_on=true;
			document.getElementById("div_sidefooter").innerHTML = '';
			sidefooter_on=false;
			winResize();
			
			setSidePanel(currentviewmode);		// shouldn't need as PVM is called and that does it.
			if (aplisten){
				GEvent.removeListener(aplisten);
				aplisten=false;
			}
			break;
		case GP_EDIT_MODE:	// Add / Edit	============================================= EDIT MODE ====================================================
			if (edit_html[2]==0){	// only if currently inactive
				document.getElementById("div_sideheader").innerHTML = '<center><b><font size=3>'+gp_lang['editmode']+'</font></center>';
				sideheader_on=true;
				
				// Set initial title and create div for edit box (div_edit_html) in the body div
				var html_str = '';
				var step = 1;
				
				// Header table
				html_str += '<form name="form_pointform">';
				html_str += '<table border="0" cellpadding="0" cellspacing="0" width="100%" class="gensmall">';
				
				// Region
				html_str += '<th><b>'+gp_lang['step']+" "+step+" : "+gp_lang['edit_region']+'</b>&nbsp;&nbsp;'
				html_str += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'edit_region_help\')">';
				html_str += '</th>';
				html_str += '<tr><td><div class="row2" style="display:none" id="edit_region_help"><i>'+gp_lang['edit_region_help']+'</i></div></tr></td>';
				html_str += '<tr><td><div id="div_loc_regions"></div></td></tr>';
				html_str += '</table>';
				html_str += '<br>';
				html_str += '<div id="div_edit_html"></div>';
				document.getElementById("div_sidepanel").innerHTML = html_str;
				step++;
				// Create Divs for Add / Edit / Delete / Reset buttons in the footer div
				html_str = '<table border="0" cellpadding="0" cellspacing="0" width="100%" class="gensmall"><tr>';
				html_str += '<td width="25%"><p align="center"><div id="div_add_button"></td>';
				html_str += '<td width="25%"><p align="center"><div id="div_edit_button"></td>';
				html_str += '<td width="25%"><p align="center"><div id="div_delete_button"></td>';
				html_str += '<td width="25%"><p align="center"><div id="div_reset_button"></td>';
				html_str += '</tr></table>';
				html_str += '</form>';
				document.getElementById("div_sidefooter").innerHTML = html_str;
				sidefooter_on=true;
				winResize();
				
				// Set up the edit box HTML into edit_html ready to be parsed.
				// edit_html[0] contains the div and edit_html[1] contains the data
				// evaling html[0] to edit_html[1] will then populate the box.
				// edit_html[2] contains 1 to indicate if the edit box is populated with the data in edit_html[1].
				edit_html[0] = 'div_edit_html';
	
				// Start table			
				edit_html[1] = '';
				edit_html[1] += '<table border="0" cellpadding="0" cellspacing="0" width="100%" class="gensmall">';
				
				// Type
				if (mge_enabled){
					edit_html[1] += '<th colspan=2><b>'+gp_lang['step']+" "+step+" : "+gp_lang['edit_type']+'</b>&nbsp;&nbsp;'
					edit_html[1] += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'edit_type_help\')">';
					edit_html[1] += '</th>';
					edit_html[1] += '<tr><td colspan=2><div class="row2" style="display:none" id="edit_type_help"><i>'+gp_lang['edit_type_help']+'</i></div></tr></td>';
					//edit_html[1] += '<tr><td width="20%"><b>'+gp_lang['type']+'</b></td>';
					edit_html[1] += '<tr><td colspan=2><center><input type="radio" class="input" name="radio_typebutton" value="Point" onclick="locationType(GP_POINT_TYPE);" checked>'+gp_lang['point']+'';
					edit_html[1] += '&nbsp;&nbsp;&nbsp;&nbsp;<input type="radio" class="input" name="radio_typebutton" value="Path" onclick="locationType(GP_LINE_TYPE);">'+gp_lang['line']+'</center></td></tr>';
					edit_html[1] += '<tr><td colspan=2>&nbsp</td></tr>';	// add blank line spacer
					step++;
				}
				// Location
				edit_html[1] += '<th colspan=2><b>'+gp_lang['step']+" "+step+" : "+gp_lang['edit_location']+'</b>&nbsp;&nbsp;'
				edit_html[1] += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'edit_location_help\')">';
				edit_html[1] += '</th>';
				edit_html[1] += '<tr><td colspan=2><div class="row2" style="display:none" id="edit_location_help"><i>'+gp_lang['edit_location_help']+'</i></div></tr></td>';
				// Name
				edit_html[1] += '<tr><td><b>'+gp_lang['name']+'</b></td><td><input type="text" class="input" name="PointName"></td></tr>';
				// Lng
				edit_html[1] += '<tr><td><b>'+gp_lang['lng']+'</b></td><td>';
					edit_html[1] += '<table border=0 cellpadding=0 cellspacing=0 width="100%"><tr>';
						edit_html[1] += '<td><input type="text" class="input" name="PointLng"></td>';
						edit_html[1] += '<td width="70px" align="right"><input type="button" class="button" value="'+gp_lang['center']+'" onclick="getCenter(\'document.form_pointform.PointLng\',\'document.form_pointform.PointLat\');editpath=[];plotTempMarkers()"></td>';
					edit_html[1] += '</tr></table>';
				edit_html[1] += '</td></tr>';
				// Lat
				edit_html[1] += '<tr><td><b>'+gp_lang['lat']+'</b></td><td>';
					edit_html[1] += '<table border=0 cellpadding=0 cellspacing=0 width="100%"><tr>';
						edit_html[1] += '<td><input type="text" class="input" name="PointLat"></td>';
						edit_html[1] += '<td width="70px" align="right"></td>';
					edit_html[1] += '</tr></table>';
				edit_html[1] += '</td></tr>';
				// Geom
				edit_html[1] += '<tr><td><b>'+gp_lang['geometry_native']+'<b></td><td>';
					edit_html[1] += '<table border=0 cellpadding=0 cellspacing=0 width="100%"><tr>';
						edit_html[1] += '<td><input type="text" class="input gensmall" name="PointLine"></td>';
						edit_html[1] += '<td width="70px" align="right"><input type="button" class="button" value="'+gp_lang['import']+'" onclick="clickImport()" name="ShowOnMap">';
					edit_html[1] += '</tr></table>';
				edit_html[1] += '</td></tr>';
				
				// Import
				edit_html[1] += '<tr><td><b>'+gp_lang['import']+'<b></td><td><textarea style="width:100%" rows="3" class="input gensmall" name="PointImport" ></textarea></td></tr>';
				edit_html[1] += '<tr><td>&nbsp</td><td>'+sprintf(gp_lang['chtigps_compat'],['<a href="http://www.chtisoft.com/us/chtiGPS?page=0">chtiGPS</a>'])+'</td></tr>';
				edit_html[1] += '<tr><td colspan=2>&nbsp</td></tr>';	// add blank line spacer
				step++;
				
				// Infowindow
				edit_html[1] += '<th colspan=2><b>'+gp_lang['step']+" "+step+" : "+gp_lang['edit_infowindow']+'</b>&nbsp;&nbsp;'
				edit_html[1] += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'edit_infowindow_help\')">';
				edit_html[1] += '</th>';
				edit_html[1] += '<tr><td colspan=2><div class="row2" style="display:none" id="edit_infowindow_help"><i>'+gp_lang['edit_infowindow_help']+'</i></div></tr></td>';
				edit_html[1] += '<tr><td colspan=2><textarea rows="15" cols="38" name="PointInfowindow" id="PointInfowindow"></textarea></td></tr>';
				edit_html[1] += '<tr><td colspan=2>&nbsp</td></tr>';	// add blank line spacer
				step++;
				
				// Category
				edit_html[1] += '<th colspan=2><b>'+gp_lang['step']+" "+step+" : "+gp_lang['edit_category']+'</b>&nbsp;&nbsp;'
				edit_html[1] += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'edit_category_help\')">';
				edit_html[1] += '</th>';
				edit_html[1] += '<tr><td colspan=2><div class="row2" style="display:none" id="edit_category_help"><i>'+gp_lang['edit_category_help']+'</i></div></tr></td>';
				edit_html[1] += '<tr><td colspan=2>';
				edit_html[1] += '<div id="div_loc_categories"></div>';
				edit_html[1] += '</td></tr>';
				step++;
				
				// End main table
				edit_html[1] += '</table>';
				
				// Start set bunch div (hideable);
				edit_html[1] += '<div id="div_setbunch" style="display:none">';
				
				// Set Bunch
				edit_html[1] += '<br>';
				edit_html[1] += '<table border="0" cellpadding="0" cellspacing="0" width="100%" class="gensmall">';
				edit_html[1] += '<th colspan=3><b>'+gp_lang['step']+" "+step+" : "+gp_lang['edit_bunch']+'</b>&nbsp;&nbsp;'
				edit_html[1] += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'edit_bunch_help\')">';
				edit_html[1] += '</th>';
				edit_html[1] += '<tr><td colspan=3><div class="row2" style="display:none" id="edit_bunch_help"><i>'+gp_lang['edit_bunch_help']+'</i></tr></td>';
				edit_html[1] += '<tr><td width="30%"><b>'+gp_lang['is_bunch']+'</b></td><td colspan=2><input type="checkbox" class="input" name="PointBunch" value="OFF" disabled></textarea></td></tr>';
				edit_html[1] += '<tr><td width="30%"><b>'+gp_lang['zoom']+'</b></td><td>';
				edit_html[1] += '<div id="div_edit_zoom"></div></td>';
				edit_html[1] += '<td><input type="button" class="button" class="button" value="'+gp_lang['this_zoom']+'" name="ThisZoom" onclick="selectOption(document.form_pointform.PointZoom,map.getZoom());"></td></tr>';
				edit_html[1] += '</table>';
				step++;
				// End set bunch div
				edit_html[1] += '</div>';
				
				// Start edit bunch div
				edit_html[1] += '<div id="div_editbunch" style="display:none">';
				
				// Region Permissions - EDIT
				edit_html[1] += '<br>';
				edit_html[1] += '<table border="1" cellpadding="0" cellspacing="0" width="100%" class="gensmall">';
				edit_html[1] += '<th colspan=2><b>'+gp_lang['step']+" "+step+" : "+gp_lang['edit_regionperm']+'</b>&nbsp;&nbsp;'
				edit_html[1] += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'edit_regionperm_help\')">';
				edit_html[1] += '</th>';
				edit_html[1] += '<tr><td colspan=2><div class="row2" style="display:none" id="edit_regionperm_help"><i>'+gp_lang['edit_regionperm_help']+'</i></tr></td>';
				edit_html[1] += '<tr><td width="50%"><center><b>'+gp_lang['users']+'</b></center></td><td width="50%"><center><b>'+gp_lang['groups']+'</b></center></td></tr>';
				edit_html[1] += '<tr><td><select size=5 name=PointBunchUsers '+widestyle+' class="select" multiple></select></td><td><select size=5 name=PointBunchGroups '+widestyle+' class="select" multiple></select></td></tr>';
				edit_html[1] += '<tr><td align=center>';
				edit_html[1] += '<input type=button name= "PointBunchAddUser" value="'+gp_lang['add']+'" class="button" onclick = "javascript:med_window(\'gp_upop.php\',\'users\');">';
				edit_html[1] += '<input type=button name= "PointBunchDelUser" value="'+gp_lang['del']+'" class="button" onclick = "javascript:delListItem(document.form_pointform.PointBunchUsers);">';
				edit_html[1] += '</td>';
				edit_html[1] += '<td align=center>';
				edit_html[1] += '<input type=button name= "PointBunchAddGroup" value="'+gp_lang['add']+'" class="button" onclick = "javascript:small_window(\'gp_gpop.php\',\'groups\');">';
				edit_html[1] += '<input type=button name= "PointBunchDelGroup" value="'+gp_lang['del']+'" class="button" onclick = "javascript:delListItem(document.form_pointform.PointBunchGroups);">';
				edit_html[1] += '</td></tr>';
				edit_html[1] += '</table>';
				edit_html[1] += '<br>';
				step++;
				
				// Bunch Mouseover
				edit_html[1] += '<table border="1" cellpadding="0" cellspacing="0" width="100%" class="gensmall">';
				edit_html[1] += '<th colspan=2><b>'+gp_lang['step']+" "+step+" : "+gp_lang['edit_bunchmo']+'</b>&nbsp;&nbsp;'
				edit_html[1] += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'edit_bunchmo_help\')">';
				edit_html[1] += '</th>';
				edit_html[1] += '<tr><td colspan=2><div class="row2" style="display:none" id="edit_bunchmo_help"><i>'+gp_lang['edit_bunchmo_help']+'</i></tr></td>';
				edit_html[1] += '<tr><td>';
				edit_html[1] += '<input type="text" '+widestyle+' class="input" name="PointBunchMo" size="30">';
				edit_html[1] += '</td></tr>';
				
				// End edit bunch div
				edit_html[1] += '</div>';
				step++;
				
				// Set the buttons to default values
				eval(add_button[0]+"=''");		// add off
				eval(edit_button[0]+"=''");		// edit off
				eval(delete_button[0]+"=''");	// delete off
				eval(reset_button[0]+"='"+reset_button[1]+"'");		// reset is always on
	
				// Initialise the region box
				// This could set the edit box (div_edit_html) to "Not allowed to post in this region"
				// or it could cause the HTML for the edit box to be displayed
				getRegions(document.form_regionselect.select_regionselect.value,0,'form_pointform','select_regionselect','div_loc_regions');
				//getCategories(0,0,0,"form_pointform","select_categoryselect","div_loc_categories");
			}
			break;
			
		case GP_PROFILE_MODE:	// Profile (user)	============================================= PROFILE MODE ====================================================
			sideheader_on=true;
			document.getElementById("div_sideheader").innerHTML = '<center><b><font size=3>'+gp_lang['profilemode']+'</font></center>';

			var sidepanel = '';	
			
			// start form		
			sidepanel += '<form name="form_profile">';
			
			// start table
			sidepanel += '<table class="gensmall" border=0 cellpadding=1 cellspacing=0 style="border-collapse: collapse" bordercolor="#111111" width="100%">';

			// Default Region - PROFILE
			sidepanel += '<th colspan=3><b>'+gp_lang['default_region']+'</b>&nbsp;';
			sidepanel += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'div_default_region_info\')">';
			sidepanel += '</th>';
			sidepanel += '<tr><td colspan=3 class="row1">';
			sidepanel += '<div id="div_default_region_info" style="display:none"><i>'+gp_lang['default_region_desc']+'</i></div>';
			sidepanel += '</td></tr>';
			sidepanel += '<tr><td colspan=2><div id="div_default_region"></div></td><td align="right">';
			sidepanel += '&nbsp;';
			sidepanel += '</td></tr>';
			sidepanel += '<tr><td colspan=2>';
			if (profile['default_region'] == ""){	// default region not set
				sidepanel += '<img border="0" src="templates/subSilver/images/topic_unlock.gif" width="19" height="18">';
			} else {	// default region set - show clear button
				sidepanel += '<img border="0" src="templates/subSilver/images/topic_lock.gif" width="19" height="18">';
				sidepanel += '&nbsp;&nbsp;<input type="button" class="button" value="'+gp_lang['clear']+'" onclick="editProfile(\'default_region\',\'\');">';
			}
			sidepanel += '</td><td align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editProfile(\'default_region\',\'select_default_region\');"></td></tr>';
			
			// Default View - PROFILE
			sidepanel += '<th colspan=3><b>'+gp_lang['default_view']+'</b>&nbsp;';
			sidepanel += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'div_default_view_info\')">';
			sidepanel += '</th>';
			sidepanel += '<tr><td colspan=3 class="row1">';
			sidepanel += '<div id="div_default_view_info" style="display:none"><i>'+gp_lang['default_view_desc']+'</i></div>';
			sidepanel += '</td></tr>';
			sidepanel += '<tr><td width="10%"><b>'+gp_lang['lng']+'</b></td><td><input disabled name="txt_default_lng" size="10" value="'+profile['default_lng']+'"></td><td rowspan=3 align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editProfile(\'default_view\',\'txt_default_\');"></td></tr>';
			sidepanel += '<tr><td><b>'+gp_lang['lat']+'</b></td><td><input disabled name="txt_default_lat" size="10" value="'+profile['default_lat']+'">';
			sidepanel += '&nbsp;&nbsp;&nbsp;<input type="button" class="button" value="'+gp_lang['here']+'" onclick="getCenter(\'document.form_profile.txt_default_lng\',\'document.form_profile.txt_default_lat\',\'document.form_profile.txt_default_zoom\');"></td></tr>';
			sidepanel += '<tr><td><b>'+gp_lang['zoom']+'</b></td><td><input disabled name="txt_default_zoom" size="10" value="'+profile['default_zoom']+'">';
			sidepanel += '&nbsp;&nbsp;&nbsp;<input type="button" class="button" value="'+gp_lang['clear']+'" onclick="document.form_profile.txt_default_lng.value=\'\';document.form_profile.txt_default_lat.value=\'\';document.form_profile.txt_default_zoom.value=\'\';"></td></tr>';
			
			// end table
			sidepanel += '</table>';
			
			// end form
			sidepanel += '</form>'
			document.getElementById("div_sidepanel").innerHTML = sidepanel;
			getRegions(+profile['default_region'], 0, "form_profile", "select_default_region", "div_default_region");

			
			document.getElementById("div_sidefooter").innerHTML = '';
			sidefooter_on=false;
			winResize();
			break;
		
		case GP_SETTINGS_MODE:	// Settings (Admin)	============================================= SETTINGS MODE ====================================================
			document.getElementById("div_sideheader").innerHTML = '<center><b><font size=3>'+gp_lang['settingsmode']+'</font></center>';
			sideheader_on=true;

			var sidepanel = '';
			
			// display link to back end settings script
			sidepanel += '<br>';
			sidepanel += sprintf (gp_lang['settings_link'],['<a href="gp_admin.php">','</a>']);
			sidepanel += '<br><br>';

			// Start form						
			sidepanel += '<form name="form_settings">';
			
			// Start sidepanel table
			sidepanel += '<table class="gensmall" border=0 cellpadding=1 cellspacing=0 style="border-collapse: collapse" bordercolor="#111111" width="100%">';

			// Root permissions - SETTINGS
			sidepanel += '<th colspan=3><b>'+gp_lang['root_permissions']+'</b>&nbsp;';
			sidepanel += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" eight="13" onClick="toggleDiv(\'div_root_permissions_info\')">';
			sidepanel += '</th>';
			sidepanel += '<tr><td colspan=3 class="row1">';
			sidepanel += '<div id="div_root_permissions_info" style="display:none"><i>'+gp_lang['root_permissions_desc']+'</i></div>';
			sidepanel += '</td></tr>';
			sidepanel += '<tr><td colspan=3>';
			sidepanel += '<table border="1" cellpadding="0" cellspacing="0" class="gensmall" width="100%">';
			sidepanel += '<tr><td colspan=2><div class="row2" style="display:none" id="edit_regionperm_help"><i>'+gp_lang['edit_regionperm_help']+'</i></tr></td>';
			sidepanel += '<tr><td width="50%"><center><b>'+gp_lang['users']+'</b></center></td><td width="50%"><center><b>'+gp_lang['groups']+'</b></center></td></tr>';
			sidepanel += '<tr><td><select size=5 class="select" name="RootUsers" '+widestyle+' multiple></select></td><td><select size=5 name="RootGroups" class="select" '+widestyle+' multiple></select></td></tr>';
			sidepanel += '<tr><td align=center>';
			sidepanel += '<input type=button value="'+gp_lang['add']+'" class="button" onclick = "javascript:med_window(\'gp_upop.php\',\'users\');">';
			sidepanel += '<input type=button value="'+gp_lang['del']+'" class="button" onclick = "javascript:delListItem(document.form_settings.RootUsers);">';
			sidepanel += '</td>';
			sidepanel += '<td align=center>';
			sidepanel += '<input type=button value="'+gp_lang['add']+'" class="button" onclick = "javascript:small_window(\'gp_gpop.php\',\'users\');">';
			sidepanel += '<input type=button value="'+gp_lang['del']+'" class="button" onclick = "javascript:delListItem(document.form_settings.RootGroups);">';
			sidepanel += '</td></tr>';
			sidepanel += '</table>';
			sidepanel += '</td></tr>';
			sidepanel += '<tr><td colspan=2>&nbsp;</td><td align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editSetting(\'root_permissions\',\'\');"></td></tr>';
			
			// Default Region - SETTINGS
			sidepanel += '<th colspan=3><b>'+gp_lang['default_region']+'</b>&nbsp;';
			sidepanel += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'div_default_region_info\')">';
			sidepanel += '</th>';
			sidepanel += '<tr><td colspan=3 class="row1">';
			sidepanel += '<div id="div_default_region_info" style="display:none"><i>'+gp_lang['default_region_desc']+'</i></div>';
			sidepanel += '</td></tr>';
			sidepanel += '<tr><td colspan=2><div id="div_default_region"></div></td><td align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editSetting(\'default_region\',\'select_default_region\');"></td></tr>';
			
			// Default View - SETTINGS
			sidepanel += '<th colspan=3><b>'+gp_lang['default_view']+'</b>&nbsp;';
			sidepanel += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'div_default_view_info\')">';
			sidepanel += '</th>';
			sidepanel += '<tr><td colspan=3 class="row1">';
			sidepanel += '<div id="div_default_view_info" style="display:none"><i>'+gp_lang['default_view_desc']+'</i></div>';
			sidepanel += '</td></tr>';
			sidepanel += '<tr><td width="10%"><b>'+gp_lang['lng']+'</b></td><td><input disabled name="txt_default_lng" size="10" value="'+settings['default_lng']+'"></td><td rowspan=3 align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editSetting(\'default_view\',\'txt_default_\');"></td></tr>';
			sidepanel += '<tr><td><b>'+gp_lang['lat']+'</b></td><td><input disabled name="txt_default_lat" size="10" value="'+settings['default_lat']+'">';
			sidepanel += '&nbsp;&nbsp;&nbsp;<input type="button"  class="button" value="'+gp_lang['here']+'" onclick="getCenter(\'document.form_settings.txt_default_lng\',\'document.form_settings.txt_default_lat\',\'document.form_settings.txt_default_zoom\');"></td></tr>';
			sidepanel += '<tr><td><b>'+gp_lang['zoom']+'</b></td><td><input disabled name="txt_default_zoom" size="10" value="'+settings['default_zoom']+'">';
			sidepanel += '&nbsp;&nbsp;&nbsp;<input type="button"  class="button" value="'+gp_lang['clear']+'" onclick="document.form_settings.txt_default_lng.value=\'\';document.form_settings.txt_default_lat.value=\'\';document.form_settings.txt_default_zoom.value=\'\';"></td></tr>';
			//sidepanel += '</td></tr>';
			
			// Region Forums
			sidepanel += '<th colspan=3><b>'+gp_lang['region_forum']+'</b>&nbsp;';
			sidepanel += '<img border="0" src="templates/subSilver/images/icon_mini_faq.gif" width="12" height="13" onClick="toggleDiv(\'div_region_forum_info\')">';
			sidepanel += '</th>';
			sidepanel += '<tr><td colspan=3 class="row1">';
			sidepanel += '<div id="div_region_forum_info" style="display:none"><i>'+gp_lang['region_forum_desc']+'</i></div>';
			sidepanel += '</td></tr>';
			sidepanel += '<tr><td colspan=2>';
			sidepanel += '<b>'+gp_lang['region']+':</b><br>';
			sidepanel += '<div id="div_region_forum_r"></div>';
			sidepanel += '</td><td></td></tr>';
			sidepanel += '<tr><td colspan=3>';
			sidepanel += '<br><b>'+gp_lang['forum']+':</b><br>';
			sidepanel += '<div id="div_region_forum_f"></div>';
			sidepanel += '</td></tr>';

			// Misc Settings
			sidepanel += '<th colspan=3>'+gp_lang['misc_settings']+'</th>';
		
			// Debug Mode
			sidepanel += '<tr><td><b>'+gp_lang['debug_mode']+'</b></td><td><select size="1" name="select_debug_mode"><option value="1">On</option><option value="0">Off</option></select></td>';
			sidepanel += '<td align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editSetting(\'debug_mode\',\'select_debug_mode\');"></td></tr>';

			// HTMLArea
			sidepanel += '<tr><td><b>'+gp_lang['htmlarea']+'</b></td><td><select size="1" name="select_htmlarea"><option value="1">On</option><option value="0">Off</option></select></td>';
			sidepanel += '<td align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editSetting(\'htmlarea\',\'select_htmlarea\');"></td></tr>';

			// HTMLArea Buttons
			sidepanel += '<tr><td><b>'+gp_lang['htmlarea_buttons']+'</b></td><td><input name="txt_htmlarea_buttons" value="'+settings['htmlarea_buttons']+'"></td>';
			sidepanel += '<td align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editSetting(\'htmlarea_buttons\',\'txt_htmlarea_buttons\')"></td></tr>';
			
			// HTMLArea File
			sidepanel += '<tr><td><b>'+gp_lang['htmlarea_file']+'</b></td><td><input name="txt_htmlarea_file" value="'+settings['htmlarea_file']+'"></td>';
			sidepanel += '<td align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editSetting(\'htmlarea_file\',\'txt_htmlarea_file\')"></td></tr>';
			
			// Showhelp status
			sidepanel += '<tr><td><b>'+gp_lang['showhelp_status']+'</b></td><td><select size="1" name="select_showhelp_status"><option value="1">On</option><option value="0">Off</option></select></td>';
			sidepanel += '<td align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editSetting(\'showhelp_status\',\'select_showhelp_status\');"></td></tr>';
			
			// Welcome HTML
			sidepanel += '<th colspan=3>'+'<b>'+gp_lang['welcome_html']+'</b>'+'</th>';
			sidepanel += '<tr><td colspan=3><textarea rows="15" cols="38" name="txt_welcome_html" id="txt_welcome_html" >'+settings['welcome_html']+'</textarea></td></tr>';
			sidepanel += '<tr><td colspan=3 align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="editSetting(\'welcome_html\',\'txt_welcome_html\')"></center></td></tr>';

			//sidepanel += '</table>';
			sidepanel += '<th colspan=3>'+gp_lang['extra_tools']+'</h>';
			
			sidepanel += '<tr><td colspan=3>';
			// Links to back end PHP stuff - fill out boxes via vars in the URL where possible
			sidepanel += '<b>'+gp_lang['region_branch_import']+':</b><br>';
			sidepanel += '<div id="div_region_branch_import">&nbsp</div>';
			sidepanel += sprintf (gp_lang['region_branch_import_link'],['<a href="javascript: window.location=\'gp_admin.php?action=rb_import&update_id=\'+document.form_settings.select_region_branch_import.value">','</a>']);
			sidepanel += '<br><br>';
			sidepanel += '<b>'+gp_lang['region_branch_export']+':</b><br>';
			sidepanel += '<div id="div_region_branch_export">&nbsp</div>';
			sidepanel += sprintf (gp_lang['region_branch_export_link'],['<a href="javascript: window.location=\'gp_admin.php?action=rb_export&update_id=\'+document.form_settings.select_region_branch_export.value">','</a>']);
			sidepanel += '</td></tr>';
			
			// end table
			sidepanel += '</table>';
			
			// end form
			sidepanel += '</form>'
			
			// push the HTML to the div
			document.getElementById("div_sidepanel").innerHTML = sidepanel;
			//toggleDiv('div_default_region_info');

			// Activate the WYSIWYG editor if enabled.
			if (settings['htmlarea'] ==1){
				var htmlarea_config = new HTMLArea.Config();
				htmlarea_config.toolbar=[];
				var lines=settings['htmlarea_buttons'].split(";");
				for (var i=0;i < lines.length;i++){
					htmlarea_config.toolbar[i]=lines[i].split(",");
					htmlarea_config.toolbar[i].push("linebreak");
				}
				htmlarea_config.width	= '100px';
				WelcomeHtml_editor = new HTMLArea('txt_welcome_html',htmlarea_config);
				WelcomeHtml_editor.generate();
			}
			
			// Root Permissions init start
			var request = GXmlHttp.create();
			var urlstr="gp_read.php?action=root_permissions";
			request.open('GET', urlstr, true);	// request XML from PHP with AJAX call
			request.onreadystatechange = function () {
				if (request.readyState == 4) {
					var xmlDoc = request.responseXML;
					var permission = xmlDoc.documentElement.getElementsByTagName("permission");
					
					// populate user permissions list for bunch point with current list
					document.form_settings.RootUsers.length=0;
					var tmpusers=permission[0].getAttribute("userlist");
					if (!isempty(tmpusers)){
						var users=tmpusers.split(",");	// split into records
						for (var j = 0;j<users.length;j++){
							var user=users[j].split(":");	// split IDs and names
							document.form_settings.RootUsers.options[j] = new Option(user[1],user[0]);
						}
					}
					// populate group permissions list for bunch point with current list
					document.form_settings.RootGroups.length=0;
					var tmpgroups=permission[0].getAttribute("grouplist");
					if (!isempty(tmpgroups)){
						var groups=tmpgroups.split(",");
						// Add the group to the menu
						for (var j = 0;j<groups.length;j++){
							var group=groups[j].split(":");	// split IDs and names
							document.form_settings.RootGroups.options[j] = new Option(group[1],group[0]);
						}
					}
			
					// set the initial values of the region selectors in the settings menu
					initRegionForum();
					getRegions(1, 0, "form_settings", "select_region_branch_import", "div_region_branch_import");
					getRegions(1, 0, "form_settings", "select_region_branch_export", "div_region_branch_export");
					getRegions(+settings['default_region'], 0, "form_settings", "select_default_region", "div_default_region");
					
					// Set buttons etc to current values.
					document.form_settings.select_debug_mode.value=settings['debug_mode'];
					document.form_settings.select_htmlarea.value=settings['htmlarea'];
					document.form_settings.select_showhelp_status.value=settings['showhelp_status'];
					
					// Display footer
					document.getElementById("div_sidefooter").innerHTML = '';
					sidefooter_on=false;
					winResize();

				}
			}
			request.send(null);
			// Root Permissions init end

			break;
	}
}

// =======================================================================================================
// ================================================ viewMode END =========================================
// =======================================================================================================

// toggles a div on or off
function toggleDiv(div){
	if (document.getElementById(div).style.display == "none"){
		document.getElementById(div).style.display = "block";
	} else {
		document.getElementById(div).style.display = "none";
	}
}

// initialises the region forum system in the settings menu.
// Gets forum list via AJAX, populates box select_region_forum_f
// then calls getregions with postexec command to populate the region box
function initRegionForum(){
	var request = GXmlHttp.create();
	var urlstr="gp_read.php?action=forums";
	request.open('GET', urlstr, true);	// request XML from PHP with AJAX call
	request.onreadystatechange = function () {
		if (request.readyState == 4) {
			var xmlDoc = request.responseXML;
			var forums = xmlDoc.documentElement.getElementsByTagName("forum");
			
			var menu ='<table border=0 cellpadding=0 cellspacing=0><tr><td><select name="select_region_forum_f">';
			menu += '<option value="0" selected>'+gp_lang['none'];
			for (var i=0;i<forums.length;i++){
				menu += '<option value="'+forums[i].getAttribute("id")+'">'+forums[i].getAttribute("name");
			}
			menu += '</select></td>';
			menu += '<td align="right"><input type="button" class="button" value="'+gp_lang['submit']+'" onclick="regionForumUpdate(document.form_settings.select_region_forum_r.value,document.form_settings.select_region_forum_f.value);"></center></td></tr></table>';

			document.getElementById("div_region_forum_f").innerHTML=menu;
			getRegions(1, 0, "form_settings", "select_region_forum_r", "div_region_forum_r", "setRegionForum", "forum_id");
		}
	}
	request.send(null);
	
}

// Updates the forum for a region in the database
function regionForumUpdate(region_id, forum_id){
	var request = GXmlHttp.create();
	var urlstr="gp_write.php?action=region_forum&"+queryOptions;
	var sendstr="&regid="+region_id+"&fid="+forum_id;
	request.open('POST', urlstr , true);
	request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); 
	request.onreadystatechange = function () {
		if (request.readyState == 4) {
			var xmlDoc = request.responseXML;
			var replies = xmlDoc.documentElement.getElementsByTagName("reply");
			if (replies[0].getAttribute("id")==1){
				userMessage (gp_lang['setting_ok']+gp_lang['please_refresh']);
			} else {
				userMessage ("ERROR: "+replies[0].getAttribute("message"));
			}
		}
	}
	request.send(sendstr);
}

// Sets the forum list in settings mode to the forum selected for that region
function setRegionForum(regid){
	// Find which item in the menu is the selected one and set it.
	for (var i=0;i < document.form_settings.select_region_forum_f.options.length;i++){
		if (document.form_settings.select_region_forum_f.options[i].value == regid){
			document.form_settings.select_region_forum_f.selectedIndex = i;
			break;
		}
	}
}

// =========================================== User / Group Select Popup Start ==================================

// Adds a group to the region permissions list
// called by popup php script, may well not be used in this script.
function addRegionGroup(id,name){
	if (currentmode == GP_EDIT_MODE){
		var destinationList = window.document.form_pointform.PointBunchGroups;
	} else if (currentmode == GP_SETTINGS_MODE){
		var destinationList = window.document.form_settings.RootGroups;
	}
	$ctr=0;
	for(var i = 0; i < destinationList.options.length; i++) {
		if (destinationList.options[i] != null){
			if (destinationList.options[i].value == id){	// user already in list
				$ctr++;
				break;
			}
		}
	}
	if ($ctr == 0){	// no matches - add user
		destinationList.options[destinationList.options.length] = new Option(name, id );
	}
}

// Adds a user to the region permissions list
// called by popup php script, may well not be used in this script.
function addRegionUser(id,name){
	if (currentmode == GP_EDIT_MODE){
		var destinationList = window.document.form_pointform.PointBunchUsers;
	} else if (currentmode == GP_SETTINGS_MODE){
		var destinationList = window.document.form_settings.RootUsers;
	}
	$ctr=0;
	for(var i = 0; i < destinationList.options.length; i++) {
		if (destinationList.options[i] != null){
			if (destinationList.options[i].value == id){	// user already in list
				$ctr++;
				break;
			}
		}
	}
	if ($ctr == 0){	// no matches - add user
		destinationList.options[destinationList.options.length] = new Option(name, id );
	}
}

// Deletes an item from a select list
function delListItem(tmpitem){
	var i=tmpitem.selectedIndex;
	if (i >= 0){	// will be -1 if nothing selected.
		tmpitem.options[i] = null;
	}
}

// opens a small size window (users)
function small_window(url,id) {
	var config = 'scrollBars=yes,resizable=yes,toolbar=no,menubar=no,location=no,directories=no,width=300,height=120';
	var newWindow = window.open(url, id, config);
}

// opens a medium sized window (groups)
function med_window(url,id) {
	var config = 'scrollBars=yes,resizable=yes,toolbar=no,menubar=no,location=no,directories=no,width=400,height=220';
	var newWindow = window.open(url, id, config);
}

// ============================ User / Group Select Popup end ===========================

// beep function - for debugging
function beep(){
	java.awt.Toolkit.getDefaultToolkit().beep();
}

// debug message function - prints passed string in div_debug.
function decho(string){
	if (settings['debug_mode']==1 && isAdmin){	// only show in settings mode and if a phpBB admin
		GLog.writeHtml(string);
		//document.getElementById("div_debug").innerHTML+=string+"<br>";
	}
}

// called when window is resized and on start
// Attempts to size the map so it is viewable without scrolling
// also determines size of sidepanel and it's header and footer
// should now be cross-browser (IE / FF)
function winResize(){
	var bodyHeight=parseInt((document.body.clientHeight / 100) * 80);
	var paneldiv = document.getElementById('div_sidepanel_cont');
	paneldiv.style.height=bodyHeight+"px";
	var mapdiv = document.getElementById('div_map');
	mapdiv.style.height=bodyHeight+"px";

	var tmpVar=0;	
	var paneldiv = document.getElementById('div_sideheader');
	if (sideheader_on){
		paneldiv.style.height="20px";
		tmpVar += 20;
	} else {
		paneldiv.style.height="0px";
	}
		paneldiv = document.getElementById('div_sidefooter');
	if (sidefooter_on){
		paneldiv.style.height="20px";
		tmpVar += 20;
	} else {
		paneldiv.style.height="0px";
	}
	paneldiv = document.getElementById('div_sidepanel');
	paneldiv.style.height=(bodyHeight-tmpVar)+"px";
	if (maploaded){
		// trigger resize event
		if (isset(map.checkResize)){	// API Version
			map.checkResize();	// V2
		} else {
			map.onResize();	// V1
		}
	}
}

// =========================== Formatted Print Function =======================
// useage: sprintf("The answer to life, the universe, and everything is: %s", ["42"]);
function sprintf(S, L) {
	var nS = "";
	var tS = S.split("%s");
	if (tS.length > 1){
		if (tS.length != L.length+1) return "sprintf error";
		for(var i=0; i<L.length; i++){
			nS += tS[i] + L[i];
		}
		return nS + tS[tS.length-1];
	} else {
		return S;
	}
}

// Show or Hide a Marker
function markerDisplay(marker,show) {
	var i = marker.markerindex;
	if (show){
		map.addOverlay(markers[i]);
		hiddenEditMarker=false;
	} else {
		map.removeOverlay(markers[i]);
		hiddenEditMarker=marker;
	}
	/*
	for (var i=0; i < marker.images.length; i++) { 
		marker.images[i].style.display = (show ? "" : "none");
		hiddenEditMarker = (show ? false : marker);
	}
	*/
}

// Show or Hide a Line
function lineDisplay(marker,show) {
	if (show){
		map.addOverlay(polylines[marker.polyline]);
	} else {
		map.removeOverlay(polylines[marker.polyline]);	// remove overlay
	}
}

// Called when a temporary marker is clicked in edit mode.
function clickTempMarker(overlay){
	if (overlay.markertype=="add"){	// ---------------- START MARKER -------------------
		if (getLocationMode()==GP_LINE_TYPE){	// Line Type
			if (editpath.length==1){	// last icon left
				// remove
				editpath=[];
				document.form_pointform.PointLng.value='';
				document.form_pointform.PointLat.value='';
				document.form_pointform.PointLine.value='';
				plotTempMarkers();	// redraw line
			} else {	// start of line
				editpath.shift();	// remove first item
				plotTempMarkers();	// redraw line
				// update lng, lat boxes in form (they hold first point in case user switches to point mode)
				document.form_pointform.PointLng.value = rndVar(editpath[0][0]);
				document.form_pointform.PointLat.value = rndVar(editpath[0][1]);
			}
		} else {	// Point Type
			// do not delete only point in point mode when editing
			infowindowMain(overlay.markerindex);	// openinfowindow
		}
	} else if (overlay.markertype=="end"){	// ------------------------------- END MARKER -------------
		if (getLocationMode()==GP_LINE_TYPE){	// Line Type
			
		} else {	// Point Type
			document.form_pointform.PointLng.value = rndVar(editpath[0][0]);
			document.form_pointform.PointLat.value = rndVar(editpath[0][1]);
		}
		editpath.pop();	// remove last item in line
		plotTempMarkers();	// redraw line
	}
}

// Actually processes the edit click once the regions box has been set to the right region.
// If this isn't done, then if the user is in a region they can't edit, clicking a marker they could edit will not work
// because the edit boxes will not exist - the sidepanel will contain "You cannot edit points in this region"
function getLocData(){
	var overlay=last_overlay;	// pull overlay data back from global var.
	var obj_setbunch = document.getElementById("div_setbunch");
	var obj_editbunch = document.getElementById("div_editbunch");
	obj_setbunch.style.display="none";
	obj_editbunch.style.display="none";

	removeTempMarkers();
	if (hiddenEditMarker){	// a line was being drawn on a different marker
		// try and find marker
		//could have changed id as we could have re-plotted due to zoom etc
		var j=0;
		for (var i=0;i<markers.length;i++){
			if (hiddenEditMarker.id==markers[i].id){
				markerDisplay(markers[i],true);
				if (markers[i].geometrytype=="LINESTRING"){
					lineDisplay(markers[i],true);
				}
				j++;
				break;
			}
		}
		/*
		if (j==0){	// marker not in cache. chance it ;)
			markerDisplay(hiddenEditMarker,true);
		}
		*/
	}
	editpath=[];
	// store id (ie location_id from locs table) of selected marker
	selected_location=overlay.id;
	// show the edit boxes
	editShowHide(1);		// show edit fields
	// populate boxes
	
	if (markers[overlay.markerindex].fulldata){	// got the full amount of data ?
		editLocData(overlay);	// yes - go straight to populating edit box
		//overlay.openInfoWindowHtml(renderInfowindow(padMainInfowindow(overlay.markerindex)));
		infowindowMain(overlay.markerindex);
	} else {
		// Get full point data
		var request = GXmlHttp.create();
		incEditUID();
		var urlstr="gp_read.php?action=points&"+queryOptions+"&locid="+overlay.id+"&uid="+editUID;
		request.open('GET', urlstr, true);	// request XML from PHP with AJAX call
		request.onreadystatechange = function () {
			if (request.readyState == 4) {
				var xmlDoc = request.responseXML;
				var location = xmlDoc.documentElement.getElementsByTagName("location");
				
				markers[overlay.markerindex].rp_zoom=location[0].getAttribute("rp_zoom");
				if (markers[overlay.markerindex].represents_region > 0){ // bunch point
					//markers[overlay.markerindex].rr_zoom=location[0].getAttribute("rr_zoom");	// zoom value of region it represents (or null)
					markers[overlay.markerindex].bunch_mo=location[0].getAttribute("bunch_mo");	// add mouseover line to marker so we don't have to get it again for this zoom
					markers[overlay.markerindex].rc_zoom=location[0].getAttribute("rc_zoom");
					markers[overlay.markerindex].rr_userlist=location[0].getAttribute("rr_userlist");
					markers[overlay.markerindex].rr_grouplist=location[0].getAttribute("rr_grouplist");
				}
				markers[overlay.markerindex].infowindow=unescape((location[0].getAttribute("infowindow")));
				markers[overlay.markerindex].pointimport=unescape(location[0].getAttribute("import"));
				markers[overlay.markerindex].pointowner=location[0].getAttribute("pointowner");
				markers[overlay.markerindex].topic_id=location[0].getAttribute("topic_id");

				// set fulldata attribute to stop re-grabbing of data for this point.
				markers[overlay.markerindex].fulldata=true;
				
				var uniqueid = xmlDoc.documentElement.getElementsByTagName("request");
				uniqueid=uniqueid[0].getAttribute("uniqueid");	// find the uid of the request
				
				if (editUID==uniqueid && selected_location==overlay.id){
					// only populate the edit box if:
					// another ajax request hasn't been initiated to edit another marker
					// and the selected_location matches the overlay's id
					//overlay.openInfoWindowHtml(renderInfowindow(padMainInfowindow(overlay.markerindex)));
					infowindowMain(overlay.markerindex);
					editLocData(overlay);
				}
			}
		}
		request.send(null);
	}
	
}

// Called when a location marker is clicked. Initiates editing of the marker in edit mode
function clickLocMarker(overlay){
	if (overlay.editable==1 || isAdmin){	// as long as rights to edit
		last_overlay=overlay;
		// seek the region selecter in the edit window to it's region
		getRegions(overlay.region,0,'form_pointform','select_regionselect','div_loc_regions',"getLocData","");
	}	
}

// returns true if an object is "empty"
function isempty(object){
	if (!isset(object)){
		return(true);
	} else {
		if (object == ""){
			return (true);
		} else {
			return (false);
		}
	}
}

// returns true if an object is not false and not unset
function isnf(object){
	if (!isset(object)){
		return (false);
	} else {
		if (object == false){
			return (false);
		} else {
			return (true);
		}
	}
}

// returns true if object type is not "undefined"
function isset(object){
	if (typeof(object) == "undefined"){
		return (false);
	} else {
		return (true);
	}
}

// Takes the attributes from an overlay and populates the edit box accordingly
function editLocData(overlay){
	var obj_setbunch = document.getElementById("div_setbunch");
	var obj_editbunch = document.getElementById("div_editbunch");

	obj_setbunch.style.display="block";
	if (overlay.geometrytype=="LINESTRING"){	// is a line
		document.form_pointform.PointLine.value=overlay.geometry;
		if (document.form_pointform.radio_typebutton){
			document.form_pointform.radio_typebutton[GP_POINT_TYPE].checked=false;
			document.form_pointform.radio_typebutton[GP_LINE_TYPE].checked=true;
		}
		// disable lng lat boxes but do not clear - they wil hold the values of the start of the line
		document.form_pointform.PointLat.disabled = true;
		document.form_pointform.PointLng.disabled = true;
	} else {					// is a point
		// set mode
		if (document.form_pointform.radio_typebutton){
			document.form_pointform.radio_typebutton[GP_POINT_TYPE].checked=true;
			document.form_pointform.radio_typebutton[GP_LINE_TYPE].checked=false;
		}
		// enable lng lat boxes
		document.form_pointform.PointLat.disabled = false;
		document.form_pointform.PointLng.disabled = false;
		// populate lng lat boxes
		document.form_pointform.PointLng.value = overlay.lng;
		document.form_pointform.PointLat.value = overlay.lat;
		// clear line box
		document.form_pointform.PointLine.value="";
	}
	// Set category
	getCategories(overlay.category,0,0,"form_pointform","select_categoryselect","div_loc_categories");
	
	// Bunch Point section
	editZoomRange(overlay.rc_zoom,overlay.rp_zoom);
	if (overlay.represents_region==0){	// not bunch point
		// Not bunch point - add button to make bunch point.
		document.form_pointform.PointBunch.value="ON";
		document.form_pointform.PointBunch.checked=false;
		document.form_pointform.PointBunch.disabled=false;
	} else {	// 	Bunch point
		obj_editbunch.style.display="block";
		if (overlay.childcount==0){
			// No children - allow changing back to non-bunch point
			document.form_pointform.PointBunch.value="ON";
			document.form_pointform.PointBunch.checked=true;	
			document.form_pointform.PointBunch.disabled=false;
		} else {
			// Has children - do not allow changing back to non-bunch point.
			document.form_pointform.PointBunch.value="ON";
			document.form_pointform.PointBunch.checked=true;	
			document.form_pointform.PointBunch.disabled=true;
		}
		//document.form_pointform.PointZoom.disabled=true;
		selectOption(document.form_pointform.PointZoom,overlay.rr_zoom);
		//document.form_pointform.PointZoom.value = overlay.rr_zoom;
		// populate user permissions list for bunch point with current list
		document.form_pointform.PointBunchUsers.length=0;
		
		// Region Permissions
		if (!isempty(overlay.rr_userlist)){
			var users=overlay.rr_userlist.split(",");	// split into records
			for (var j = 0;j<users.length;j++){
				var user=users[j].split(":");	// split IDs and names
				document.form_pointform.PointBunchUsers.options[j] = new Option(user[1],user[0]);
			}
		}
		if (!isempty(overlay.rr_grouplist)){
			var groups=overlay.rr_grouplist.split(",");	// split into records
			for (var j = 0;j<groups.length;j++){
				var group=groups[j].split(":");	// split IDs and names
				document.form_pointform.PointBunchGroups.options[j] = new Option(group[1],group[0]);
			}
		}
		document.form_pointform.PointBunchMo.value=overlay.bunch_mo;
	}
	document.form_pointform.PointName.value = overlay.name;
	document.form_pointform.PointImport.value = overlay.pointimport;
	document.form_pointform.PointInfowindow.value = overlay.infowindow;
	if (settings['htmlarea'] == 1){
		PointInfowindow_editor.setHTML(document.form_pointform.PointInfowindow.value);
	}

	if (document.form_pointform.PointBunch.checked==false){
		eval(delete_button[0]+"='"+delete_button[1]+"'");	// insert delete button
	} else {
		eval(delete_button[0]+"='&nbsp'");	// remove delete button
	}
	
	markerDisplay(overlay,false);		// hide marker being edited
	if (overlay.geometrytype=="LINESTRING"){ // Line Mode
		lineDisplay(overlay,false);		// hide line being edited
	}
	plotTempMarkers();

}

// called when the background is clicked
function clickBackground(point2){
	var point = new Array();
	if (isset(point2.lngDegrees)){
		point.x = point2.lngDegrees;
		point.y = point2.latDegrees;
	} else {
		point=point2;
	}
	if (currentmode == GP_EDIT_MODE){	// we are in edit mode
		if (getLocationMode()==GP_POINT_TYPE){	// ----------------- POINT TYPE ----------------
			if (selected_location){	// if we are editing a point
				if (editpath.length){
					editpath[1]=new Array(rndVar(point.x),rndVar(point.y));	// set end (point 1) to clicked point
				}
			} else {	// new point - no from / to line
				editpath=[];	// just in case
				editpath[0]=new Array(rndVar(point.x),rndVar(point.y));	// set end (point 1) to clicked point
			}
			document.form_pointform.PointLng.value = rndVar(point.x);
			document.form_pointform.PointLat.value = rndVar(point.y);
			plotTempMarkers();
		} else {	// --------------------------------------------------------------------- LINE TYPE --------------------
			if (!editpath.length){	// if start of line
				document.form_pointform.PointLng.value = rndVar(point.x);
				document.form_pointform.PointLat.value = rndVar(point.y);
			}
			// ToDo: Populate the native box on the form
			editpath[editpath.length]=new Array(rndVar(point.x),rndVar(point.y));	// add point to end of path
			plotTempMarkers();
		}
	}
	if (selected_location == false){
		eval(add_button[0]+"='"+add_button[1]+"'");	// insert edit button
		eval(edit_button[0]+"='&nbsp'");						// remove add button
	} else {
		eval(edit_button[0]+"='"+edit_button[1]+"'");	// insert edit button
		eval(add_button[0]+"='&nbsp'");						// remove add button
	}
	//getRegions(overlay.region,0,'form_pointform','select_regionselect','div_loc_regions');
}

// Finds out if we are in point or line mode
function getLocationMode(){
	if (document.form_pointform){
		if(document.form_pointform.radio_typebutton){
			if(document.form_pointform.radio_typebutton[1].checked){
				return (GP_LINE_TYPE);
			}
		}
	}
	return (GP_POINT_TYPE);
}
