//  Displays an "Ajax Loading" warning in the provided element's innerHTML
//  The Call to Action text is optional and will say "Please be patient..." if nothing else is provided  
function displayRelativeAjaxWarning(elementId, loadingText,callToAction) {

	if ( callToAction === null || typeof(callToAction) == "undefined") {
		callToAction = "Please be patient...";
	}
	
	var ajaxHtml =  "<div class='ajaxWarning' id='relativeAjaxWarning'>";
		ajaxHtml +=	"<div class='ajGrayHeading' style='padding-bottom:5px'>" + loadingText + "</div>";
		ajaxHtml +=	"<img src='./images/ajax_loading.gif' border='0'>";
		ajaxHtml +=	"<div class='ajGrayText' style='padding-top:10px'>" + callToAction + "</div>";
		ajaxHtml +=	"</div>";
	$(elementId).innerHTML = ajaxHtml;
	toggleLayerBlock(elementId, true);
	toggleLayerBlock("relativeAjaxWarning", true);
}

//  Displays an "Ajax Loading" warning in the provided element's innerHTML
function displayAbsoluteAjaxWarning(elementId, loadingText) {
	var ajaxHtml =  "<div class='absoluteAjaxWarning' id='absoluteAjaxWarning'>";
		ajaxHtml +=	"<div class='ajGrayHeading'>" + loadingText + "</div>";
		ajaxHtml +=	"<img src='./images/ajax_loading.gif' border='0'>";
		ajaxHtml +=	"<div class='ajGrayText' style='padding-top:10px'>Please be patient...</div>";
		ajaxHtml +=	"</div>";
	$(elementId).innerHTML = ajaxHtml;
	toggleLayerBlock(elementId, true);
	toggleLayerBlock("absoluteAjaxWarning", true);
}

function hideAjaxWarning(elementId) {
	toggleLayerBlock(elementId, false);
}

function setButtonEnabled(buttonId, isEnabled) {
	if ( typeof(buttonId) != "undefined" ) {
		$(buttonId).disabled = !isEnabled;
		if(isEnabled)
			$(buttonId).className="ajButton";
		else
			$(buttonId).className="ajDisabledButton";
	}
}

/*  NOTE: To use the following calendar functions, you must include this <div> 
	and related .js files in your JSP:
	<div id="dateCalendarPopupDiv" STYLE="z-index:5;position:absolute;visibility:hidden;background-color:white;layer-background-color:white;"></DIV>
	<link href="./css/calendar.css" rel="stylesheet" type="text/css" />
	<script src="./js/calendarPopup.js" type="text/javascript"></script>	
	<script src="./js/prototype.js" type="text/javascript"></script>
*/

/*  Shows a Calendar popup and sends selected date to a text input.  Also see
    the showCalendarWithSpan() */  
function showCalendarWithTextInput(divId, textBox, anchor, callback)
{
	var calendar = new CalendarPopup(divId);
	calendar.setCssPrefix("AJ");
	var textElement = $(textBox);
	calendar.setDateUpdatedCallback(callback);
	calendar.selectTextElement(textElement,anchor,"MM/dd/yyyy");
}

/*  Shows a Calendar popup and sends selected date to a text input.  Also see
    showCalendarWithTextInput() */
function showCalendarWithSpan(divId, spanTagName, anchor, callback, optionalXOffset, optionalYOffset)
{
	var calendar = new CalendarPopup(divId);
	calendar.setCssPrefix("AJ");
	var spanElement = $(spanTagName);
	calendar.setDateUpdatedCallback(callback);
	if (parseInt(optionalXOffset) == optionalXOffset)
		calendar.setXOffset(optionalXOffset);
	if (parseInt(optionalYOffset) == optionalYOffset)
		calendar.setYOffset(optionalYOffset);
	calendar.selectSpanElement(spanElement,anchor,"MM/dd/yyyy");
}

//  Display the layer if true else hide if false
//  Sets display to inline so element acts like a <span> insertion
function toggleLayerInline( layerId, isShow )
{   
	var style = $(layerId).style;  
	style.display = (isShow)?'inline':'none';
}

//  Display the layer if true else hide if false
//  Sets display to block so element acts like a <div> insertion
function toggleLayerBlock( layerId, isShow )
{   
	var style = $(layerId).style;  
	style.display = (isShow)?'block':'none';
}


//  Display the layer if hidden or hide if visible
//  Sets display to inline so element acts like a <span> insertion
function toggleVisibilityInline( whichLayer)
{  
	var style = $(whichLayer).style;  
	style.display = (style.display == 'inline')?'none':'inline';
}

//  Display the layer if hidden or hide if visible
//  Sets display to block so element acts like a <div> insertion
function toggleVisibilityBlock( whichLayer)
{  
	var style = $(whichLayer).style;  
	style.display = (style.display == 'inline')?'none':'block';
}

function setEnabled(enabled, element1, element2)
{
	$(element1).disabled = !enabled;
	if ( element2 != null && element2 != 'undefined')
		$(element2).disabled = !enabled;
}

//  Assumes the "All" checkbox (cb) is preselected upon page load.
//  (State 1) If any non-"All" cb was selected so deselect the "All" cb.
//  (State 2) If the "All" cb was selected, then deselect all non-"All" checkboxes.
//  (State 3) If all non-"All" cb are deselected, then select the "All" cb.
//  NOTE:  requires that a global IsAllSelected variable maintain state of "All" 
//  between user updates.  This variable is passed as the globalIsAllSelected
//  NOTE:  Returns the updated global "All" selection variable so parent calling method
//  can update it's global instance
function updateAllCBSelection(checkboxes, allCBValue, globalIsAllSelected)
{
	//  First determine the current CB state
	var isNonAllSelected = false;
	var isAllSelected = false;
	for (i = 0; i < checkboxes.length; i++) {
      if (checkboxes[i].value == allCBValue)
         isAllSelected = checkboxes[i].checked;
      else if (checkboxes[i].checked)
         isNonAllSelected = true;
	}
	
	if ( isNonAllSelected && isAllSelected) {
		if ( globalIsAllSelected ) {
			//  (State 1) A non-"All" cb was selected so deselect the "All" cb.
			toggleInput(checkboxes, allCBValue, false);
			globalIsAllSelected = false;
		} else {
		//  (State 2) The "All" cb was selected so deselect the non-"All" checkboxes.
			deselectAllCBBut(checkboxes, allCBValue)
			globalIsAllSelected = true;
		}
	} else if ( isNonAllSelected && !isAllSelected) {
		// A non-"All" was selected but everything is as it's supposed to be
	} else if ( !isNonAllSelected && isAllSelected) {
		// Probably can never get here....
	} else if ( !isNonAllSelected && !isAllSelected) {
		//  (State 3) Either the "All" or all the non-"All" checkboxes were deselected
		//  In either case, reselect the "All" cb
			toggleInput(checkboxes, allCBValue, true);
			globalIsAllSelected = true;
	}
	return globalIsAllSelected;
}
//  Sets the input element (checkbox or radio) with the given value from the given input array to the provided checked state
function toggleInput(inputs, inputValueToUpdate, isChecked)
{
	for (i = 0; i < inputs.length; i++) {
      if (inputs[i].value == inputValueToUpdate )
         inputs[i].checked = isChecked;
	}
}

//  Deselects all Checkboxes except one with the given name
function deselectAllCBBut(checkboxes, cbValueToSelect)
{
	for (i = 0; i < checkboxes.length; i++)
		checkboxes[i].checked = (checkboxes[i].value == cbValueToSelect);
}

//  Returns a single selected value for the given radiobutton
function getSelectedRadioButton(radioButtons)
{
	for (i = 0; i < radioButtons.length; i++) {
      if (radioButtons[i].checked)
         return radioButtons[i];
	}
	return null;
}

//  Returns all selected value for the given checkboxes
function getSelectedCheckboxes(checkboxes)
{
	var selection = new Array();
	var index = 0;
	for (i = 0; i < checkboxes.length; i++) {
      	if (checkboxes[i].checked) {
         	selection[index] = checkboxes[i];
         	index++;
		}
	}
	return selection;
}

//  Selected checkboxes with given values in the array of provided checkboxes
//  and deselects all other checkboxes
function selectCheckboxes(checkboxes, valuesToSelect)
{
	var isSelected;
	for (i = 0; i < checkboxes.length; i++) {
		isSelected = false;
		for (j = 0; j < valuesToSelect.length; j++) {
	      	if (checkboxes[i].value == valuesToSelect[j]) {
    	     	isSelected = true;
	         	break;
	         }
		}
		checkboxes[i].checked = isSelected;
	}
}

//  Selected radioButton with given value
function selectRadioButton(radioButtons, valueToSelect)
{
	for (i = 0; i < radioButtons.length; i++) {
      	if (radioButtons[i].value == valueToSelect) {
			radioButtons[i].checked = true;
			return;
         }
	}
}
function replaceAll( str, from, to ) {
    var idx = str.indexOf( from );


    while ( idx > -1 ) {
        str = str.replace( from, to ); 
        idx = str.indexOf( from, (idx + to.length) );
    }

    return str;
}


function sprintf(str){
    var arg = arguments;
    for(var i=0; i<arg.length; i++) if(arg[i]==undefined) arg[i] = ""; 
    i = 1;
    return str.replace(/(([^\\]?)%(s|d))/g, function(s, a1, a2){ return a2 + arg[i++]; });
}

//  Creates a cookie with the given name/value with the supplied expiration in days
function createCookie(name,value,days) {
	var expires = "";
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		expires = "expires="+date.toGMTString();
	}
	document.cookie = name+"="+value+"; path=/;"+expires+";";
}

//  Returns the cookie value associated with the given name (if found)
function readCookie(name) {
	var nameEQ = name + "=";
	var cookies = document.cookie.split(';');
	for(var i=0;i < cookies.length;i++) {
		var cookie = cookies[i];
		while (cookie.charAt(0)==' ') 
			cookie = cookie.substring(1,cookie.length);
		if (cookie.indexOf(nameEQ) == 0) 
			return cookie.substring(nameEQ.length,cookie.length);
	}
	return null;
}

//  Deletes the cookie with the given name
function eraseCookie(name) {
	createCookie(name,"",-1);
}

//  Disables a button if the given input field has no data
//  Usage:  onkeyup="updateInputRequired('neighborhoodName', 'nNameError', 'Submit' 'A neighborhood name is required.')"
function updateInputRequired(inputId, errorId, errorMessage, buttonId) {

	var numChars = $(inputId).value.length;
	if ( numChars == 0 ) {
		$(errorId).innerHTML=errorMessage;
		setButtonEnabled(buttonId,false);
	} else {
		$(errorId).innerHTML="";
		setButtonEnabled(buttonId,true);
	}
}

//  Disables a button if the given input field has to much or too little data
//  Usage:  onkeyup="updateMaxMinCharactersRequired(100,200,'nameInput', 'nNameError', 'Submit', 'Neighborhood name.')"
function updateMaxMinCharactersRequired(min, max, inputId, errorId, errorPrefix, buttonId) {

	var error = getMaxMinCharactersRequired(min, max, inputId, errorPrefix);
	$(errorId).innerHTML = error;
	setButtonEnabled(buttonId,error.length == 0);
}

//  @return the appropriate error message in the provided input field has to much or too little data
function getMaxMinCharactersRequired(min, max, inputId, errorPrefix) {

	var numChars = $(inputId).value.length;
	if ( numChars < min ) {
		return errorPrefix + " requires " + (min - numChars) + " more characters";
	} else if (numChars > max){
		return errorPrefix + " requires " + (numChars - max) + " fewer characters";
	} else {
		return ""; 
	}
}
