/*function appendCell(theCell, theTable, perRow)
{
	length=theTable.rows.length
	currentRow=theTable.rows[length - 1];
	if(currentRow.cells.length >= perRow)
	{
		currentRow=theTable.insertRow(length);
	}
	currentRow.appendChild(theCell);
}
*/

function appendCell(thisCell, thisTable, perRow)
{
	var thisLength=thisTable.rows.length;
	var last=thisLength - 1;
	var currentRow='';
	if(thisLength==0)
	{
		thisTable.insertRow(0);
		thisLength=thisTable.rows.length;
		last=thisLength - 1;
	}
	var currentRow=thisTable.rows[last];
	if(currentRow.cells.length >= perRow)
	{
		currentRow=thisTable.insertRow(thisLength);
	}
	currentRow.appendChild(thisCell);
}

function emptyTable(theTable) //more complex. Don't delete row if you want to reuse parts of it in internet Explorer
{
	if(theTable.nodeName=='table' || theTable.nodeName=='tbody')
	{
		alert('emptyTable called with an argument of type "' + theTable.nodName +'". Can only be called with arguments of type "table" or "tbody"');
		return -1;
	}
	if(theTable.firstChild.nodeName=='tbody')
		theTable=theTable.firstChild;
	theRows=theTable.rows;
	numberOfRows=theRows.length;
	for(i=0;i<numberOfRows;i++)
	{
		var currentRow=theRows[i];
		var theCells=currentRow.cells;
		rowLength=theCells.length;
		for(j=0;j<rowLength;j++)
		{
			var currentCell=theCells[0];
			currentCell.parentNode.removeChild(currentCell);
		}
	}
	
}

/*
function emptyTable(theTable)
{
	if(theTable.nodeName=='table' || theTable.nodeName=='tbody')
	{
		alert('emptyTable called with an argument of type "' + theTable.nodName +'". Can only be called with arguments of type "table" or "tbody"');
		return -1;
	}
	if(theTable.firstChild.nodeName=='tbody')
		theTable=theTable.firstChild;
	numberOfRows=theTable.rows.length;
	for(i=0;i<numberOfRows;i++)
	{
		theTable.deleteRow(0);
	}
	
}
*/

function alpha(str)
{
 str=str.toLowerCase();
 ok=1;
 len=str.length;
var i;
 for(i=0;i<len;i++)
 {
  x=str.charCodeAt(i);
  if((((x != 32)&&(x != 95)) && (((x<48)||(x>57))&&((x<97)||(x>122)))) && (x!=45))
  {
    ok=0; 
  }
 }
 return ok;
}
function removePath(myString)
{
	i=myString.lastIndexOf('/');
	j=myString.lastIndexOf('\\');
	if(j>i)
	{
		i=j;
	}
	i++;
	return myString.substr(i);
}
function MultiSelector(list_target, max)
{
	this.list_target = list_target;
	this.count = 0;
	this.id = 0;
	if(max)
	{
		this.max = max;
	}
	else
	{
		this.max = -1;
	};
	this.addElement = function(element)
	{
		if(element.tagName == 'INPUT' && element.type == 'file')
		{
			element.name = 'file_' + this.id++;
			element.multi_selector = this;
			element.onchange = function()
			{
				var new_element = document.createElement('input');
				new_element.type = 'file';
				this.parentNode.insertBefore(new_element, this);
				this.multi_selector.addElement(new_element);
				this.multi_selector.addListRow( this );
				this.style.position = 'absolute';
				this.style.left = '-1000px';
			};
			if( this.max != -1 && this.count >= this.max )
			{
				element.disabled = true;
			};
			this.count++;
			this.current_element = element;
		}
		else
		{
			alert( 'Error: not a file input element' );
		};
	};
	this.addListRow = function( element )
	{
		var amount=document.getElementById('amount');
		amount.value++;
		var new_row = document.createElement( 'div' );
		var new_row_button = document.createElement( 'span' );
		var myText = document.createTextNode('remove');
		new_row_button.className='blueLink';
		new_row_button.appendChild(myText);
//		new_row_button.type = 'button';
//		new_row_button.value = 'Delete';
		new_row.element = element;
		new_row_button.onclick= function()
		{
			var total=document.getElementById('amount');
			total.value--;
			this.parentNode.element.parentNode.removeChild( this.parentNode.element );
			this.parentNode.parentNode.removeChild( this.parentNode );
			this.parentNode.element.multi_selector.count--;
			this.parentNode.element.multi_selector.current_element.disabled = false;
			return false;
		};
		fileName=removePath(element.value);
		new_row.innerHTML = fileName + '&nbsp&nbsp';
		new_row.appendChild( new_row_button );
		this.list_target.appendChild( new_row );
	};
};
/*****Takes the elements in myArray and clears
out anything in myDrop and fills it with the 
elements from myArray**************************/
function dropIt(myArray, myDrop, text)
{
	if(typeof(myDrop)=='string')
	{
		x=document.forms[0].elements.namedItem(myDrop);
	}
	else
	{
		x=myDrop;
	}
	if(x!=null)
	{
		if(x.tagName=='SELECT')
		{
			if(myArray)
			{
				clearIt(x, 'This doesn\'t matter');
				if(!text)
				text='Select one';
  			len=myArray.length;
				if(len)
				{
  				x.options[0].text=text;
  				x.disabled=false;
				}
				else
				{
					x.options[0].text='none available';
				}
  			for(i=0;i<len;i++)
  			{
    			x.options[i+1]=new Option(myArray[i], myArray[i]);
  			}
			}
			else
			{
				alert('Array doesn\' exist. Remove this warning');
			}	
		}
		else
		{
			alert(x.name + ' is not a select element, it is a ' + x.tagName);
		}
	}
	else
	{
		alert('This is not a valid element in forms[0]');
	}
}
function clearIt(myDrop, text)
{
	if(typeof(myDrop)=='string')
	{
		x=document.forms[0].elements.namedItem(myDrop);
	}
	else
	{
		x=myDrop;
	}
	if(x!=null)
	{
		if(x.tagName=='SELECT')
		{
			total=x.options.length;
			for(i=1;i<total;i++)
			{
				x.options[i]=null;
			}
			x.options.length=1;
			x.options[0].text=text;
			x.disabled=true;
		}
		else
		{
			alert(x.name + ' is not a select element.');
		}
	}
	else
	{
		alert('This is not a valid element in forms[0]');
	}
}
function searchSelect(myValue, mySelect)
{
	if((mySelect.nodeName=='SELECT')&&(myValue!=''))
	{
		myOptions=mySelect.options;
		total=myOptions.length;
		for(i=0;i<total;i++)
		{
			if(myOptions.item(i).value==myValue)
			{
				return i;
			}
		}
	}
	return -1;
}
function selectSelect(myValue, mySelect)
{
	if((mySelect.nodeName=='SELECT')&&(myValue!=''))
	{
		myOptions=mySelect.options;
		total=myOptions.length;
		for(i=0;i<total;i++)
		{
			if(myOptions.item(i).value==myValue)
			{
				mySelect.selectedIndex=i;
			}
		}
	}
	return -1;
}
function setTabs(myForm)
{
	if(typeof(myForm)=='string')
	{
		myForm=document.forms.namedItem(myForm);
	}
	if(myForm.nodeName=='FORM')
	{
		j=1;
		for(i=0;i<myForm.length;i++)
		{
			if((myForm.elements.item(i).nodeName!='INPUT')||((myForm.elements.item(i).nodeName=='INPUT')&&(myForm.elements.item(i).type!='hidden')))
			{
				myForm.elements.item(i).tabIndex=j;
				j++;
			}
		}
	}
	else
	{
		alert('Error 245');
	}
}
function GetTagPixels(StartTag, Direction) {
   var PixelAmt = (Direction == 'LEFT') ? StartTag.offsetLeft : StartTag.offsetTop;
   while ((StartTag.tagName != 'BODY') && (StartTag.tagName != 'HTML')) {
      StartTag = StartTag.offsetParent;
      PixelAmt += (Direction == 'LEFT') ? StartTag.offsetLeft : StartTag.offsetTop;
   }
   return PixelAmt;
}

/* Base64 conversion methods.
 * Copyright (c) 2006 by Ali Farhadi.
 * released under the terms of the Gnu Public License.
 * see the GPL for details.
 *
 * Email: ali[at]farhadi[dot]ir
 * Website: http://farhadi.ir/
 */

//Encodes data to Base64 format
if(typeof(btoa)!= 'function')
{
	var btoa = function(data)
	{
		if (typeof(btoa) == 'function') return btoa(data);//use internal base64 functions if available (gecko only)
		var b64_map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
		var byte1, byte2, byte3;
		var ch1, ch2, ch3, ch4;
		var result = new Array();
		var j=0;
		for (var i=0; i<data.length; i+=3) {
			byte1 = data.charCodeAt(i);
			byte2 = data.charCodeAt(i+1);
			byte3 = data.charCodeAt(i+2);
			ch1 = byte1 >> 2;
			ch2 = ((byte1 & 3) << 4) | (byte2 >> 4);
			ch3 = ((byte2 & 15) << 2) | (byte3 >> 6);
			ch4 = byte3 & 63;
			
			if (isNaN(byte2)) {
				ch3 = ch4 = 64;
			} else if (isNaN(byte3)) {
				ch4 = 64;
			}

			result[j++] = b64_map.charAt(ch1)+b64_map.charAt(ch2)+b64_map.charAt(ch3)+b64_map.charAt(ch4);
		}

		return result.join('');
	}
}
//Decodes Base64 formated data
if(typeof(atob)!='function')
{
	atob=function(data)
	{
		data = data.replace(/[^a-z0-9\+\/=]/ig, '');// strip none base64 characters
		if (typeof(atob) == 'function') return atob(data);//use internal base64 functions if available (gecko only)
		var b64_map = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
		var byte1, byte2, byte3;
		var ch1, ch2, ch3, ch4;
		var result = new Array();
		var j=0;
		while ((data.length%4) != 0) {
			data += '=';
		}
	
		for (var i=0; i<data.length; i+=4) {
			ch1 = b64_map.indexOf(data.charAt(i));
			ch2 = b64_map.indexOf(data.charAt(i+1));
			ch3 = b64_map.indexOf(data.charAt(i+2));
			ch4 = b64_map.indexOf(data.charAt(i+3));

			byte1 = (ch1 << 2) | (ch2 >> 4);
			byte2 = ((ch2 & 15) << 4) | (ch3 >> 2);
			byte3 = ((ch3 & 3) << 6) | ch4;

			result[j++] = String.fromCharCode(byte1);
			if (ch3 != 64) result[j++] = String.fromCharCode(byte2);
			if (ch4 != 64) result[j++] = String.fromCharCode(byte3);	
		}

		return result.join('');
	}
}
function windowDimensions(axis)
{
	var myWidth = 0;
	if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
		myWidth = window.innerWidth;
		myHeight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    myWidth = document.documentElement.clientWidth;
    myHeight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    myWidth = document.body.clientWidth;
    myHeight = document.body.clientHeight;
  }
	if(axis =='width')
		return myWidth;
	else
		return myHeight;
}

//  This function is the same as getFrame but it passes a variable that
//  stops automatic population of other fields. i.e. observed near.
function getFrame2(myInput)
{
//	alert('getFrame() called');
	if(typeof(myInput)=='string')
	{
		var myItem=document.forms[0].elements.namedItem(myInput);
		if(myItem)
		{

//vvvvvvvvvvvvvvvvvvSend the page the required valuevvvvvvvvvvvvvvvvvvvvvvv

//			sendValue='?input=' + escape(myInput);
			myValue=myItem.value;
			if(myValue==myItem.defaultValue)
				myValue='';
//			alert("myValue: " + myValue);

			myValue=myValue.trim();
			myValue='&value=' + encodeURI(myValue);
			sendValue='?setAll=false&input=' + encodeURI(myInput) + myValue;
			switch(myInput)
			{
				case "common_name":
				case "bp":
					myAnimal=document.forms[0].type.value;
					myAnimal=myAnimal.trim();
					if(''!=myAnimal)
//						sendValue = sendValue + '&type=' + escape(myAnimal);
						sendValue = sendValue + '&type=' + encodeURI(myAnimal);
					break;
				case "state":
				case "island":
					myCountry=document.forms[0].country.value;
					myCountry=myCountry.trim();
					if(''!=myCountry)
//						sendValue=sendValue + '&country=' + escape(myCountry);
						sendValue=sendValue + '&country=' + encodeURI(myCountry);
					break;
				case "town":
					myState=document.forms[0].state.value;
					myState=myState.trim();
					myCountry=document.forms[0].country.value;
					myCountry=myCountry.trim();
					isFirst=0;
					if(''!=myCountry)
//						sendValue = sendValue + "&country=" + escape(myCountry);
						sendValue = sendValue + "&country=" + encodeURI(myCountry);
					if(''!=myState)
//						sendValue = sendValue + '&state=' + escape(myState);
						sendValue = sendValue + '&state=' + encodeURI(myState);
					break;
				case "session":
					mySurvey=document.forms[0].survey.value;
					mySurvey=mySurvey.trim();
					if(''!=mySurvey)
//						sendValue = sendValue + '&survey=' + escape(mySurvey);
						sendValue = sendValue + '&survey=' + encodeURI(mySurvey);
					break;
				case 'observed_near':
					
					break;
				case 'port':
					break;
				default:
					break;

			}

	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//			myContainer=document.getElementById('container');
//			window.top.document.body.appendChild(myContainer);
			myPageName='frameList.php' + sendValue;
			myFrameName=myInput + 'Iframe';
			if(myIframe=document.getElementById(myFrameName))
			{
				myPath=removePath(myIframe.src);
				if(myPath==myPageName)
				{
					myIframe.style.display='block';
//					document.getElementById('container').style.display='block';
					myContainer.style.display='block';
				}
				else
				{
					myIframe.src='placeholder.html';
					myIframe.src=myPageName;
					myIframe.style.display='block';
//					document.getElementById('container').style.display='block';
					myContainer.style.display='block';
				}
			}
			else
			{
				myContainer=document.getElementById('container');
				if(!myContainer)
				{
					myContainer=document.createElement('div');
					myContainer.id='container';
					myContainer.className='container';
					myContainer.style.display='none';
					document.body.appendChild(myContainer);
				}
				myIframe=document.createElement('iframe');
				myIframe.id=myFrameName;
				myIframe.src='placeholder.html';
				myIframe.className='center';
				myIframe.style.display='block';
				myIframe.src=myPageName;
				myContainer.appendChild(myIframe);
				myContainer.style.display='block';
			}
		}
		else
		{
			alert(myInput + ' is not a form input.');
		}
	}
	else
	{
		alert(myInput + ' is not a form input.');
	}
}
function getFrame(myInput)
{
	if(arguments.length > 1)
	{
		if(arguments[1] === 'true')
		{
			var sendToIcons = true;
		}
	}

//	alert('getFrame() called');
	if(typeof(myInput)=='string')
	{
		if(document.forms[0].elements.namedItem(myInput))
		{

//vvvvvvvvvvvvvvvvvvSend the page the required valuevvvvvvvvvvvvvvvvvvvvvvv

//			sendValue='?input=' + escape(myInput);
			myValue=document.forms[0].elements.namedItem(myInput).value;
//			alert("myValue: " + myValue);

			myValue=myValue.trim();
			myValue='&value=' + encodeURI(myValue);
			sendValue='?input=' + encodeURI(myInput) + myValue;
			switch(myInput)
			{
/*
				case 'bp':
//				case 'size':
					myParent='family';
					break;
*/
				case 'common_name':
					if(document.forms[0].family.value!='')
						myParent='family'
					else
						myParent='class';
					break;
				case 'family':
				case 'bp':
					myParent='class';
					break;
				case 'island':
				case 'town':
					if(document.forms[0].state.value!='')
						myParent='state';
					else
						myParent='country';
					break;
				case 'observed_near':
					if(document.forms[0].town.value!='')
						myParent='town';
					else
					{
						if(document.forms[0].island.value!='')
							myParent='island';
						else
						{
							if(document.forms[0].state.value!='')
								myParent='state';
							else
								myParent='country';
						}
					}
					break;
				case 'session':
					myParent='survey';
					break;
				case 'state':
					myParent='country';
					break;
				default:
					myParent='';
					break;
			}
			if(myParent!=='')
			{
//				parentValue=document.getElementById(myParent).value;
				parentValue=document.getElementsByName(myParent)[0].value;
				parentValue=parentValue.trim();
				if(''!=parentValue)
					sendValue = sendValue + '&parentName=' + encodeURI(myParent) + '&parentValue=' + encodeURI(parentValue);
			}
/*
				case "state":
				case "island":
					myCountry=document.forms[0].country.value;
					myCountry=myCountry.trim();
					if(''!=myCountry)
//						sendValue=sendValue + '&country=' + escape(myCountry);
						sendValue=sendValue + '&country=' + encodeURI(myCountry);
					break;
				case "town":
					myState=document.forms[0].state.value;
					myState=myState.trim();
					myCountry=document.forms[0].country.value;
					myCountry=myCountry.trim();
					isFirst=0;
					if(''!=myCountry)
//						sendValue = sendValue + "&country=" + escape(myCountry);
						sendValue = sendValue + "&country=" + encodeURI(myCountry);
					if(''!=myState)
//						sendValue = sendValue + '&state=' + escape(myState);
						sendValue = sendValue + '&state=' + encodeURI(myState);
					break;
				case "session":
					mySurvey=document.forms[0].survey.value;
					mySurvey=mySurvey.trim();
					if(''!=mySurvey)
//						sendValue = sendValue + '&survey=' + escape(mySurvey);
						sendValue = sendValue + '&survey=' + encodeURI(mySurvey);
					break;
				case 'observed_near':
					
					break;
				case 'port':
					break;
				default:
					break;

*/
		}
		else
		{
			alert(myInput + ' is not an input element');
			return null;
		}

	//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

//			myContainer=document.getElementById('container');
//			window.top.document.body.appendChild(myContainer);
		if(sendToIcons)
			myPageName='frameList2.php';
		else
			myPageName='frameList.php';
		myPageName = myPageName + sendValue;
		myFrameName=myInput + 'Iframe';
		if(myIframe=document.getElementById(myFrameName))
		{
			myPath=removePath(myIframe.src);
			if(myPath==myPageName)
			{
				myIframe.style.display='block';
//					document.getElementById('container').style.display='block';
				myContainer.style.display='block';
			}
			else
			{
				myIframe.src='placeholder.html';
				myIframe.src=myPageName;
				myIframe.style.display='block';
//					document.getElementById('container').style.display='block';
				myContainer.style.display='block';
			}
		}
		else
		{
			myContainer=document.getElementById('container');
			if(!myContainer)
			{
				myContainer=document.createElement('div');
				myContainer.id='container';
				myContainer.className='container';
				myContainer.style.display='none';
				document.body.appendChild(myContainer);
				myShield = document.createElement('div')
				myShield.id='shield';
				myShield.className='shield';
				myContainer.appendChild(myShield);
			}

/*
			myShield = document.getElementById('shield');
			if(!myShield)
			{
			myShield = document.createElement('div')
			myShield.id='shield';
			myShield.className='shield';
			myContainer.appendChild(myShield);
			}
*/

			myIframe=document.createElement('iframe');
			myIframe.id=myFrameName;
			myIframe.src='placeholder.html';
			myIframe.className='center';
			myIframe.style.display='block';
			myIframe.src=myPageName;
			myContainer.appendChild(myIframe);
			myContainer.style.display='block';
		}
	}
	else
	{
		alert(myInput + ' is not a form input.');
	}
}
function undisable()
{
	myElements=document.forms[0].elements;
	myLength=myElements.length;
	for(i=0;i<myLength;i++)
	{
			myElement=myElements.item(i);
			if(myElement.getAttributeNode('disabled'))
				myElement.removeAttribute('disabled');
	}
}

String.prototype.trim=function(){
    return this.replace(/^\s*|\s*$/g,'');
}
function basename(path)
{
	return path.replace( /.*\//, "" );
}
function findPosX(obj)
{
  var curleft = 0;
  if (obj.offsetParent)
  {
    while (obj.offsetParent)
    {
      curleft += obj.offsetLeft
      obj = obj.offsetParent;
    }
  }
  else if (obj.x)
    curleft += obj.x;
  return curleft;
}
function findPosY(obj)
{
  var curtop = 0;
  if (obj.offsetParent)
  {
    while (obj.offsetParent)
    {
      curtop += obj.offsetTop
      obj = obj.offsetParent;
    }
  }
  else if (obj.y)
    curtop += obj.y;
  return curtop;
}
if('function' !== typeof Array.indexOf)
{
	Array.prototype.indexOf = function(needle){
//	Array.prototype.indexOf = theFunction;
//	function theFunction(needle){
		var len=this.length;
		var index = -1;
		var i;
		for(i=0;i<len;i++)
		{
			if(this[i] === needle)
			{
				index=i;
				break;
			}
		}
		return index;
	}
}
function getHTTPRequest()
{
	var returnable=null
	try
  {
  // Firefox, Opera 8.0+, Safari
  returnable=new XMLHttpRequest();
  }
	catch (e)
  {
		// Internet Explorer
		try
    {
			returnable=new ActiveXObject("Msxml2.XMLHTTP");
    }
		catch (e)
    {
			try
      {
				returnable=new ActiveXObject("Microsoft.XMLHTTP");
      }
			catch (e)
      {
				alert("Your browser does not support AJAX!");
				return false;
      }
    }
  }	
	return returnable;
}

function makeDefaultSelect_old()
{
	var ok = false;
	var mySelect = document.createElement('select');
	mySelect.id='defaultInput';
	mySelect.name='default';

	var firstOption=document.createElement('option');
	firstOption.value='';
	var firstText=document.createTextNode('Choose one');
	firstOption.appendChild(firstText);
	mySelect.appendChild(firstOption);
	j=1;

	for(i in defaultArray)
	{
		ok = true;
		var myOption = document.createElement('option');
		myOption.value = j;
		var myText = document.createTextNode(defaultArray[i][1]);
		myOption.appendChild(myText);
		mySelect.appendChild(myOption);
		j++;
	}
	if(ok)
	{
		var theForm=document.getElementById('myForm');
		var myText=document.createTextNode('Choose a query: ');
		theForm.appendChild(myText);
		theForm.appendChild(mySelect);
		var mySubmit = document.createElement('input');
		mySubmit.type='submit';
		theForm.appendChild(mySubmit);
	}
}

function makeDefaultSelect()
{
	var ok = false;
	var mySelect = document.createElement('select');
	mySelect.id='defaultInput';
	mySelect.name='default';

	var firstOption=document.createElement('option');
	firstOption.value='';
	var firstText=document.createTextNode('Choose a default query');
	firstOption.appendChild(firstText);
	mySelect.appendChild(firstOption);
	j=1;

	for(i in defaultArray)
	{
		if(i!=parseInt(i))
			continue; // ie starts with a weird i
		ok = true;
		var myOption = document.createElement('option');
		myOption.value = j;
		var myText = document.createTextNode(defaultArray[i][1]);
		myOption.appendChild(myText);
		mySelect.appendChild(myOption);
		j++;
	}
	if(ok)
	{
		var myRows=document.createElement('input');
		myRows.type='hidden';
		myRows.name='limit';
		myRows.value='200';
		var theForm=document.getElementById('defaultForm');
		theForm.appendChild(myRows);
		theForm.appendChild(mySelect);
		mySelect.onchange=validateDefault;
	}
}

function validateDefault()
{
	var returnable=false;
	var myDefaultInput=document.getElementById('defaultInput');
	if(myDefaultInput.selectedIndex>0)
	{
		returnable=true;
		var theForm=document.getElementById('defaultForm');
		theForm.submit();
	}
	else
		alert("Please select one of the choices");
	return returnable;
}

function printArray(myArray)
{
	if(myArray === null)
	{
		alert("the array passed (" + myArray + ") evaluates to null");
		return false;
	}
	if(myArray.constructor != (new Array).constructor)
	{
		alert("the array passed (" + myArray + ") is not an array");
		return false;
	}
	var len = myArray.length;
	var say = '';
//	var i = 0;
	for(i = 0; i < len; i++)
	{
		if(myArray[i] !== undefined)
			say = say + 'array[' + i + '] => ' + myArray[i] + '; ';
	}
//	alert(say);
	return say;
}
function blankIt(which)
{
	var theDoc = document;
	switch(which)
	{
		case 'class':
			theDoc.getElementById('searchForm').family.value = '';
			theDoc.getElementById('searchForm').common_name.value = '';
			break;
		case 'family':
			theDoc.getElementById('searchForm').common_name.value = '';
			break;
		default:
			alert('error: blankIt called with ' + which);
			break;
	}
}

function sortAlg(a, b)
{
	av = a['value'];
	bv = b['value'];
	if(av === '&nbsp;')
		return 1;
	if(bv === '&nbsp;')
		return 0;
	if(isNaN(av) && isNaN(bv))
	{
		var x = av.toLowerCase();
		var y = bv.toLowerCase();
		return ((x < y) ? -1 : ((x > y) ? 1 : 0));
	}
	else
		return av - bv;
}

function rsortAlg(b, a)
{
	av = a['value'];
	bv = b['value'];
	if(bv === '&nbsp;')
		return 1;
	if(av === '&nbsp;')
		return 0;
	if(isNaN(av) && isNaN(bv))
	{
		var x = av.toLowerCase();
		var y = bv.toLowerCase();
		return ((x < y) ? -1 : ((x > y) ? 1 : 0));
	}
	else
		return av - bv;
}

function sortTable()
{
	var which = sortTable.arguments[0];
	var reverse = false;
	if(sortTable.arguments.length == 2)
	{
		reverse = sortTable.arguments[1];
	}
	var ci = which.cellIndex;
	var myParent = which.parentNode.parentNode;
	var myTable = myParent;
	if(myTable.tagName == 'TBODY')
		myTable = myTable.parentNode;
	if(myTable.tagName != 'TABLE')
	{
		alert("didn't get a table, instead got a " + myTable.tagName);
		return 1;
	}
	myRows=myTable.rows;
	rowsLen=myRows.length;
	var valueArray= new Array();
	var j=0; // Length of valueArray
	for(i=0;i<rowsLen;i++) // Step through the rows
	{
		currentRow=myRows[i];
		currentSortable = currentRow.getAttribute('sortable');
		if(i===0)  // no need to sort by first row
			continue;
		myCells=currentRow.cells;
		var currentValue = new Array();
		currentValue['value'] = myCells[ci].innerHTML;
		currentValue['row'] = i;
		valueArray[i] = currentValue;
		j++;
	}
	if(reverse)
		valueArray.sort(rsortAlg);
	else
		valueArray.sort(sortAlg);
	
	var k=1; //this is the row counter, starting on one because we don't want to mess with row 0?
	var p=0; //this is how many rows were changed
	var newTable = myTable.cloneNode(false);
//	var firstRow = myTable.removeChild(myRows[0]);
//	newTable.appendChild(myRows[0].cloneNode(true));
//	newTable.appendChild(firstRow);
	for(i=0;i<j;i++)
	{
		var rowNumber = valueArray[i]['row'];
		var currentClone = myRows[rowNumber].cloneNode(true);
		newTable.appendChild(currentClone);
	}
	var firstRow = myRows[0].parentNode.removeChild(myRows[0]);
	var firstChildRef = newTable.firstChild;
	newTable.insertBefore(firstRow, firstChildRef);
	myTable.parentNode.replaceChild(newTable, myTable);
	
}
function textToXML(someText)
{
	var xmlDoc;
	try //Internet Explorer
	{
		xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.loadXML(someText);
	}
	catch(e)
	{
		try //Firefox, Mozilla, Opera, etc.
		{
			parser=new DOMParser();
			xmlDoc=parser.parseFromString(someText,"text/xml");
		}
		catch(e)
		{
			alert(e.message);
			return false;
		}
	}
	return xmlDoc;
}
function showAttributes(smthg)
{
	if(!smthg.hasAttributes())
	{
		alert(smthg  + ' has no attributes');
		return false;
	}
	var ats = smthg.attributes;
	var len = ats.length;
	var myDiv = document.createElement('div');
	document.body.appendChild(myDiv);
	for(i=0;i<len;i++)
	{
		var name = ats.item(i).name;
		var value = ats.item(i).value;
		var text = document.createTextNode(name + ': ' + value);
		myDiv.appendChild(text);
		myDiv.appendChild(document.createElement('br'));
	}
}

function alertt(a)
{
	document.body.appendChild(document.createElement('br'));
	document.body.appendChild(document.createTextNode(a));
}

//*************************************************
//                   Stuff for brevity
//888888888888888888888888888888888888888888888888

function previousDate()
{
var currentDay = new Date();

var newDay=(currentDay.getDate())

var newMonth=(currentDay.getMonth() -1)
if((newMonth == 11 || newMonth == 6) && (newDay == 31))
{
  newDay = 30;
}
if((newMonth == 2)&&(newDay>=29))
{
  newDay = 28;
}

var newYear=(currentDay.getFullYear())
if(newMonth < 1) 
{
  newYear=newYear -1;
  newMonth=newMonth +12;
}

return newMonth+ "/" + newDay  + "/" + newYear;

}

function finishIt(inputId, evt)
{
	var myInput=document.getElementById(inputId);
	if(evt.keyCode!=16)
		clearTimeout(sendTimeoutArray[inputId]);
	if(myInput.value!=myInput.defaultValue)
	{
		if((evt.keyCode>=65&&evt.keyCode<=90)||(evt.keyCode>=97&&evt.keyCode<=122))
		{
			sendTimeoutArray[inputId]=setTimeout("getList('" + inputId + "', true, true);", 400);
		}
	}
}

//******************************************************
//                   functions for brevity
//******************************************************

function map_clickIt(smthg)
{
	if(!ready)
	{
		return 0;
	}
	if(smthg===undefined)
	{
		smthg=this;
	}
	else
	{
		if(typeof(smthg.button) !='undefined') // if this li was created dynamically, doesn't have a smthg and needs to be set as the caller.
		{	
			smthg = this;
		}
	}
	if(ns = smthg.nextSibling)
		var nsTag = ns.tagName.toLowerCase();
	if(nsTag == 'ul')
	{
		if(ns.style.display!='none')
		{
			ns.style.display='none';
			return;
		}
	}
	if(smthg.getAttribute('table')=='observed_near')
	{
		//do something
		var listId=smthg.id;
		var myParent = smthg.parentNode.previousSibling; // e.g. Alaska(li) or Mexico(li)
		var parentId=myParent.id; // e.g. United States_state_0 or _country_4
		var table_id = myParent.getAttribute('table_id'); // i.e. actual id
		var whichArray= myParent.getAttribute('table'); // e.g. state or country
		var ci =listId.slice(listId.lastIndexOf('_') + 1); // i.e. counter
		var currentArray = eval(whichArray + '_array_' + table_id);
//					alert('currentArray = eval(' + whichArray + '_array_' + table_id + '); called');
		map_showWin3(whichArray, ci, table_id, smthg.getAttribute('table_id'));

		return;
	}
	var theLat = smthg.getAttribute('lat');
	var theLon = smthg.getAttribute('lon');
	var theFocus = false;
		if(theLat == '' || theLon == '')
			theFocus = true;
		myMap.setCenter(new GLatLng(theLat, theLon));
		var theZoom = smthg.getAttribute('zoom');
		if(!theZoom)
			theZoom = 3;
		myMap.setZoom(Number(theZoom));

	map_getChildren(smthg, theFocus);
}
function map_getChildren(smthg, theFocus)
{
	if(!ready)
	{
		return;
	}
	if(typeof(smthg.button) !=='undefined') // if this li was created dynamically, doesn't have a smthg and needs to be set as the caller.
	{	
		smthg = this;
	}
	
	var listId=smthg.id;
	var tableId=smthg.getAttribute('table_id');;
	var cp=smthg.getAttribute('table');;
	var ci = listId.slice(listId.lastIndexOf('_') + 1);
	var tableId = tableId.slice(tableId.lastIndexOf('_') + 1);
	
	var currentArray = eval(cp + '_array_' + tableId);
	myMap.clearOverlays();
	currentMarkersArray = null;
	for(i in currentArray)
	{
		if(i!=parseInt(i))
			continue; // ie starts with a weird i
		myMap.addOverlay(currentArray[i]);
	}
	currentMarkersArray = currentArray;
	if(theFocus)
	{
		if(currentMarkersArray.length < 1)
			myMap.setZoom(1);
		else
			frameMarkers();
	}
	var ns;
	var nsTag=null;
	if(ns = smthg.nextSibling)
		var nsTag = ns.tagName.toLowerCase();
	if(nsTag == 'ul')
	{
		if(smthg.nextSibling.style.display=='none')
		{
			smthg.nextSibling.style.display='block';
		}
		return;
	}
	var cc = smthg.title;
	var myUrl = 'locationScript.php';
	var xhr = getHTTPRequest();
	xhr.onreadystatechange=function(){if(xhr.readyState==4){ready = true; map_newEntries(xhr.responseText, listId, ci);}}
		xhr.open("POST", myUrl, true);
		xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
		ready=false;
		xhr.send('parent=' + cp + '&value=' + cc + '&ci=' + ci + all); 
}
function map_showWin3(theWhat, theCounter, tableId, theId)
{
	theArray= eval(theWhat + '_array_' + tableId);
	var theOne = theArray[theCounter];;
	if(!theOne)
		alert(theWhat + '_array[' + theId + '] is not defined');
	var infoDiv = document.createElement('div');
	infoDiv.innerHTML = 'Loading...';
	theOne.openInfoWindowHtml(infoDiv);
	GDownloadUrl('infoWindow.php', function(data){infoDiv.innerHTML = data; theOne.closeInfoWindow(); theOne.openInfoWindowHtml(infoDiv); }, 'id=' + theId + '&which=obnear&foobar=');
}
function map_newEntries(incoming, theId, ci)
{
	var current;
	var i = 0;
	var xmlDoc = textToXML(incoming);
	var dataArray = xmlDoc.getElementsByTagName('data');
	var which = xmlDoc.getElementsByTagName('which')[0].firstChild.nodeValue;
	var value = xmlDoc.getElementsByTagName('value')[0].firstChild.nodeValue;
	var length = dataArray.length;
	if(length < 1)
		return;
	var currentParent=document.getElementById(theId);
	var entriesList = document.createElement('ul');
	entriesList.style.paddingLeft='10px';
	entriesList.style.fontSize='.9em';
	var ns = currentParent.nextSibling;
	if(ns)
		currentParent.parentNode.insertBefore(entriesList, ns);
	else
		currentParent.parentNode.appendChild(entriesList);
	var cn = 'secondary';
	if(currentParent.className == 'secondary')
		cn = 'primary';
	for(i=0;i<length;i++)
	{
		current = dataArray[i];
		var currentName = current.firstChild.nodeValue;
		var displayName = currentName;
		if(displayName.length > 15)
			displayName=displayName.substr(0, 12) + '...';
		currentId = current.getAttribute('id');
		currentLat = current.getAttribute('lat');
		currentLon = current.getAttribute('lon');
		currentZoom = current.getAttribute('zoom');
		currentText = document.createTextNode(displayName);
		currentLi = document.createElement('li');
		currentLi.appendChild(currentText);
		currentLi.setAttribute('id', value + '_' + which + '_' + i);
		currentLi.setAttribute('lat', currentLat);
		currentLi.setAttribute('lon', currentLon);
		currentLi.setAttribute('zoom', currentZoom);
		currentLi.className = cn;
		currentLi.title = currentName;
		currentLi.setAttribute('table_id', currentId);
		currentLi.setAttribute('table', which);
		entriesList.appendChild(currentLi);
		currentLi.onclick=map_clickIt;
	}
}
/*
function frameMarkers()
{
//	alert('started');
	if(!currentMarkersArray)
	{
//		alert('!CMA');
		return false;
	}
	if(currentMarkersArray.length<1)
	{
//		alert('CMA.lengh<1');
		return false;
	}
//	alert('so far');
	
	var firstCoords=null;
	var currentLat = null;
	var currentLng = null;
	var myBounds= null;
//	alert('so far 2');
	var firstTime = true;
	for(i in currentMarkersArray)
	{
		if(firstTime)
		{
			firstCoords=currentMarkersArray[i].getLatLng();
			currentLat = firstCoords.lat();
			currentLng = firstCoords.lng();
			myBounds= new GLatLngBounds(firstCoords, firstCoords);
			firstTime=false;
		}
		else
		{
//			alertt(i + ' started');
			var cm = currentMarkersArray[i];
//			alertt('i: ' + i + ', cm: ' + cm);
			if(cm === undefined)
				continue;
//			alertt('i: ' + i + ', cm: ' + cm);
			var cc = cm.getLatLng();
	//					if(!myBounds.containsLatLng(cc))
				myBounds.extend(cc);
		}
	}


	var currentCenter = myBounds.getCenter();
	myMap.setCenter(currentCenter);
	var currentZoom = myMap.getBoundsZoomLevel(myBounds);

	// extend it just a bit.
	var ra = 0; //amount to move relative to zoom;
	switch(currentZoom)
	{
		case 0:
		case 1:
			break;
		case 2:
			ra = 10;
			break;
		case 3:
			ra = 5;
			break;
		case 4:
			ra = 3;
			break;
		case 5:
			ra = 1;
			break;
		case 6:
		case 7:
			ra = .5;
			break;
		case 8:
			ra = .2;
			break;
		case 9:
			ra = .1;
			break;
		case 10:
		case 11:
			ra = .05;
			break;
		default:
			ra = .01;
			break;
	}
//				alert(currentZoom + ', ' + ra);
	var neLat = myBounds.getNorthEast().lat();
	var neLng = myBounds.getNorthEast().lng();
	var swLat = myBounds.getSouthWest().lat();
	var swLng = myBounds.getSouthWest().lng();
//				alert('NE: ' + neLat + ', ' + neLng + '; SW: ' + swLat + ', ' + swLng);
	neLat = neLat + ra; neLng = neLng + ra; swLat = swLat - ra; swLng = swLng - ra;
//				alert('NE: ' + neLat + ', ' + neLng + '; SW: ' + swLat + ', ' + swLng);
	if(neLng > 180)
		neLng = (neLng - 360);
	if(swLng < -180)
		swLng = (swLng + 360);
//				alert('NE: ' + neLat + ', ' + neLng + '; SW: ' + swLat + ', ' + swLng);
	myBounds.extend(new GLatLng(neLat, neLng));
	myBounds.extend(new GLatLng(swLat, swLng));
	var currentZoom = myMap.getBoundsZoomLevel(myBounds);
	myCoords = myMap.getCenter();
	myMaxZoom = 11;
	if(currentZoom > myMaxZoom)
		currentZoom = myMaxZoom;
	myMap.setZoom(currentZoom);
}
function frameMarkers_old()
{
	if(!currentMarkersArray)
		return false;
	if(currentMarkersArray.length<1)
		return false;
	var firstCoords=currentMarkersArray[0].getLatLng();
	var currentLat = firstCoords.lat();
	var currentLng = firstCoords.lng();
	var myBounds= new GLatLngBounds(firstCoords, firstCoords);
	for(i in currentMarkersArray)
	{
		var cm = currentMarkersArray[i];
		var cc = cm.getLatLng();
		myBounds.extend(cc);
	}


	var currentCenter = myBounds.getCenter();
	myMap.setCenter(currentCenter);
	var currentZoom = myMap.getBoundsZoomLevel(myBounds);

	// extend it just a bit.
	var ra = 0; //amount to move relative to zoom;
	switch(currentZoom)
	{
		case 0:
		case 1:
			break;
		case 2:
			ra = 10;
			break;
		case 3:
			ra = 5;
			break;
		case 4:
			ra = 3;
			break;
		case 5:
			ra = 1;
			break;
		case 6:
		case 7:
			ra = .5;
			break;
		case 8:
			ra = .2;
			break;
		case 9:
			ra = .1;
			break;
		case 10:
		case 11:
			ra = .05;
			break;
		default:
			ra = .01;
			break;
	}
	var neLat = myBounds.getNorthEast().lat();
	var neLng = myBounds.getNorthEast().lng();
	var swLat = myBounds.getSouthWest().lat();
	var swLng = myBounds.getSouthWest().lng();
	neLat = neLat + ra; neLng = neLng + ra; swLat = swLat - ra; swLng = swLng - ra;
	if(neLng > 180)
		neLng = (neLng - 360);
	if(swLng < -180)
		swLng = (swLng + 360);
	myBounds.extend(new GLatLng(neLat, neLng));
	myBounds.extend(new GLatLng(swLat, swLng));
	var currentZoom = myMap.getBoundsZoomLevel(myBounds);
	myMap.setZoom(currentZoom);
}
*/

function htmlspecialchars(p_string) {
		p_string = p_string.replace(/&/g, '&amp;');
			p_string = p_string.replace(/</g, '&lt;');
				p_string = p_string.replace(/>/g, '&gt;');
					p_string = p_string.replace(/"/g, '&quot;');
					//	p_string = p_string.replace(/'/g, '&#039;');
						return p_string;
}

function htmlspecialchars_decode(p_string) {
		p_string = p_string.replace(/&amp;/g, '&');
			p_string = p_string.replace(/&lt;/g, '<');
				p_string = p_string.replace(/&gt;/g, '>');
					p_string = p_string.replace(/&quot;/g, '"');
					//	p_string = p_string.replace(/&#039;/g, '\'');
						return p_string;
}

function map_showThis(level, which)
{
	var currentArray = eval(level + '_array_' + which);
	myMap.clearOverlays();
	currentMarkersArray = null;
	for(i in currentArray)
	{
		if(i!=parseInt(i))
			continue; // ie starts with a weird i
		myMap.addOverlay(currentArray[i]);
	}
	currentMarkersArray = currentArray;
	frameMarkers();
}
//******************************************************



//******************************************************
//             functions for brevity for mapGallery
//******************************************************

// start stuff for form

function mg_finishIt(inputId, evt)
{
	var myInput=document.getElementById(inputId);
	if(evt.keyCode!=16)
		clearTimeout(sendTimeoutArray[inputId]);
	if(myInput.value!=myInput.defaultValue)
	{
		if((evt.keyCode>=65&&evt.keyCode<=90)||(evt.keyCode>=97&&evt.keyCode<=122))
		{
			sendTimeoutArray[inputId]=setTimeout("mg_getList('" + inputId + "', true, true);", 400);
		}
	}
}
function mg_clickIt(selected, inputId)
{
	var theInput=document.getElementById(inputId);
	theInput.value=selected;
	theInput.className='';

	document.getElementById('hidden_' + inputId).style.display='none';
}
function mg_makeHiddenList(myString, inputId)
{
	var myHidden=document.getElementById('hidden_' +inputId);

	try //Internet Explorer
	{
		xmlDoc=new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async="false";
		xmlDoc.loadXML(myString);
	}
	catch(e)
	{
		try //Firefox, Mozilla, Opera, etc.
		{
			parser=new DOMParser();
			xmlDoc=parser.parseFromString(myString,"text/xml");
		}
		catch(e)
		{
			alert(e.message);
			return;
		}
	}

	var dataArray=xmlDoc.getElementsByTagName('data');
	arrayLength=dataArray.length;
	if(1)
	{
		var topStuff=document.createElement('div');

		// Delete the old stuff
		if(oldCon=document.getElementById('hiddenCon_' + inputId))
		{
			myHidden.removeChild(oldCon);
		}

		// if searching by something, make link to unsearch it.
		if(searchString=xmlDoc.getElementsByTagName('searchstring'))
		{
			if(searchString.length===1)
			{
				searchString=String(searchString[0].firstChild.nodeValue);
				var searchingBy=document.createTextNode("Using search string '" + searchString + "'. ");
				searchLinkText=document.createTextNode("To see all valid values, click here.");
				searchLinkSpan=document.createElement('span');
				searchLinkSpan.onclick= function(){mg_getList(inputId, true, false);};
				searchLinkSpan.appendChild(searchLinkText);
				searchLinkSpan.style.cursor='pointer';
				searchLinkSpan.style.textDecoration='underline';
				searchLinkSpan.style.color='blue';
				var valueDiv=document.createElement('div');
				valueDiv.appendChild(searchingBy);
				valueDiv.appendChild(searchLinkSpan);
				topStuff.appendChild(valueDiv);
			}
		}

		if(parentString=xmlDoc.getElementsByTagName('parent'))
		{
			if(parentString.length===1)
			{
				if(parentValue=xmlDoc.getElementsByTagName('parentvalue'))
				{
					if(parentValue.length===1)
					{
						parentString=String(parentString[0].firstChild.nodeValue);
						parentValue=parentValue[0].firstChild.nodeValue;
						var parentSearchingBy=document.createTextNode("Searching under '" + parentString + ":" + parentValue + "'.");
						parentLinkText=document.createTextNode("To see all valid values, click here.");
						parentLinkSpan=document.createElement('span');
						parentLinkSpan.onclick=function(){mg_getList(inputId, false, true);};
						parentLinkSpan.appendChild(parentLinkText);
						parentLinkSpan.style.cursor='pointer';
						parentLinkSpan.style.textDecoration='underline';
						parentLinkSpan.style.color='blue';
						var parentDiv=document.createElement('div');
						parentDiv.appendChild(parentSearchingBy);
						parentDiv.appendChild(parentLinkSpan);
						topStuff.appendChild(parentDiv);
					}
				}
			}
		}


		var errorArray=xmlDoc.getElementsByTagName('parenterror');
		if(errorArray.length>0)
		{
			theError=errorArray[0].firstChild.nodeValue;
			errorString=document.createTextNode(theError);
			if(topStuff.hasChildNodes)
				topStuff.insertBefore(errorString, topStuff.firstChild);
			else
				topStuff.appendChild(errorString);
		}
		var hiddenContainer=document.createElement('div');
		hiddenContainer.id='hiddenCon_' + inputId;
//		hiddenContainer.style.paddingLeft='20';
		topStuff.style.marginLeft='20px';
		topStuff.style.fontSize='.8em';
		topStuff.style.color='red';
		var lineBreaker=document.createElement('hr');

		if(arrayLength>0)
		{
			var myList = document.createElement('ul');
			myList.style.marginLeft='20px';


			for(i=0;i<arrayLength;i++)
			{
				var currentText=String(dataArray[i].firstChild.nodeValue);
				var currentValue=document.createTextNode(currentText);
				var currentLi=document.createElement('li');
				currentLi.onclick=function(){ 
					mg_clickIt(this.firstChild.nodeValue, inputId);
				};

				currentLi.appendChild(currentValue);
				myList.appendChild(currentLi);
			}
		}
		else
		{
			myList=document.createElement('span');
			myList.style.color='silver';
			myList.style.marginLeft='20px';
			myList.style.marginBottom='20px';
			listText=document.createTextNode("(none)");
			myList.appendChild(listText);
		}
		myHidden.appendChild(hiddenContainer);
		hiddenContainer.appendChild(topStuff);
		hiddenContainer.appendChild(lineBreaker);
		hiddenContainer.appendChild(myList);
		if(myHidden.style.display!='block')
		{
//			myHidden.style.height='350px';
			myHidden.style.display='block';
		}
		document.getElementById(inputId).focus();
		return true;
	}
	else
	{
		sError='';
		pError='';
		if(sString=xmldoc.getElementsByTagName('searchstring'))
		{
			if(sString.length===1)
			{
				sError='"' + sString[0].firstChild.nodeValue + '"';
			}
		}
		if(sParent=xmldoc.getElementsByTagName('parent'))
		{
			if(sParent.length===1)
			{
				if(sParentValue=xmldoc.getElementsByTagName('parentvalue'))
				{
					if(sParentValue.length===1)
					{
						if(sString)
							pError=" and ";
						pError=pError + "with parent: " + sParentValue[0].firstChild.nodeValue;
					}
				}
			}
		}
		var myError="No valid entries searching under " + sError + pError + ".";
		var myLink=document.createElement('a');
		return false;
	}
}
function mg_nextStep(inputId)
{
	if(xhr.readyState==4)
	{
		var response = xhr.responseText;
		if(mg_makeHiddenList(response, inputId))
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	else
		return false;
}
function mg_getList(inputId, useParent, useValue)
{
	clearTimeout(hideTimeoutArray[inputId]);

	var myInput = document.getElementById(inputId);
	var parentInput='';
	var parentOut='';
	var valueOut='';
	if(useParent)
	{
		switch(inputId)
		{
			case "common_name":
				parentInput="family";
				break;
			case "observed_near":
			case "state":
			case "town":
			case "island":
				parentInput="country";
				break;
			case "session":
				parentInput="survey";
				break;
			default:
				//do nothing
				break;
		}
		if(parentInput !=='')
		{
			parentInputElement = document.getElementById(parentInput);
			parentValue=parentInputElement.value;
			if(parentValue!='' && parentValue != parentInputElement.defaultValue)
			{
				parentOut="&parent=" + parentInput + "&parentValue=" + parentValue;
			}
		}
	}
	if(useValue)
	{
		var theValue=myInput.value;
		if(theValue!='' && theValue!=myInput.defaultValue)
		valueOut='&value=' + theValue;
	}
	xhr = getHTTPRequest();
	if(xhr)
	{
		var myUrl = "test4.php";
		xhr.onreadystatechange=function(){mg_nextStep(inputId);};
		xhr.open("POST", myUrl, true);
		xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
		xhr.send("input=" + inputId + valueOut + parentOut);
	}
}

function mg_blurIt(inputId)
{
	var myInput=document.getElementById(inputId);
	if(myInput.value==''||myInput.value==myInput.defaultValue)
	{
		myInput.value=myInput.defaultValue;
		myInput.className='grayed';
	}
	hideTimeoutArray[inputId] = setTimeout("document.getElementById('hidden_" + inputId + "').style.display='none'", 1000);
}

function mg_refocus(r) //i.e. doesn't hold the focus as you scroll
{
	var myName=String(r.id).replace('hidden_', '');
	var myInput=document.getElementById(myName);
	myInput.focus();
	clearTimeout(hideTimeoutArray[myName]);
}

function mg_changeWhichDate()
{
	endateSelected=false;
	rangeSelected=false;
	whichOne=document.forms[0].dateType;
	if(whichOne.item(0).checked)
		rangeSelected=true;
	whichOne=document.forms[0].whichDate;
	if(whichOne.item(1).checked)
		endateSelected=true;
	var now = new Date();
	currentYear=now.getFullYear();
	currentMonth=now.getMonth + 1;
	if(endateSelected)
	{
		if(!rangeSelected)
		{
			singleMonth=document.getElementById('single_Month_ID');
			singleDay=document.getElementById('single_Day_ID');
			singleYear=document.getElementById('single_Year_ID');
			singleMonth.selectedIndex=currentMonth;
			single_Object.changeMonth(singleMonth);
			singleDay.selectedIndex=0;
			single_Object.changeDay(singleDay);
			singleYear.value=currentYear;
			single_Object.checkYear(singleYear);
		}
		else
		{
			fromMonth=document.getElementById('from_Month_ID');
			fromDay=document.getElementById('from_Day_ID');
			fromYear=document.getElementById('from_Year_ID');
			fromMonth.selectedIndex=currentMonth;
			from_Object.changeMonth(fromMonth);
			fromDay.selectedIndex=0;
			from_Object.changeDay(fromDay);
			fromYear.value=currentYear;
			from_Object.checkYear(fromYear);
			toMonth=document.getElementById('to_Month_ID');
			toYear=document.getElementById('to_Year_ID');
			toYear.value=currentYear;
			toMonth.selectedIndex=0;
			to_Object.changeMonth(toMonth);
		}
	}
}
function mg_changeDate()
{
	var thisRangeTable=document.getElementById('rangeTable');
	var thisSingleTable=document.getElementById('singleTable');

	if(thisSingleTable.style.display=='none')
	{
		thisSingleTable.style.display='inline';
		thisRangeTable.style.display='none';
		single=document.getElementById('single_Month_ID');
		single.selectedIndex=0;
		single_Object.changeMonth(single);
	}
	else
	{
		thisSingleTable.style.display='none';
		thisRangeTable.style.display='inline';
		from=document.getElementById('from_Month_ID');
		to=document.getElementById('to_Month_ID');
		from.selectedIndex=0;
		to.selectedIndex=0;
		from_Object.changeMonth(from);
		to_Object.changeMonth(to);
	}
	mg_changeWhichDate();
}

function mg_enterIt(here)
{
	var myDefault=here.defaultValue;
	if(here.value==myDefault)
	{
		here.value='';
		here.className='';
	}
}

function mg_clearAll()
{
	var allInputs=document.getElementsByTagName('input');
	var	theLength=allInputs.length;

// clear all markers and results
	myMap.clearOverlays();
	currentMarkersArray.length=0;
	if(mc.getTotalMarkers())
		mc.clearMarkers();
	myResults = document.getElementById('results');
	while(myResults.hasChildNodes())
	{
		myResults.removeChild(myResults.firstChild);
	}
	document.getElementById('frameMarkersButton').style.display='none';

//reset map position and zoom
	myMap.returnToSavedPosition();

	for(i=0;i<theLength;i++)
	{
		if(allInputs[i].type=='text')
		{
			var myInput=allInputs[i];
			if(myInput.value!=myInput.defaultValue)
			{
				myInput.value=myInput.defaultValue;
				myInput.className='grayed';
			}
		}
	}
}
function mg_noDefaults()
{
	var allInputs=document.getElementsByTagName('input');
	var	theLength=allInputs.length;
	for(i=0;i<theLength;i++)
	{
		if(allInputs[i].type=='text')
		{
			var myInput=allInputs[i];
			if(myInput.value==myInput.defaultValue)
				myInput.value='';
		}
	}
	var myDefault=here.defaultValue;
	if(here.value=='')
		here.value=myDefault;
}
function mg_previousDate()
{
var currentDay = new Date();

var newDay=(currentDay.getDate())

var newMonth=(currentDay.getMonth() -1)
if((newMonth == 11 || newMonth == 6) && (newDay == 31))
{
  newDay = 30;
}
if((newMonth == 2)&&(newDay>=29))
{
  newDay = 28;
}

var newYear=(currentDay.getFullYear())
if(newMonth < 1) 
{
  newYear=newYear -1;
	newMonth = newMonth + 12;
}
newYear=2008;

return newMonth+ "/" + newDay  + "/" + newYear;

}

// start stuff for map 

function mg_getChildren()
{
	if(!ready)
	{
		return;
	}
	ready = false;
	var elems = document.getElementById('myForm').elements;
	var cf = elems.namedItem('family');
	if(cf.defaultValue===cf.value)
		cf='';
	else
		cf=cf.value;
	var cn = elems.namedItem('common_name');
	if(cn.defaultValue===cn.value)
		cn='';
	else
		cn=cn.value;
	var cb = elems.namedItem('bp');
	if(cb.defaultValue===cb.value)
		cb='';
	else
		cb=cb.value;
	var cc = elems.namedItem('country');
	if(cc.defaultValue===cc.value)
		cc='';
	else
		cc=cc.value;
	var cs = elems.namedItem('state');
	if(cs.defaultValue===cs.value)
		cs='';
	else
		cs=cs.value;
	var ci = elems.namedItem('island');
	if(ci.defaultValue===ci.value)
		ci='';
	else
		ci=ci.value;
	var cd = elems.namedItem('from');
	cd=cd.value;
	var ct = elems.namedItem('to');
	ct=ct.value;
	myMap.clearOverlays();
	currentMarkersArray.length=0;
	if(mc.getTotalMarkers())
		mc.clearMarkers();
	var myUrl = 'test5.php';
	var xhr = getHTTPRequest();
	document.getElementById('loading').style.display = 'inline';
	mg_startSpinner();
	document.getElementById('loading').style.color = 'red';
	xhr.onreadystatechange=function(){if(xhr.readyState==4){ready = true; mg_newEntries(xhr.responseText);}}
		xhr.open("POST", myUrl, true);
		xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
		ready=false;
		xhr.send('family=' + cf + '&common_name=' + cn + '&bp=' + cb + '&country=' + cc + '&state=' + cs + '&island=' + ci + '&from=' + cd + '&to=' + ct + '&dateType=range&whichDate=obdate'); 
}
function mg_showWin2(theCounter, theId)
{
	var theOne = markerArray[theCounter];
	if(!theOne)
		alert('markerArray[' + theId + '] is not defined');
	var infoDiv = document.createElement('div');
	infoDiv.innerHTML = 'Loading...';
	theOne.openInfoWindowHtml(infoDiv);
	GDownloadUrl('infoWindow.php', function(data){infoDiv.innerHTML = data; theOne.closeInfoWindow(); theOne.openInfoWindowHtml(infoDiv); }, 'id=' + theId + '&which=obnear&foobar=');
}
function mg_newEntries(incoming)
{
	document.getElementById('loading').style.color = 'green';
	var say = '';
	var current;
	var i = 0;
	var xmlDoc = textToXML(incoming);
	xd= textToXML(incoming);
	var dataElems = xmlDoc.getElementsByTagName('data');
	len = dataElems.length;
	var dataArray = xmlDoc.getElementsByTagName('data');
	var length = dataArray.length;
	var queryOut = xmlDoc.getElementsByTagName('query').item(0).firstChild.nodeValue;
	queryOut = htmlspecialchars_decode(queryOut);

	var myResults = document.getElementById('results');
	while(myResults.hasChildNodes())
	{
		myResults.removeChild(myResults.firstChild);
	}

	if(length < 1)
	{
		var mySpan = document.createElement('span');
		var myText = document.createTextNode('No results found');
		mySpan.appendChild(myText);
		mySpan.style.color='red';
		mySpan.style.marginRight='15px';
		myResults.appendChild(mySpan);
		document.getElementById('loading').style.display = 'none';
		mg_stopSpinner();
		document.getElementById('frameMarkersButton').style.display = 'none';
		return;
	}
	else
	{
		myGalleryLink = document.createElement('a');
		myGalleryLink.href="viewGallery.php?query=" + queryOut;
		var myText = document.createTextNode('Click here to see all (' + length + ') results in a gallery');
		myGalleryLink.appendChild(myText);
		myResults.appendChild(myGalleryLink);
	}
	sa = new Array(); // singles array, or at least single for now.
	var falses = 0;
	var	trues = 0;
	var	duplicates = new Array();
	for(j=0;j<length;j++)
	{
		current = dataArray[j];
		var currentId = current.getAttribute('dataId');
		var currentLat = current.getAttribute('lat');
		var currentLon = current.getAttribute('lon');

		var currentKey = mg_makeKey(currentLat, currentLon);
		var k;
		var keep = true;
		var remo = null;
		var done = false;

		//first check to see if there is already a duplicates entry with this key.
		//if so, add to that duplicate.
		for(k in duplicates)
		{
			if(k!=parseInt(k))
				continue; // ie starts with a weird j
			if(duplicates[k][0] === currentKey)
			{
				duplicates[k].push(currentId);
				keep = false;
				done = true;
				falses = falses + 1;
			}
		}

		//it's still viable to keep so check the already kept
		if(keep)
		{
			for(k in sa)
			{
				if(k!=parseInt(k))
					continue; // ie starts with a weird j
				if(sa[k][0] === currentKey)
				{
					keep = false;
					concurrent = sa.splice(k,1);
					concurrent = concurrent[0];
					var dupLat = Math.round(currentLat*100);
					var dupLon = Math.round(currentLon*100);
					dupLat = dupLat/100;
					dupLon = dupLon/100;
					var currentArray = new Array(currentKey, dupLat, dupLon, currentId, concurrent[1]);
					duplicates.push(currentArray);
					falses = falses + 2;
					trues = trues - 1;
					break;
				}
			}
		}

		if(keep)
		{
			trues = trues + 1;
			sa[j] = new Array(currentKey, currentId, currentLat, currentLon);
			done = true;
		}
	}

	var myIcon = new GIcon(G_DEFAULT_ICON);
	myIcon.image = "images/map_icons/custom2.png";
	myIcon.iconSize = new GSize(24, 32);
	myIcon.iconAnchor = new GPoint(12, 29);
	myIcon.shadow = "images/map_icons/C2Shadow.png";
	myIcon.shadowSize = new GSize(50, 32);
	var myOpts = {icon:myIcon};
	var groupIcon = new GIcon(G_DEFAULT_ICON);
	groupIcon.image = "images/map_icons/group2.png";
	groupIcon.iconSize = new GSize(30, 35);
	groupIcon.iconAnchor = new GPoint(14, 32);
	groupIcon.shadow = "images/map_icons/g2Shadow.png";
	groupIcon.shadowSize = new GSize(43, 35);
	var groupOpts = {icon:groupIcon};

	var lastKey=null;
	currentMarkersArray.length = 0;

	for(j in sa)
	{
		if(j!=parseInt(j))
		{
			continue; // ie starts with a weird j
		}
		var currentId = sa[j][1];
		var currentLat = sa[j][2];
		var currentLon = sa[j][3];
		var currentMarker = new GMarker(new GLatLng(currentLat, currentLon), myOpts);
		var pushedLength = currentMarkersArray.push(currentMarker);
		var pushedIndex = pushedLength - 1;

		eval("GEvent.addListener(currentMarker, 'click', function(){ var itself = this; var infoDiv = document.createElement('div'); infoDiv.innerHTML = 'Loading...'; this.openInfoWindow(infoDiv);this.closeInfoWindow(); mg_dlu(infoDiv, " + pushedIndex + ", " + currentId + ", false); });");



		lastKey = j;
	}
	var cmaLen = currentMarkersArray.length;
	for(j in duplicates)
	{
		if(j!=parseInt(j))
			continue; // ie starts with a weird j
		var k = Number(j) + Number(lastKey) + 1;
		var myLength = duplicates[j].length;
		var myKey = duplicates[j][0];
		var myLat = duplicates[j][1];
		var myLon = duplicates[j][2];
		var myIds = duplicates[j][3];
		for(i=4;i<myLength;i++)
		{
			myIds = myIds + ',' + duplicates[j][i];
			//add the current id to the query that clicking on this marker returns
		}
		var currentMarker = new GMarker(new GLatLng(myLat, myLon), groupOpts);

		pushedLength = currentMarkersArray.push(currentMarker);
		pushedIndex = pushedLength - 1;
		eval("GEvent.addListener(currentMarker, 'click', function(){ var itself = this; var infoDiv = document.createElement('div'); infoDiv.innerHTML = 'Loading...'; this.openInfoWindow(infoDiv); this.closeInfoWindow();mg_dlu(infoDiv, " + pushedIndex + ", '" + myIds + "', true); });");

	}
	mc.addMarkers(currentMarkersArray);
	frameMarkers();
	ready = true;
	document.getElementById('loading').style.display = 'none';
	document.getElementById('frameMarkersButton').style.display = 'inline';
	mg_stopSpinner();
}
function mg_dlu(myDiv, index, id, gallery)
{
	var args = 'id=' + id + '&which=images';
	if(gallery)
		args = 'ids=' + id;
	GDownloadUrl('infoWindow.php', function(data){myDiv.innerHTML=data;var cm = currentMarkersArray[index]; theDiv=myDiv;theMarker=cm;mg_openTheWindow();}, args);
}
function mg_openTheWindow()
{
	infoWindowTimeout = setTimeout("theMarker.openInfoWindow(theDiv);", 150);
}
function mg_makeKey(olat, olon)
{
	olat = Number(olat);
	olon = Number(olon);
	var nlat = Math.round((olat + 90)*100);
	var nlon = Math.round((olon + 180)*100);
	var nd = Math.ceil(Math.log(nlat) / Math.log(10));
	var returnable =  nlat + nlon * Math.pow(10, nd);
	return returnable;
}
function mg_startSpinner()
{
	var mySpinner = document.getElementById('spinner');
	var myStage = mySpinner.firstChild.nodeValue;
	switch(myStage)
	{
		case '-':
			newStage = '\\';
			break;
		case '\\':
			newStage = '|';
			break;
		case '|':
			newStage = '/';
			break;
		case '/':
			newStage = '-';
			break;
		default:
			alert('error in start spinner');
	}
	newText = document.createTextNode(newStage);
	mySpinner.replaceChild(newText, mySpinner.firstChild);
	spinnerTimer = setTimeout('mg_startSpinner()', 500);
}
function mg_stopSpinner()
{
	clearTimeout(spinnerTimer);
}

//******************************************************

function frameMarkers()
{
	if(!currentMarkersArray)
	{
		return false;
	}
	if(currentMarkersArray.length<1)
	{
		return false;
	}
	
	var firstCoords=null;
	var currentLat = null;
	var currentLng = null;
	var myBounds= null;
	var firstTime = true;
	for(i in currentMarkersArray)
	{
		if(i!=parseInt(i))
			continue; // ie starts with a weird j
		if(firstTime)
		{
			firstCoords=currentMarkersArray[i].getLatLng();
			currentLat = firstCoords.lat();
			currentLng = firstCoords.lng();
			myBounds= new GLatLngBounds(firstCoords, firstCoords);
			firstTime=false;
		}
		else
		{
			var cm = currentMarkersArray[i];
			if(cm === undefined)
				continue;
			var cc = cm.getLatLng();
				myBounds.extend(cc);
		}
	}

	var currentCenter = myBounds.getCenter();
	myMap.setCenter(currentCenter);
	var currentZoom = myMap.getBoundsZoomLevel(myBounds);

	// extend it just a bit.
	var ra = 0; //amount to move relative to zoom;
	switch(currentZoom)
	{
		case 0:
		case 1:
			break;
		case 2:
			ra = 10;
			break;
		case 3:
			ra = 5;
			break;
		case 4:
			ra = 3;
			break;
		case 5:
			ra = 1;
			break;
		case 6:
		case 7:
			ra = .5;
			break;
		case 8:
			ra = .2;
			break;
		case 9:
			ra = .1;
			break;
		case 10:
		case 11:
			ra = .05;
			break;
		default:
			ra = .01;
			break;
	}
	var neLat = myBounds.getNorthEast().lat();
	var neLng = myBounds.getNorthEast().lng();
	var swLat = myBounds.getSouthWest().lat();
	var swLng = myBounds.getSouthWest().lng();
	neLat = neLat + ra; neLng = neLng + ra; swLat = swLat - ra; swLng = swLng - ra;
	if(neLng > 180)
		neLng = (neLng - 360);
	if(swLng < -180)
		swLng = (swLng + 360);
	myBounds.extend(new GLatLng(neLat, neLng));
	myBounds.extend(new GLatLng(swLat, swLng));
	var currentZoom = myMap.getBoundsZoomLevel(myBounds);
	myCoords = myMap.getCenter();
	myMaxZoom = 11;
	if(currentZoom > myMaxZoom)
		currentZoom = myMaxZoom;
	myMap.setZoom(currentZoom);
}
