	// var log = log4javascript.getDefaultLogger();
	// log.debug('Log opened.');
	var pageOnLoaders = new Array();

	if( window.addEventListener ) {
	  window.addEventListener('load',onPageLoad,false);
	} else if( document.addEventListener ) {
	  document.addEventListener('load',onPageLoad,false);
	} else if( window.attachEvent ) {
	  window.attachEvent('onload',onPageLoad);
	}
	
	function onPageLoad() {
		var pageLoader = null;

		// Iterate through the page loaders and be sure to
		// remove them when used. This will make it so that
		// as ajaxified pages don't re-init things on accident 
		while( pageLoader = pageOnLoaders.pop()) {
			setTimeout(pageLoader, 500);
		}
 
	}

	function addOnLoad(loaderFunction ) {
		pageOnLoaders.push(loaderFunction);
	}


	function setFormTextHint(elementId) { 
		var element = document.getElementById(elementId);

		if( element !== null && element.value == '' ) {
			element.onfocus = function() {
				clearFormTextHint(this.id);
			}

			element.onblur = function() {
				setFormTextHint(this.id);
			}

			element.value = textHints[elementId];
			element.style.color = "#9f9f9f";
		}
	}

	function clearFormTextHint(elementId) {
		var element = document.getElementById(elementId);

		if( element !== null && element.value == textHints[elementId] ) {
			element.value = '';
			element.style.color = "#000000";
		}
	}

	function swapImage(imageId, imageSrc) {
		var image = document.getElementById(imageId);
		
		if( image != null ) {
			if( image.tagName.toLowerCase() == 'img' ) {
				var result = image.src.match(/^\w+:\/\/[\w.]+\/(\S*)/);
				
				if( result === null || result[1] != imageSrc) {
					 image.src = imageSrc;
				}
			} else {
				var newImage = document.createElement('img');
				newImage.src = imageSrc;


				image.innerHTML = '';
				image.appendChild(newImage);

			}
		}
	}

// Given an input element, validates the element and 
// if it is not valid, post an error
function validatePostalCodeField(element, country) {
	if( element !== null ) {
		var invalidMessage = null;

		if( country == "Canada" ) {
			invalidMessage = '^- Canadian postal codes must have 6 characters such as "K0A 1B6"';
		} else {
			invalidMessage = '^- US ZIP code needs to be exactly 5 numbers';
		}

		var isCodeValid = validatePostalCode( element.value, country );

		if( isCodeValid == false ) {
			insertErrorAfter(element, invalidMessage); 

			return false;
		}
	}

	return true;
}


// Validates a postal code.
// 
// Valid countries -> 'USA', 'Canada'
function validatePostalCode(code, country) {
	var validator = null;

	if( country == "Canada" ) {
		validator = /^[ABCEGHJKLMNPRSTVWXYZ]\d[ABCEGHJKLMNPRSTVWXYZ]\s?\d[ABCEGHJKLMNPRSTVWXYZ]\d$/;
	} else {
		validator = /^\d{5}$/;
	}

	return(validator.test(code));
}

function insertErrorAfter(el, message){
	var s = document.createElement('div');
	s.className = "errorMsg";
	s.appendChild(document.createTextNode(message));
	el.parentNode.insertBefore(s, el.nextSibling);
	setTimeout(function(){
		s.parentNode.removeChild(s);
	}, 6000);
}

function displayJoinUpQuestion(targetId, screenName) {
	var target = document.getElementById(targetId);

	if( target != null ) {
		var joinupBox = document.createElement('div')
		var questionText = document.createElement('span');
		questionText.appendChild(document.createTextNode('You are currently logged in as \'' + screenName + '\'.'));

		var questionButtons = document.createElement('form');
		var yesButton = document.createElement('a');
		yesButton.href = '/logout.php';
		yesButton.onclick = function() {
			hideConfirmation(target);
		}
		yesButton.className = 'hrefButton';
		yesButton.appendChild(document.createTextNode('I am not \'' + screenName + '\', Log Out'));

		var noButton = document.createElement('a');
		noButton.href = 'javascript:void(0); return false;';
		noButton.onclick = function() {
			hideConfirmation(target);			
		}
		noButton.className = 'hrefButton';
		noButton.appendChild(document.createTextNode('I am \'' + screenName + '\', stay logged in'));

		questionButtons.appendChild(yesButton);
		questionButtons.appendChild(noButton);

		joinupBox.className = 'joinupQuestion';
		joinupBox.innerHTML = '';
		joinupBox.appendChild(questionText);
		joinupBox.appendChild(document.createElement('br'));
		joinupBox.appendChild(document.createElement('br'));
		joinupBox.appendChild(questionButtons);
		
		target.className = 'joinupPrompt';
		target.innerHTML = '';
		target.appendChild(joinupBox);		
	}
}

function displayConfirmation(target, confirmationText, onConfirm, parameter) {
	if( target != null ) {

		var questionText = document.createElement('span');
		questionText.innerHTML = confirmationText;

		var questionButtons = document.createElement('form');
		var yesButton = document.createElement('input');
		yesButton.type = 'button';
		yesButton.value = 'Yes';
		yesButton.onclick = function() {
			hideConfirmation(target);

			if( onConfirm != null ) {
				onConfirm(parameter);
			}
		}

		var noButton = document.createElement('input');
		noButton.type = 'button';
		noButton.value = 'No';
		noButton.style.marginLeft = '10px';
		noButton.onclick = function() {
			hideConfirmation(target);
		}

		questionButtons.appendChild(yesButton);
		questionButtons.appendChild(noButton);

		target.className = 'statusQuestion';
		target.innerHTML = '';
		target.appendChild(questionText);
		target.appendChild(questionButtons);
	}
}

function hideConfirmation(target) {
	if( target != null ) {
		target.className = 'statusHidden';
		target.innerHTML = '';
	}
}


	function updateStates(country) {
		var stateSelector = document.getElementById('states');
		stateSelector.options.length = 0;
		stateSelector.options[stateSelector.options.length] = new Option('------ Please Choose ------', '', false, false);
		var stateList = new Object();

		if( country == "Canada" ) {
			stateList['AB'] = 'Alberta  ';
			stateList['BC'] = 'British Columbia ';
			stateList['MB'] = 'Manitoba ';
			stateList['NB'] = 'New Brunswick ';
			stateList['NL'] = 'Newfoundland and Labrador ';
			stateList['NT'] = 'Northwest Territories ';
			stateList['NS'] = 'Nova Scotia ';
			stateList['NU'] = 'Nunavut ';
			stateList['ON'] = 'Ontario ';
			stateList['PE'] = 'Prince Edward Island ';
			stateList['QC'] = 'Quebec ';
			stateList['SK'] = 'Saskatchewan ';
			stateList['YT'] = 'Yukon ';
		} else {
			stateList['AL'] = 'ALABAMA';
			stateList['AK'] = 'ALASKA';
			stateList['AZ'] = 'ARIZONA';
			stateList['AR'] = 'ARKANSAS';
			stateList['CA'] = 'CALIFORNIA';
			stateList['CO'] = 'COLORADO';
			stateList['CT'] = 'CONNECTICUT';
			stateList['DE'] = 'DELAWARE';
			stateList['DC'] = 'DISTRICT OF COLUMBIA';
			stateList['FL'] = 'FLORIDA';
			stateList['GA'] = 'GEORGIA';
			stateList['HI'] = 'HAWAII';
			stateList['ID'] = 'IDAHO';
			stateList['IL'] = 'ILLINOIS';
			stateList['IN'] = 'INDIANA';
			stateList['IA'] = 'IOWA';
			stateList['KS'] = 'KANSAS';
			stateList['KY'] = 'KENTUCKY';
			stateList['LA'] = 'LOUISIANA';
			stateList['ME'] = 'MAINE';
			stateList['MD'] = 'MARYLAND';
			stateList['MA'] = 'MASSACHUSETTS';
			stateList['MI'] = 'MICHIGAN';
			stateList['MN'] = 'MINNESOTA';
			stateList['MS'] = 'MISSISSIPPI';
			stateList['MO'] = 'MISSOURI';
			stateList['MT'] = 'MONTANA';
			stateList['NE'] = 'NEBRASKA';
			stateList['NV'] = 'NEVADA';
			stateList['NH'] = 'NEW HAMPSHIRE';
			stateList['NJ'] = 'NEW JERSEY';
			stateList['NM'] = 'NEW MEXICO';
			stateList['NY'] = 'NEW YORK';
			stateList['NC'] = 'NORTH CAROLINA';
			stateList['ND'] = 'NORTH DAKOTA';
			stateList['OH'] = 'OHIO';
			stateList['OK'] = 'OKLAHOMA';
			stateList['OR'] = 'OREGON';
			stateList['PA'] = 'PENNSYLVANIA';
			stateList['RI'] = 'RHODE ISLAND';
			stateList['SC'] = 'SOUTH CAROLINA';
			stateList['SD'] = 'SOUTH DAKOTA';
			stateList['TN'] = 'TENNESSEE';
			stateList['TX'] = 'TEXAS';
			stateList['UT'] = 'UTAH';
			stateList['VT'] = 'VERMONT';
			stateList['VA'] = 'VIRGINIA';
			stateList['WA'] = 'WASHINGTON';
			stateList['WV'] = 'WEST VIRGINIA';
			stateList['WI'] = 'WISCONSIN';
			stateList['WY'] = 'WYOMING';

		}

		var selectedStateElement = document.getElementById('prefill_state');
		var selectedState = '';

		if( selectedStateElement !== null ) {
			selectedState = selectedStateElement.value;
		}

		// Loop through the above array
		for( state in stateList ) {
			var isSelected = false;

			if( state == selectedState ) {
				isSelected = true;
			}

			stateSelector.options[stateSelector.options.length] = new Option(stateList[state], state, isSelected, isSelected);
		}
	}

	function setCountry(country) {
		var new_state_label = 'State:';
		var new_postalcode_label = 'ZIP code:';
		var postalcode_error_text = 'US ZIP code needs to be exactly 5 numbers';
		var postalcode_error_pattern = '\d\d\d\d\d';

		if( country == "Canada" ) {
			new_state_label = 'Province:';
			new_postalcode_label = 'Postal code';
			postalcode_error_text = 'Canadian postal code needs to be 6 characters, such as "K1A0B1"';
			postalcode_error_pattern = '[A-Za-z]\d[A-Za-z]\d[A-Za-z]\d';
		}

		if( document.all) {
			document.getElementById('state_label').innerText = new_state_label;
			document.getElementById('postalcode_label').innerText = new_postalcode_label;
		} else {
			document.getElementById('state_label').textContent = new_state_label;
			document.getElementById('postalcode_label').textContent = new_postalcode_label;
		}

		updateStates(country);
	}

var initCountrySelector = function() {
	var countrySet = false;
	var canadaSelector = document.getElementById('country_Canada');

	if( canadaSelector !== null ) {
		canadaSelector.onClick = function() {
			setCountry('Canada');
		}

		if( canadaSelector.checked ) {
			setCountry('Canada');
			countrySet = true;
		} 
			
	} 

	var usaSelector = document.getElementById('country_USA');

	if( usaSelector !== null ) {
		usaSelector.onClick = function() {
			setCountry('USA');
		}

		if( usaSelector.checked ) {
			setCountry('USA');
			countrySet = true;
		}
	} 
}

function submitWithAction(formId, actionId, action) {
	var actionField = document.getElementById(actionId);
	
	if( actionField != null ) {
		actionField.value = action;
	}
	
	var myForm = document.getElementById(formId);
	if( myForm != null ) {
		myForm.submit();
	}
}

/********************** AJAX-y goodies ********************************/

/* 
 * Finds submittable form elements in formId who's name confirms to namePattern  * and returns a string suitable for POSTing. 
 */
function getSubmitValues(formId, namePattern) { 
	var form = document.getElementById(formId);
	var postValues = '';

	for( var elementIndex = 0; elementIndex < form.elements.length; elementIndex++ ) {
		if( form.elements[elementIndex] != null && namePattern.test(form.elements[elementIndex].name)) {
			var element = form.elements[elementIndex];

			if( element.type == 'text' ||
				element.type == 'password' ||
				element.type == 'hidden' ||
				element.type == 'textarea') {
			
				postValues += '&' + element.name + '=' + escape(element.value);
			} else if( element.type == 'select-one') {
				postValues += '&' + element.name + '=' + escape(element.options[element.selectedIndex].value);
			} else if( element.type == 'radio' || element.type == 'checkbox') {
				if( element.checked ) {
					postValues += '&' + element.name + '=' + escape(element.value);
				}
			
			} else {
				//alert(element.name + ' -- ' + element.type); 
			}
		}
	}

	return postValues;
}

/*
 * Replaces HTML in a given target ID.
 */
function replaceHtml(url, targetId, errorHandler) {
	var httpRequest;

    if (window.XMLHttpRequest) { // Mozilla, Safari, ...
        httpRequest = new XMLHttpRequest();
        //if (httpRequest.overrideMimeType) {
        //    httpRequest.overrideMimeType('text/xml');
        //    // See note below about this line
        //}
    } else if (window.ActiveXObject) { // IE
        try {
            httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
        } 
        catch (e) {
	  		try {
   		    	httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
            } catch (e) {}
         }
     }
	

    if (!httpRequest) {
        alert('Giving up :( Cannot create an XMLHTTP instance');
        return false;
    }

	/* The callback function */
	httpRequest.onreadystatechange = function() {
		if (httpRequest.readyState == 4) {
			if (httpRequest.status >= 200 && httpRequest.status < 300) {
				var target = document.getElementById(targetId);
				if( target !== null ) {
					target.innerHTML = httpRequest.responseText;

					onPageLoad();
				}
			} else if( httpRequest.status >= 400 ) {
				errorHandler();
				return;
			}
		}
	 }

    httpRequest.open('GET', url, true);
    httpRequest.send('');

}

/* Posts an ajax form to a specified target and calls either the success
 * handler or the error handler.
 */
function postAjaxForm(formId, postTarget, successHandler, errorHandler) {
	
	var postString = getSubmitValues(formId, /^f_/);
	postAjax(postString, postTarget, successHandler, errorHandler);
}

/*
 * Given the post string already, post the string async 
 */
function postAjax(postString, postTarget, successHandler, errorHandler) {
	
	/* Set up the request */
	var xmlhttp = null;// =  new XMLHttpRequest();

	if (window.XMLHttpRequest) { // Mozilla, Safari, ...
        xmlhttp = new XMLHttpRequest();
        if (xmlhttp.overrideMimeType) {
            xmlhttp.overrideMimeType('text/xml');
            // See note below about this line
        }

    } else if (window.ActiveXObject) { // IE
        try {
    	        xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                   xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
                 } catch (e) {}
            }
    }

    if (!xmlhttp) {
        alert('Giving up :( Cannot create an XMLHTTP instance');
	}
         
	xmlhttp.open('POST', postTarget + '?nocache=' + new Date(), true);

	/* The callback function */
	xmlhttp.onreadystatechange = function() {
		
		if (xmlhttp.readyState == 4) {
			if (xmlhttp.status >= 200 && xmlhttp.status < 300) {
				if( successHandler != null ) {
    				successHandler(xmlhttp.responseXML);
				}
				return;
			} else if( xmlhttp.status >= 400 ) {
				if( errorHandler != null ) {
					errorHandler();
				}
				return;
			} 
		}
	 }
	 
	//var statusField = document.getElementById('status_field');
	//statusField.innerHTML = 'Gathering data...';


	//statusField.innerHTML = 'Sending request...';
	//statusField.className = 'submitInfo';

	/* Send the POST request */
	xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');	
	xmlhttp.send(postString);				
}

function getXmlAttributes(elementAttributes) {
	var attributes = new Object();
	if( elementAttributes != null ) {
		// Iterate over the attributes in the rrdprofile element and 
		// and them to the photo info
		for( var i=0; i < elementAttributes.length; i++ ) {
			var attribute = elementAttributes.item(i);

			attributes[attribute.nodeName] = attribute.nodeValue;
		} // for attributes
	}

	return attributes;
}

function loadScript(scriptUrl, scriptId) {
	var oldScript = document.getElementById(scriptId);

	
	var script = document.createElement("script");
	script.id = scriptId;
	script.type = 'text/javascript';
	script.src=scriptUrl;

	if( oldScript !== null ) { 
		document.getElementsByTagName("head")[0].replaceChild(script, oldScript);
	} else {
		document.getElementsByTagName("head")[0].appendChild(script);
	}
}

/* ------------------- Testing goodies -------------------------*/
function walkObject(obj) {
	// log.debug("walkObject of type: ");
	// log.debug(typeof obj	)
	if( obj != null ) { 
		var keys = new Array();
		for( var key in obj ) {
			if( obj[key] != null && key != "outerHTML" && key != "innerHTML" && key != "outerText" && key != "innerText") {
			 keys.push(key + ' => ' + obj[key]);
			}
		}
	
		keys.sort();
//		if( log != null ) {
//			log.debug(keys.join('\n'));
//		} else {
			alert(keys.join('\n'));
//		}
	} else {
		// log.debug('object is null');
	}
}

