function addCommas(pfValue,bShowPeriods)
{
	var sValue = this.removeDigit(pfValue,",");
	var bIsDecimal = false;
	var sRemainder = "";
	var iGroup = 0;
	var bIsEvenLength = true;
	var iInitialGroupLength = 0;
	var iValueLen = 0;
	
	if (!bShowPeriods)
	{
		var iDecimalPlace = sValue.lastIndexOf(".",sValue.length);
		
		if (iDecimalPlace>-1)
		{
			bIsDecimal = true;
			sRemainder = sValue.substring(iDecimalPlace)
			sValue = sValue.substring(0,iDecimalPlace);
		}
	}
	
	iGroup = Math.floor(sValue.length / 3);
	
	if (sValue.length % 3 > 0)
	{
		iInitialGroupLength = sValue.length - (3 * iGroup);
		iGroup += 1;
		bIsEvenLength = false;
	}
	
	var sAryValue = new Array(iGroup);
	var iValueLen = sValue.length;
	
	for (var i=0; i<sAryValue.length; i++)
	{
		if (i == 0 && !bIsEvenLength)
		{
			sAryValue[i] = sValue.substring(0,iInitialGroupLength);
			iValueLen -= iInitialGroupLength;
		}
		else
		{
			sAryValue[i] = sValue.substring(0,3);
			iValueLen -= 3;
		}
		
		sValue = sValue.substring(sValue.length - iValueLen);
	}
	
	sValue = sAryValue.join(",");
	
	if (bIsDecimal)
	{
		sValue += sRemainder;
	}
	
	return sValue;
}

function removeDigit(psOrigValue,psCharToRemove)
{
	var psOrigValue = psOrigValue.toString();
	var sTempValue = psOrigValue;
	var iDigitLoc;
	while (sTempValue.indexOf(psCharToRemove) > -1) {
		iDigitLoc = sTempValue.indexOf(psCharToRemove);
		sTempValue1 = sTempValue.substring(0,iDigitLoc);
		sTempValue2 = sTempValue.substring(iDigitLoc+1);
		sTempValue  = sTempValue1 + sTempValue2;
		}
	return sTempValue;
}

function formatCurrency(pfValue,piNoOfDigits)
{
	var piWholeNo;
	var piDecimal;
	
	if (pfValue.toString().indexOf(".") == -1)
	{
		piWholeNo = pfValue;
		piDecimal = 0;
	}
	else
	{
		piWholeNo = parseInt(pfValue.toString().substring(0, pfValue.toString().indexOf(".")));
		piDecimal = Math.round(pfValue * Math.pow(10,piNoOfDigits)) % Math.pow(10,piNoOfDigits);// parseInt(pfValue.toString().substring(pfValue.toString().indexOf(".")+1));
	}
	
	if (piNoOfDigits == 2)
	{
		if (piDecimal >= 100)
		{
			piDecimal = Math.round((piDecimal / Math.pow(10,(piDecimal.toString().length - 2))));
		}
		//return pfValue.toString().indexOf(".");
		return "$" + piWholeNo.toString() + "." + this.twoDigits(piDecimal).toString();
	}
	else if (piNoOfDigits == 0)
	{
		return "$" + Math.round(pfValue).toString();
	}
	else
	{
		return "$" + pfValue.toString();
	}
}

function twoDigits(piValue)
{
	if (piValue < 10)
	{
		return "0" + piValue.toString();
	}
	else
	{
		return piValue;
	}
}
	
function Trim(psValue)
{
	while (psValue.substring(0,1) == " ")
		psValue = psValue.substring(1);
	while (psValue.substring((psValue.length-1),psValue.length)==" ")
		psValue = psValue.substring(0,psValue.length-1,psValue.length);
	return psValue;
}

// Creates mailto link (to circumvent spam scrapers)
function SendCoStarEmail(psEmailPrefix, psSubject, psBodyText)
{
	var sLink = "";
	var sSubject = "";
	var sBodyText = "";
	
	if (psEmailPrefix.toLowerCase().indexOf("@costar.com") == -1 && psEmailPrefix.toLowerCase().indexOf("@costargroup.com"))
	{
		psEmailPrefix += "@costar.com";
	}
	
	if (psSubject != "" && psSubject != null)
	{
		sSubject = "?subject=" + escape(psSubject);
	}
	
	if (psBodyText != "" && psBodyText != null)
	{
		if (sLink.indexOf("?subject=") > -1)
		{
			sBodyText = "&";
		}
		else
		{
			sBodyText = "?";
		}

		sBodyText += "body=" + escape(psBodyText);
	}

	location.href = "mailto:" + psEmailPrefix + sSubject + sBodyText;
}

// Checks to see if e-mail address is in valid format	
function isValidEmail(psEmailAddress)
{
	var oRegExp = new RegExp("\\S+@[^\\.].*\\.[a-z]{2,}");
	return oRegExp.test(psEmailAddress);
}

// Checks to see if URL is in valid format	
function isValidURL(psURL)
{
	var oRegExp = new RegExp("(http|ftp|https)(:\\/\\/[\\w]+)(.[\\w]+)([\\w\\-\\.,@?^=%&:/~\\+#]*[\\w\\-\\@?^=%&/~\\+#])?");
	return oRegExp.test(psURL);
}

// Checks to see if the value is an integer
function isInteger(psValue)
{	
	var oRegExp = new RegExp("^([\\+\\-])?([0-9]+)$");
	return oRegExp.test(psValue);
}

// Checks to see if the value is numeric (inc. decimal)
function isNumeric(psValue)
{
	var oRegExp = new RegExp("^([\\+\\-])?([0-9]+)(\\.[0-9]+)*$");
	return oRegExp.test(psValue);
}

// Checks to see if string is in MM/DD/YYYY format
function isValidDate(psValue)
{
	var oRegExp = new RegExp("((^(10|12|0?[13578])([/])(3[01]|[12][0-9]|0?[1-9])([/])((1[8-9]\\d{2})|([2-9]\\d{3}))$)|(^(11|0?[469])([/])(30|[12][0-9]|0?[1-9])([/])((1[8-9]\\d{2})|([2-9]\\d{3}))$)|(^(0?2)([/])(2[0-8]|1[0-9]|0?[1-9])([/])((1[8-9]\\d{2})|([2-9]\\d{3}))$)|(^(0?2)([/])(29)([/])([2468][048]00)$)|(^(0?2)([/])(29)([/])([3579][26]00)$)|(^(0?2)([/])(29)([/])([1][89][0][48])$)|(^(0?2)([/])(29)([/])([2-9][0-9][0][48])$)|(^(0?2)([/])(29)([/])([1][89][2468][048])$)|(^(0?2)([/])(29)([/])([2-9][0-9][2468][048])$)|(^(0?2)([/])(29)([/])([1][89][13579][26])$)|(^(0?2)([/])(29)([/])([2-9][0-9][13579][26])$))");
	return oRegExp.test(psValue);
}

//supposed to be assigned as a handler for event onKeyPress or onKeyDown
//returns True if Enter key is pressed
function isEnterKeyPressed()
{
	return (event.keyCode == 13);
}

function isValidZipCode(psValue)
{
	var oRegExp5 = /^\d{5}$/;
	var oRegExp9 = /^\d{5}-\d{4}$/;
	return (oRegExp5.test(psValue) || oRegExp9.test(psValue));
}
	
function isValidCreditCardNumber(psValue, psCCType)
{
	var sCCPrefix = "";
	
	switch (psCCType.toUpperCase())
	{
		case "VISA":
			return !(psValue.substring(0,1)!="4" || (psValue.length!=13 && psValue.length!=16));
			break;
		case "MASTERCARD":
			sCCPrefix = parseInt(psValue.substring(0,2));
			return !(sCCPrefix<51 || sCCPrefix>55 || psValue.length!=16);
			break;
		case "AMERICAN EXPRESS":
			sCCPrefix = psValue.substring(0,2);
			return ((sCCPrefix == "34" || sCCPrefix == "37") && psValue.length == 15);
			break;
		case "DINERS CLUB":
			sCCPrefix = parseInt(psValue.substring(0,3));
			return !((sCCPrefix >=300 && sCCPrefix <=305) || (psValue.substring(0,2)=="36" || psValue.substring(0,2)=="38") && psValue.length == 14);
			break;
		default:
			return false;
			break;
	}
}

function CheckForInvalidChars(form)
{
	for (var i = 0; i < form.elements.length; i++)
	{
		oElement = eval("form.elements[" + i.toString() + "]");
		if (typeof(oElement) != "undefined")
		{
			if (oElement.type == "text" || oElement.type == "password")
			{
				if (oElement.value.indexOf('<') > -1)
				{
					anglepos = oElement.value.indexOf('<')+1;
					if (anglepos < oElement.value.length)
					{
						oElement.focus();
						oElement.select();
						alert('You cannot use a beginning angle bracket, followed by other characters, in the search criteria: '+oElement.value);
						oElement.focus();
						oElement.select();
						return false;
					}
				}
			}
		}
	}
	return true;
}

function StripHTMLTags(psText)
{
	var oRegExp = new RegExp("<[^>]+>");

	return psText.replace(oRegExp, "");
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
// FUNCTIONS USED TO CREATE REAL "SELECT AS YOU TYPE" DROP-DOWN BOXES                                 //
// Add the following attributes to the <SELECT> tag:                                                  //
//   <select name="foobar" id="foobarID" onKeyPress="listbox_onkeypress()" onBlur="listbox_onblur()"> //
////////////////////////////////////////////////////////////////////////////////////////////////////////
//   NOTE: By default, hitting <enter> will submit the form. To disable this function, pass in false  //
//         parameter in listbox_onkeypres(), i.e.: listbox_onkeypress(false).                         //
////////////////////////////////////////////////////////////////////////////////////////////////////////
var sFindString = "";
var sTimeoutID = "";
iTimeoutInterval = 500;
var iTimeoutCounter = 0;           
var iTimeoutCounterLimit = 3;   
var oControl = "";            

function listbox_onkeypress(pbSubmitOnEnter)
{
	if (pbSubmitOnEnter == null)
	{
		pbSubmitOnEnter = true;
	}
	window.clearInterval(sTimeoutID)
	oControl = window.event.srcElement;
	
	var iKeycode = window.event.keyCode;
	if (iKeycode >= 32)
	{
		var cCharEntered = String.fromCharCode(iKeycode);
		cCharEntered = cCharEntered.toUpperCase(); 
		sFindString += cCharEntered ;
		this.find();
		sTimeoutID = window.setInterval("idle()", iTimeoutInterval);  
	}
	else if (iKeycode == 13 && pbSubmitOnEnter)
	{// Submit if user hits enter key (emulate IE & text fields)
		oControl.form.submit();
	}
}

function listbox_onblur()
{
	window.clearInterval(sTimeoutID);
	this.resetToFind();
}

function idle()
{
	iTimeoutCounter += 1;
	
	if (iTimeoutCounter > iTimeoutCounterLimit)
	{
		this.resetToFind();
		iTimeoutCounter = 0;
		window.clearInterval(sTimeoutID);
	}
}

function resetToFind()
{
	sFindString = "";
}

//TODO: IB: need to work more an the appropriate regular expression
function isValidPhoneNumber(psValue)
{
	var oRegExp = /^\D*\d{3}?\D*\d{3}?\D*\d{4}?\D*$/;
	return oRegExp.test(psValue);
}

function find()
{
	var allOptions = oControl.options;
	
	for (var i=0; i < allOptions.length; i++)
	{
		sNextOptionText = allOptions(i).text.toUpperCase();
		if (!isNaN(sNextOptionText) && !isNaN(sFindString))
		{
			sNextOptionText *= 1;
			sFindString *= 1;
		}
		if (sFindString == sNextOptionText)
		{
			oControl.selectedIndex = i;
			window.event.returnValue = false;
			break;
		}
		if (i < allOptions.length-1)
		{
			sLookAheadOptionText = allOptions(i+1).text.toUpperCase() ;
			if ((sFindString > sNextOptionText) && (sFindString < sLookAheadOptionText))
			{
				oControl.selectedIndex = i+1;
				window.event.cancelBubble = true;
				window.event.returnValue = false;
				break;
			}
		}
		else
		{
			if (sFindString > sNextOptionText)
			{
				oControl.selectedIndex = allOptions.length-1;
				window.event.cancelBubble = true;
				window.event.returnValue = false;
				break;
			}
		}
	}
}

//get a string describing duration between psDateStr1 and psDateStr2
//  if psDateStr2 is blank, then use today
function GetDuration(psDateStr1,psDateStr2,pbInclDays) {
  var iMSecPerDay = 86400000;
  var iMSecPerYr = 31557600000;
  if (psDateStr1=="" || psDateStr1=="-")
    return psDateStr1;
    
  var iMSec1 = Date.parse(psDateStr1);
  var iMSec2 = 0;
  if (psDateStr2=="") {
    var oToday = new Date();
    iMSec2 = Date.parse(oToday.getMonth()+1 + "/" + oToday.getDate() + "/" + oToday.getFullYear());
  }
  else {
    iMSec2 = Date.parse(psDateStr2);
  }

  var iDiffMSec = iMSec2 - iMSec1;
  var iDiffYrs = Math.floor(iDiffMSec/iMSecPerYr);
  iDiffMSec = iDiffMSec - (iDiffYrs * iMSecPerYr);
  var iDiffDays = Math.floor(iDiffMSec/iMSecPerDay);
  var iDiffMos = Math.floor(iDiffDays/30);
  var sRetStr = "";
  var sUnitStr = " yr";
  if (iDiffYrs > 0) {
    if (iDiffYrs > 1)
        sUnitStr = " yrs";
    sRetStr = iDiffYrs.toString() + sUnitStr;
  }
  sUnitStr = " mo";
  if (iDiffMos > 0) {
    if (iDiffMos > 1)
        sUnitStr = " mos";
    if (sRetStr != "")
        sRetStr = sRetStr + ", ";
    sRetStr = sRetStr + iDiffMos.toString() + sUnitStr;    
  }
  
  if (pbInclDays) {
      sUnitStr = " day";
      iDiffDays = iDiffDays - (iDiffMos*30);
      if (iDiffDays>0) {
        if (iDiffDays>1)
          sUnitStr = " days";
        if (sRetStr != "")
          sRetStr = sRetStr + ", ";
        sRetStr = sRetStr + iDiffDays.toString() + sUnitStr;            
      }
      else if (sRetStr=="") {
        sRetStr = "0 days";
      }
  }
  else if (sRetStr=="") {
    sRetStr = "0 mos";
  }
  
  return sRetStr;
  
  
}

////////////////////////////////////////////////////////////////////////////////////////////////////////