//-------------------------------- Geocoding Section ------------------------------------//
function geocodeAddress(country, geocode, search, selector, selForm, selBox, message, srs, addressIn) 
{
	//------------------------------------------------------------------------------------------------//
	//
	//	Country : text string used to limit the geocode to australia NZ
	//	geocode	: text string defining the Div that contains all the address entry divs 
	//	search	: text string defining the Div Id of INPUT element of address 
	//  selector: text string defining the Div that contains all the address selection divs
	//	selForm	: text string defining the Form element that is used to select from list of addresses
	//	selBox	: text string defining the Class name of the selForm
	//	message	: text string defining the Div of the message regarding too many points returned
	//	srs		: EPSG code for this map
	//  addressIn : Optional Address entry - if this is present it is assumed to be a lat,lon string 
	//
	//------------------------------------------------------------------------------------------------//
	if(addressIn != '') { var address = addressIn;}
	else
	{	// get the address from a form Input element
		var address= document.getElementById(search).value;
	}
			
	// either geocode the address or jump to its location	
	if(!goToCoords(address, false))
	{
		// make sure all %20 are removed from address string source
		address = address.replace(/%20/g, ' ');
		var searchRequest = address +" "+country;
		
		//alert('address = '+searchRequest)
		
		//--------------- This will get up to 10 matched addresses --------------------//        
		geocoder.getLocations(searchRequest, function (result)
		{ 
			if(result.Status.code == G_GEO_SUCCESS)
			{
				var currentAccuracy = result.Placemark[0].AddressDetails.Accuracy;
				no = result.Placemark.length;
				//alert('address = '+searchRequest+ '  currentAccuracy = '+currentAccuracy+" no = "+no)
				
				// Clear out any orphan markers
				if (markers) {	markers.clearMarkers(); }
				
				// initialise the geocoder selection boxes
				//var ent = document.getElementById(geocode);
				var sel = document.getElementById(selector);
				//loLat=999999999; hiLat=-999999999; loLng=99999999; hiLng=-99999999;

				// Check is comboBox present and if so kill it off
				checkRemoveObject('addropts')
				
				// when there are more than a single match
				if (no > 1) 
				{								
					// build the select box of candidate addresses
					var form = document.getElementById(selForm);

					// create the temp combo Div
					var comboDiv = document.createElement('div');
					comboDiv.id='addropts';
					comboDiv.setAttribute('id','addropts');
					
					// Ok now get all the candidate addresses as Options
					for (var i=0; i<no; i++)
					{							
						// get all address candidates from Google
						var addrs = result.Placemark[i].address;
						var p = result.Placemark[i].Point.coordinates;	// returned as lon/lat objects
						
						// save coords for lat lon output
						pString = p.toString();
						lonLatParts = pString.split(',');
						latLon = lonLatParts[1]+','+lonLatParts[0];				
						
						// transform geogs to spherical coords if required
						if (srs == 'EPSG:900913') 
						{
							var point = geogs2google(p);
							p = decodePoint(point);
						}
						var point = new OpenLayers.LonLat(p[0], p[1]);

						// stepwise calculate centre of gravity of addresses collection and zoom to it
						//adjustBoundsExtent(p[1],p[0],i);
							
						// add the choices as options to the combo select element
						var optionElement = document.createElement("input");
						optionElement.type='radio';
						//optionElement.setAttribute('type','radio')					
						optionElement.checked='';
						
						// set up the radio button element
						var currentAccuracy = result.Placemark[i].AddressDetails.Accuracy;
						optionElement.value = addrs+" "+point+":"+currentAccuracy;
						optionElement.nodeVale = addrs;
						optionElement.title='If you cannot find a suitable match then you will need to refine your search above';
						optionElement.id='opt:'+i; 
						optionElement.setAttribute('id','opt:'+i);
						optionElement.name='selForm'; 
						optionElement.setAttribute('name','selForm');
						bindEvent(optionElement, 'click', selectAddressOpt, 'true')
						comboDiv.appendChild(optionElement);						

						//create a text string of address + lon lat object
						var textDiv = document.createElement('span');
						textDiv.className = 'radioText';
						textDiv.title = addrs+" ("+latLon+" : "+accuracyDesc[currentAccuracy]+')';
						var optionText = document.createTextNode(addrs);
						textDiv.appendChild(optionText);
						comboDiv.appendChild(textDiv);

						// create a new line
						var newLine = document.createElement('br');
						comboDiv.appendChild(newLine);			
					}
					// finalise Select Options
					form.appendChild(comboDiv);
					sel.style.display="block";
					
				}
				else if (no == 1 && result.Placemark[0].AddressDetails.Accuracy>3 )
				{
					// Toggle off the address entry Div
					document.getElementById(selector).style.display='none';
					
					
					// Only one in collection so plot it only
					var p = result.Placemark[0].Point.coordinates;
					var currentAccuracy = result.Placemark[0].AddressDetails.Accuracy;
					//displayAccuracy(currentAccuracy);
					//alert('currentAccuracy = '+currentAccuracy)
										
					// transform geogs to google if required
					if (srs == 'EPSG:900913') 
					{	point = geogs2google(p);	}
					else
					{	point = new OpenLayers.LonLat(p[0], p[1]);	}
					p = decodePoint (point);
					
					// create the marker on the map
					var currentAddress = result.Placemark[0].address;
					var enterAddress = currentAddress.replace(/,/g, ' ');
					document.getElementById(search).value = enterAddress;
					if(document.getElementById('search01')){document.getElementById('search01').value = enterAddress;}

					// create the vector icon on map at this location		
					//createVectorIcon(p[0], p[1], address);		
					markers = new OpenLayers.Layer.Markers( searchRequest );
					map.addLayer(markers);
					createIcon(p[0], p[1], symbol, '20', '20');	

					// now just go to the selected location
					//var zoom = parseInt(markerZm);
					//map.setCenter(new OpenLayers.LonLat(p[0],p[1]), goToZoom);
					map.setCenter(new OpenLayers.LonLat(p[0],p[1]), map.getZoom());
				}
			}
		});
	}
}

function goToCoords(address, showMarker)
{
	// Clear out any orphan markers
	if (markers) {	markers.clearMarkers(); }

	// check to see if input string is a lat/long
	var p = [];
	var parts = address.split(',');
	if(parts.length > 1) 
	{	// change lat/long coords to map coords
		p[0] = parts[1];
		p[1] = parts[0];
		if (srs == 'EPSG:900913') 
		{	var point = geogs2google(p);		}
		else
		{	var point = new OpenLayers.LonLat(p[0], p[1]);	}
		p = decodePoint (point);
		
		// plot marker
		if(showMarker)
		{	// create the vector icon on map at thgis location		
			//createVectorIcon(p[0], p[1], address);
			markers = new OpenLayers.Layer.Markers( address );
			map.addLayer(markers);		
			createIcon(p[0], p[1], symbol, '20', '20');	
		}

		// jump to this location
		map.setCenter(new OpenLayers.LonLat(p[0], p[1]), startZoom);

		return true;
	}
	else{ return false;	}
}


function displayAccuracy(currentAccuracy)
{
	//alert('geocoded to '+accuracyDesc[currentAccuracy]+ ' accuracy')
	checkRemoveObject('accId');
	var accObj = document.getElementById('geocodeAcc');
	var textDiv=document.createElement('span');				
	textDiv.id='accId';
	textDiv.setAttribute('id','accId');
	textDiv.className = 'label';
	textDiv.title = 'Geocoded to '+accuracyDesc[currentAccuracy]+ ' accuracy';
	var text = document.createTextNode('('+accuracyDesc[currentAccuracy]+')');
	textDiv.appendChild(text);
	accObj.appendChild(textDiv);
}

// --------------- function to set map to the address selected by the user from a select box
function selectAddressOpt (evt, id)
{
	// Get the selected address and its location from the select element
	if(evt != null) {id = getThisId(evt);}
	if(!document.getElementById(id)) {return;}
	var fullAddr = document.getElementById(id).value;
	document.getElementById(id).blur();
	document.getElementById(id).checked=true;

	// echo out the accuracy to user
	var currentAccuracy = fullAddr.split(':')[1];
	//displayAccuracy(currentAccuracy);

	// Toggle off the address selection list Div
	document.getElementById("selectit").style.display='none';

	// get the returned coordinates
	var addressParts = fullAddr.split(' lon');
	var point = 'lon'+addressParts[1];
	currentAddress= addressParts[0];
	var enterAddress = currentAddress.replace(/,/g, ' ');
	document.getElementById('search').value = enterAddress;
	if(document.getElementById('search01')){document.getElementById('search01').value = enterAddress;}

	// decode point back into p 
	var tmpLL = point.toString();
	var tempP = tmpLL.split(',');
	var p = [];
	var lng = tempP[0].split('='); 
	p[0] = lng[1];
	var lat = tempP[1].split('='); 
	p[1] = lat[1];
	
	// create the vector icon on map at thgis location		
	markers = new OpenLayers.Layer.Markers( address );
	map.addLayer(markers);		
	createIcon(p[0], p[1], symbol, '20', '20');	

	// now just go to the selected location
	pointZoom=13;
	map.setCenter(new OpenLayers.LonLat(p[0],p[1]), pointZoom);

}





//-------------------------------- Geocoding Section ------------------------------------//
function showAddress(country, geocode, search, selector, selForm, selBox, message, srs, addressIn) 
{
	//------------------------------------------------------------------------------------------------//
	//
	//	Country : text string used to limit the geocode to australia NZ
	//	geocode	: text string defining the Div that contains all the address entry divs 
	//	search	: text string defining the Div Id of INPUT element of address 
	//  selector: test string defining the Div that contains all the address selection divs
	//	selForm	: text string defining the Form element that is used to select from list of addresses
	//	selBox	: text string defining the Class name of the selForm
	//	message	: text string defining the Div of the message regarding too many points returned
	//	srs		: EPSG code for this map
	//  addressIn : Optional Address entry - if this is present it is assumed to be a lat,lon string 
	//
	//------------------------------------------------------------------------------------------------//
	
	if(addressIn) { var address = addressIn;}
	else
	{	// get the address from a form Input element
		var address= document.getElementById(search).value;
	}
	// check to see we have something
	if (address == '' || address == null){return false;}
	//alert('addressIn again = '+addressIn)
	// either geocode the address or jump to its location	
	if(!goToCoords(address))
	{
		// make sure all %20 are removed from address string source
		address = address.replace(/%20/g, ' ');
		var searchRequest = address +" "+country;
		
		//--------------- This will get up to 10 matched addresses --------------------//        
		geocoder.getLocations(searchRequest, function (result)
		{ 
			// initialise the geocoder selection boxes
			var ent = document.getElementById(geocode);
			var sel = document.getElementById(selector);
			loLat=999999999; hiLat=-999999999; loLng=99999999; hiLng=-99999999;

			// Check is comboBox present and kill it off
			checkRemoveObject('combo')
			
			// Clear out any orphan markers
			if (markers) 
			{
				markers.clearMarkers(); 
				markers.addOptions({'displayInLayerSwitcher': false});
			}	
					
			// If all is well go and get the geocodes for the address 
			if (result.Status.code == G_GEO_SUCCESS) 
			{		  
				// If there are 10 returns then tell the user what to expect
				var no = result.Placemark.length
				if (result.Placemark.length == 10)
				{	document.getElementById(message).style.display='block';	}
					
				// we have more than 1 address candidate so go and build the drop down select box
				if (no > 1) 
				{				
					// build the select box of candidate addresses
					var form = document.getElementById(selForm);
					var comboBox = document.createElement("select");
					comboBox.setAttribute('id','combo');
					comboBox.id = "combo";
					comboBox.setAttribute('size','1');
					bindEvent(comboBox, 'change', selectAddress, 'false')

					// create each marker on the map
					markers = new OpenLayers.Layer.Markers( searchRequest );
					map.addLayer(markers);
					
					// write instructions into the first option of the select box
					var optionElement = document.createElement("option");
					var optionText = document.createTextNode("... Select From Address Candidates ...");
					optionElement.appendChild(optionText);
					comboBox.appendChild(optionElement);
					
					// Ok now get all the candidate addresses as Options
					for (var i=0; i<no; i++)
					{	
						// set the init flag after first time thru
						var init = false; if (i==0){init = true}
						
						// get all address candidates from Google
						var addrs = result.Placemark[i].address;
						var p = result.Placemark[i].Point.coordinates;	// returned as lon/lat objects
						
						// transform geogs to spherical coords if required
						if (srs == 'EPSG:900913') 
						{
							var point = geogs2google(p);
							// decode point back into array of lat longs
							p = decodePoint(point);
						}
						else
						{	var point = new OpenLayers.LonLat(p[0], p[1]);	}

						// stepwise calculate centre of gravity of addresses collection and zoom to it
						adjustBoundsExtent(p[1],p[0],i);
							
						// add the choices as options to the combo select element
						var optionElement = document.createElement("option");
						point = new OpenLayers.LonLat(p[0], p[1]);
						
						//create a text string of address + lon lat object
						var optionText = document.createTextNode(addrs+" "+point);
						optionElement.value = addrs+" "+point;
						optionElement.appendChild(optionText);
						comboBox.appendChild(optionElement);
				
						// draw an icon at each location in collection
						createIcon(p[0],p[1], symbol, '20', '20');	
						
					}
					// finalise Select Options
					//lastAccuracy = 0;
					comboBox.className = selBox;
					form.appendChild(comboBox);
					sel.style.display="block";
					ent.style.display="none";
					if(document.getElementById('sidebar:3'))
					{	if(document.getElementById('sidebar:3').style.display != 'block')
						{	document.getElementById('sidebar:3').style.display='block';
							toggleControl('expand:3');
						}
					}
					bounds = new OpenLayers.Bounds(loLng,loLat,hiLng,hiLat);
					map.setCenter(bounds.getCenterLonLat(),map.getZoomForExtent(bounds)-1); // this will zoom appropriately for collection
			
				}

				// we only have one address so jump to it
				else if (no == 1)
				{
					// Only one in collection so plot it only
					var p = result.Placemark[0].Point.coordinates;
					var currentAccuracy = result.Placemark[0].AddressDetails.Accuracy;
					//alert('currentAccuracy = '+currentAccuracy)
					//if(currentAccuracy <= 4){pointZoom = 12;}
					//if(currentAccuracy >4 && currentAccuracy < 7){pointZoom = 17;}
					//if(currentAccuracy >7){pointZoom = 18;}
					//alert('startBasemap = '+startBasemap)
					//if(startBasemap == 'nearmap'){pointZoom = pointZoom+3;	} 
					pointZoom=goToZoom;
					
					// transform geogs to google if required
					if (srs == 'EPSG:900913') 
					{	point = geogs2google(p);	}
					else
					{	point = new OpenLayers.LonLat(p[0], p[1]);	}
					
					// create the marker on the map
					var addrs = result.Placemark[0].address;				
					markers = new OpenLayers.Layer.Markers( searchRequest );
					map.addLayer(markers);
					p = decodePoint (point);
					createIcon(p[0], p[1], symbol, '20', '20');	
					
					// if parcel layer selected by user
					var tester = boundaryRequired();
			
					// either plot and move-to the single point or generate the boundary and plot move-to that
					if(tester == 'NONE' || tester == '' || currentAccuracy < 8) 
					{	
						//alert('pointZoom 2 = '+pointZoom);
						//alert('point = '+point);
						map.setCenter(point, pointZoom);
						
						// make a Map request link
						var output = makeMapRequest(applicationBase, srs, address, point, pointZoom, 450, 700, startBasemap, account)
						
						// send map link to a div called 'link'
						if(document.getElementById('link'))
						{
							//alert('output= '+output)
							//alert('url = '+window.location.href)
							document.getElementById('link').href=output;
							document.getElementById('link').title=output;
						}
					
					}	
					else
					{	showBoundary('propertyControl', point); 	}
					
				}
			}			
			//---------------------------- Decode the error status -----------------------------------//
			else
			{
				var reason="Code "+result.Status.code;
				if (reasons[result.Status.code]) 
				{
					reason = reasons[result.Status.code]
				} 
				alert('Could not find "'+searchRequest+ '" ' + reason);
			}
			
	   });
	  
	   return;
	}
	else { return;}
}
function makeMapRequest(url, srs, address, point, zoom, height, width, basemap, account)
{
	if(point !='' && point != null)
	{
		// convert location point into latlon string
		var pnt = [];
		if(srs == 'EPSG:900913')
		{
			// convert point to lat longs
			pnt[0] = point.lon;
			pnt[1] = point.lat;
			var lonlat = decodePoint(google2geogs(pnt));
			//alert('lonlat = '+lonlat)
			//loLeft = decodePoint(point);
			var startString = 'start='+lonlat[1]+','+lonlat[0];
		}
		else
		{
			var startString = 'start='+point.lat+','+point.lon;
		}
	}
	else if(address != '' || address != null)
	{
		var startString = '&start='+address;
	}
	// now build up the remaining getmap string
	var output = url+'solarq/solarQuoteMap.html?'+startString+'&height='+height+'&width='+width+'&zoom='+zoom+'&basemap='+basemap;
	return output;
}

function adjustBoundsExtent(glat, glng, number)
{
	//alert ("numb = "+numb)
	//alert ("numb = "+number+" BBox = "+loLat+", "+loLng+" "+hiLat+", "+hiLng);
	//Convert Lat and Long to numerical values
	var lat=parseFloat(glat);
	var lng=parseFloat(glng);

	// add points into sumLat and sumLng
	//if (number == 0){alert ("initialising limits"); loLat=lat; hiLat=lat; loLng=lng; hiLng=lng;}

	// calculate bounding box of coords	
	if (lat < loLat) {loLat=lat;}
	if (lat > hiLat) {hiLat=lat;}
	if (lng < loLng) {loLng=lng;}
	if (lng > hiLng) {hiLng=lng;}
}



// --------------------- Create an icon at the position desired ---------------------------- //
function createIcon(lng, lat, symbol, wd, ht)
{
	var size	= new OpenLayers.Size(wd, ht);
	var offset	= new OpenLayers.Pixel(-(size.w/2), -size.h/2);
	var icon	= new OpenLayers.Icon(symbol, size, offset);	
	marker		= new OpenLayers.Marker(new OpenLayers.LonLat(lng, lat), icon);
	markers.addMarker(marker);
	
	markers.setOpacity(0.7);
	if(document.getElementById('targetButt'))
	{
		document.getElementById('targetButt').className="hoverButton"	;
		document.getElementById('targetControl').title='hide targets at locations';
	}
	markers.events.register('click', marker, function(evt) { markers.clearMarkers(); OpenLayers.Event.stop(evt); });
	markers.setZIndex(map.Z_INDEX_BASE['Popup'] -1000);
	return markers;
}

// --------------- function to set map to the address selected by the user from a select box
function selectAddress (evt)
{
	var combo_Id = getThisId(evt)
	
	// Get the selected address and its location from the combo box
	var comboBox = document.getElementById(combo_Id);
	if (comboBox.selectedIndex == 0){return;}
	var fullAddr = comboBox.options[comboBox.selectedIndex].value;
	var addressParts = fullAddr.split(' lon');
	var point = 'lon'+addressParts[1];

	// decode point back into p 
	var tmpLL = point.toString();
	var tempP = tmpLL.split(',');
	var p = [];
	var lng = tempP[0].split('='); p[0] = lng[1];
	var lat = tempP[1].split('='); p[1] = lat[1];
	if (markers) {markers.clearMarkers(); markers.addOptions({'displayInLayerSwitcher': false});}	
	createIcon(p[0],p[1], symbol, '40', '40');	
	//map.setCenter(new OpenLayers.LonLat(p[0],p[1]), pointZoom);	
	//if(document.getElementById(message)) {document.getElementById(message).style.display='none';}

	// push selected address into the search box
	currentAddress = addressParts[0].replace(/,/g, ' ');
	if(document.getElementById("search01")){document.getElementById("search01").value = currentAddress;	}
	if(document.getElementById("search")){document.getElementById("search").value = currentAddress;	}

	// make sure the select buttons are swapped around
	//document.getElementById('geocodeButt2').style.display='none';
	//document.getElementById('geocodeButt').style.display='block';

	// showBoundary
	var tester = boundaryRequired();
	if(tester != 'NONE' && tester != '')
	//if(document.getElementById('propertyControl'))
	{
		//document.getElementById('propertyControl').title = 'show boundary at address';
		lastAccuracy=-1;
		showBoundary('propertyControl', ""); 
	}
	else
	{	
		map.setCenter(new OpenLayers.LonLat(p[0],p[1]), startZoom);		
	}
	
	//n off the message popup
	//if(document.getElementById(message)) 
	//{	
		document.getElementById(message).style.display='none';	
	//}
	resetZlevels();
}

 function searchon(selector, geocode, search, message)
 {
	if (markers) 
	{
		markers.setVisibility(false); 
		if(document.getElementById('targetButt'))
		{
			document.getElementById('targetButt').className="standardButton"	;
			document.getElementById('targetControl').title='show targets at locations';
		}
	}	
	if(document.getElementById('propertyButt'))
	 {
		document.getElementById('propertyButt').className="standardButton"	;
		document.getElementById('propertyControl').title='show boundary at address';
		if(boundary){boundary.setVisibility(false);}
	 }

	document.getElementById(selector).style.display="none";
	document.getElementById(message).style.display='none';
	document.getElementById(geocode).style.display="block";
	document.getElementById(search).value ='';
	if(document.getElementById('search'))
	{ document.getElementById(search).value =document.getElementById('search').value;	 }
	else {document.getElementById(search).value ='';}
	
	// set the focus to the address data entry box
	document.getElementById(search).focus();
 }

// ------------------ function to check if object exists and if so remove it --------------------
function checkRemoveObject(oId)
{
	if (document.getElementById(oId))
	{	
		var obj = document.getElementById(oId);
		obj.parentNode.removeChild(obj);
		obj.value=null;
		//alert('object '+oId+' removed')
	}
}


