//NOTE: Future developers, in order to keep this file manageable, please
//try to maintain functions alphabetically, and maintain the following
//'table of contents'.  Also, please always be careful to use local variables
//and use the var statement before variables otherwise JavaScript may allocate
//a global resulting in unpredictable, and difficult to debug behavior.

//CASCheckAlpha(ctlName) - Checks that data complies with alpha fomat.
//CASCheckDate(ctlName) - Checks that data complies with date format.
//CASCheckDate2(ctlName) - Checks that data complies with date format.
//CASCheckFieldLength(ctlName, maxLength) - Checks data length not longer than db field.
//CASCheckForErrors(control, ctlType) - case stmt on ctlType to validate data.
//CASCheckMoney(ctlName) - Checks that data complies with currency format.
//CASCheckNumber(ctlName,maxDecimals) - Checks that data complies with numeric format.
//CASCheckPhoneNumber(ctlName) - Checks tat data complies with phone format.
//CASFindControlInDoc(docToSearch,nameToFind) - Finds a named control within a doc object.
//CASPopupCommit(win,value) - Returns value from win using comma delim names and values
//CASPopupSelect(url,targetname) - Begins popup select functionality.
//checkListBox(ctlName,text) - Used to maintain the error list.
//clearHistory() - Allegedly tries to override a history entry...don't know why.
//DetectBrowser() - returns whether Browser is E or N.
//outputError (ctlName, text) - Enters an error into existing error box by ctlName
//setErrorFocus() - Sets focus to ctl when error list is selected.
//ValidDigits(val) - Verifies that target contains only numeric chars.


/* ===================================================================
FUNCTION:	CASCheckAlpha()
INPUT: 		field name,field value and database defined length
RETURNS:        true or false
DESC:		checks that the value input in the field is not longer 
		than the size of the database field
======================================================================= */
function CASCheckAlpha(ctlName)
{ 
var ctlValue = ctlName.value;

 if (ctlValue.length > ctlName.maxLength)
    outputError(ctlName.name,'The field value is longer than DB definition. ' + ctlValue);
 else
  {
    checkListBox(ctlName.name,"");	
    return true;
  }
}

/* ===================================================================
FUNCTION:	CASCheckDate(Control)
INPUT:	Control to be validated
RETURNS:	nothing
DESC:		checks that the value input in the field is a valid date
		Date value received is assumed to be in a mmddyyyy or 
		mm/dd/yyyy format
======================================================================= */
function CASCheckDate(ctlName)
{
 var i;
 var date = new Date();
 var value;
 var len = 0;
 var ctlValue = ctlName.value;
 
  if (ctlValue.length = 8 && ValidDigits(ctlValue))
    value = ctlValue.substr(0,2) + "/" + ctlValue.substr(2,2) + "/" + ctlValue.substr(4,4); 
  else
    value = ctlValue;	

  len = value.length;
  
  if ((len != 10))
      outputError(ctlName.name, "You have entered an invalid date. " + ctlValue);
  else
   {
     if(value.slice(0,2) < "01")
	outputError(ctlName.name, "You have entered an invalid month. " + ctlValue);
     else
       if(value.slice(0,2) > "12")
         outputError(ctlName.name, "You have entered an invalid month. " + ctlValue);
     else
       if(value.slice(3,5) < "01")
         outputError(ctlName.name,"You have entered an invalid day. " + ctlValue);
       else
	   if(value.slice(3,5) > "31")
            outputError(ctlName.name,"You have entered an invalid day. " + ctlValue);
         else
            checkListBox(ctlName.name,"");	
  }
}

/* ===================================================================
FUNCTION:	CASCheckDate2(Control)
INPUT:	Control to be validated
RETURNS:	nothing
DESC:		checks that the value input in the field is a valid date
		The formats supported include whatever the browsers allow 
		using the date.parse() function.  This will be transformed
                into MM/DD/YYYY format by the function if no errors.  If
                format is indistinct, has bias towards MM/DD/YYYY
======================================================================= */
function CASCheckDate2(ctlName)
{
  var date;
  var temp;
  var ctlValue;
  var bError = false;
  var unit = new Array("", "", "");
  var i;
  var j;
  var ch;
  var bError = false;
  var newValue = "";

  ctlValue = ctlName.value;
  if(ctlValue.length < 6 || ctlValue.length > 10)
    bError=true;

  if(ctlValue.search("/") == -1 && ctlValue.search("-") == -1 && !bError)
  {
    //The user didn't put their own slashes in.  We'll break it up for them 
    //(assuming 2/2/2 or 2/2/4)
    unit[0] = ctlValue.substr(0, 2);
    unit[1] = ctlValue.substr(2, 2);
    unit[2] = ctlValue.substr(4);
  }
  else if(!bError)
  {
    if(ctlValue.search("/") == -1)
      unit = ctlValue.split("-");
    else
      unit = ctlValue.split("/");

    if(unit.length != 3)
      bError = true;
  }

  if(!bError)
  {
    if(unit[2].length == 2)
    {
      unit[2] = "20" + unit[2];
    }
    if(unit[0] > 12)
      bError = true;
    if(unit[1] > 31)
      bError = true;

    temp = unit[0] + "/" + unit[1] + "/" + unit[2];
  }

  if(!bError)
  {
    date = new Date(temp);

    //Month
    tempInt = date.getMonth() + 1;
    if(!isNaN(tempInt))
    {
      tempString = new String(tempInt);
      if(tempString.length < 2)
        newValue = newValue + "0";
      newValue = newValue + tempString + "/";

      //Day
      tempInt = date.getDate();
      if(!isNaN(tempInt))
      {
        tempString = new String(tempInt);
        if(tempString.length < 2)
          newValue = newValue + "0";
        newValue = newValue + tempString + "/";
  
        //Year
        tempInt = date.getFullYear();
        if(!isNaN(tempInt))
        {
          tempString = new String(tempInt);
          newValue = newValue + tempString;
  
          ctlName.value = newValue;
        }
        else
          bError = true;
      }
      else
        bError = true;
    }
    else
    {
      bError = true;
    }
  }

  if(bError)
    outputError(ctlName.name, ctlValue + " is an invalid date.  Use MM/DD/YYYY format.");
  else
    checkListBox(ctlName.name,"");	
}

/* ===================================================================
FUNCTION:	CASCheckFieldLength()
INPUT: 		field name and database defined length
RETURNS:        true or false
DESC:		checks that the value input in the field is not longer 
		than the size of the database field
======================================================================= */
function CASCheckFieldLength(ctlName, maxLength)
{ 
var ctlValue=ctlName.value;

 if (ctlValue.length > maxLength)
  {	
    outputError(ctlName.name,'The field value is longer than DB definition.');
    return false;
  }
 else
  {
    checkListBox(ctlName.name,"");	
    return true;
  }
}


/* ===================================================================
FUNCTION:	CASCheckForErrors(control,ctlType)
INPUT: 	control object and field type - i.e(currency, alpha, phone,
		date)
RETURNS:    nothing
DESC:		based on the field type, it will call the appropriate 
            function to check for the validity of the received field.
		When calling the appropriate function it will pass the control.
======================================================================= */
function CASCheckForErrors(control, ctlType)
{
switch(ctlType)
  {
    case "alpha":
      CASCheckAlpha(control);
	break;
    case "date":
      CASCheckDate2(control);
	break;
    case "phone":
      CASCheckPhoneNumber(control);
	break;
    case "currency":
      CASCheckMoney(control);
	break;
    case "numeric":
      CASCheckNumber(control, 0);
	break;
    default:
      alert(ctlType + " is an unsupported type");
	break;
  }
}

/*=======================================================================
FUNCTION: 	CASCheckMoney()
INPUT:	fieldname and field value
RETURNS:	nothing	
DESC:		Checks to see if the users has inserted digits and it returns
            the value inserted formatted as a currency value
====================================================================== */
function CASCheckMoney(ctlName) 
{

var hundred=100;
var thousand=1000;
var million=1000000;
var numberIn = ctlName.value;
var i;

numberIn = numberIn.replace(",", "");
if (ValidDigits(numberIn))
{
  numberIn = numberIn.replace("$", "");
  //-- Returns passed number as string in $xxx,xxx.xx format.
  numberIn=eval(numberIn);
  workNum=Math.abs((Math.round(numberIn*hundred)/hundred));
  workStr=""+workNum; // convert to a string
  if (workStr.indexOf(".")==-1)
  { // add the cents if necessary
  	workStr+=".00";
  }
  dStr=workStr.substr(0,workStr.indexOf("."));
  dNum=dStr-0;
  pStr=workStr.substr(workStr.indexOf("."));
  while (pStr.length<3)
  {
 	pStr+="0";
  }

  //--- Adds comma in thousands place.
  if (dNum>=thousand) 
  {
     dLen=dStr.length;
     dStr=parseInt(""+(dNum/thousand))+","+dStr.substring(dLen-3,dLen);
  }

  //-- Adds comma in millions place.
  if (dNum>=million) 
  {
     dLen=dStr.length;
     dStr=parseInt(""+(dNum/million))+","+dStr.substring(dLen-7,dLen);
  }
  formattedMoney = dStr + pStr; 
  
  // Put numbers in parentheses if negative.
  if (numberIn<0) 
  {
     formattedMoney="("+formattedMoney+")";
  }
  ctlName.value = "$" + formattedMoney;
  checkListBox(ctlName.name,"");
}
else
  outputError(ctlName.name, "you have entered an invalid amount. " + ctlName.value);
}



/* ======================================================================
FUNCTION:   CASCheckNumber()
INPUT:	field name, field value, field length and expected 
		decimal precision
RETURNS:	Error message if fails
DESC:		Check field for the right precision and throws an error
		message.
====================================================================== */
function CASCheckNumber(ctlName,maxDecimals)
{

  var ch="";
  var length;
  var decpos=999;
  var i;
  var valid=true;  
  var ctlValue = ctlName.value;
  var value = ctlValue.split(".");

  if (CASCheckFieldLength(ctlName,ctlName.maxLength))	
    {
    length = ctlValue.length;

    // second let's check if we got digits(0-9) and a "." or ",".
    // this would be the only allowed characters 

    for (i=0;i<=ctlValue.length-1;i++)
     {
      ch = ctlValue.substring(i,i+1);
      if ((ch < "0" || ch > "9") && (ch != ".")) 
       {
         outputError(ctlName.name, "You have entered an invalid decimal number.  " + ctlValue);
         valid = false;
         break;
       }
     }
    if (valid==true)
     {
      if (value.length > 2)
         outputError(ctlName.name, "You have too many decimals points.  " + ctlValue);
      else
       {
         for(i=0; i<=ctlValue.length-1;i++)
         {
            if(ctlValue.charAt(i) == ".")
	      decpos = i;
         }
  
         if ((ctlValue.length - decpos) > maxDecimals)
         {
 	   outputError(ctlName.name, "The number you have entered contains too many decimal positions. " + ctlValue);
           valid = false;
         }
      }
     if(valid)
       checkListBox(ctlName.name,"");	
    }
   }
  else
  {
    valid= false;
    outputError(ctlName.name, "The number you have entered contains too many decimal positions. " + ctlValue);
  }

  return valid;
 }       

/*=======================================================================
FUNCTION: 	CASCheckPhoneNumber()
INPUT:		fieldname and field value
RETURNS:	nothing	
DESC:		Checks to see if the phone number entered is valid. It is
		expected to be 10 digits long and it can be expressed as 
		(410) 999-9999 or 4109999999.
====================================================================== */
function CASCheckPhoneNumber(ctlName)
{

var maxLength = 10;
var i;
var newValue = "";
var ctlValue = ctlName.value;

  if (ctlValue.length != maxLength)
   {
    for(i=0;i<ctlValue.length;i++)
     {
       if((ctlValue.charAt(i)>='0') && (ctlValue.charAt(i) <='9'))
          newValue = newValue + ctlValue.charAt(i);
     }

     if (newValue.length != maxLength)
       outputError(ctlName.name, "The phone number you have entered is invalid. " + ctlValue);
   }
  else 
   {
     newValue = "(" + ctlValue.substr(0,3) + ")" + ctlValue.substr(3,3) + "-" + ctlValue.substr(6,4); 
     ctlName.value = newValue;
     checkListBox(ctlName.name,"");	
    }

 }


/* ======================================================================
FUNCTION: 	CASFindControlInDoc(docToSearch,nameToFind)
INPUT:          docToSearch: document to look through
                nameToFind:  The name within docToSearch to find
RETURNS:	A control	
DESC:           This function finds the specified control by name in the
                specified document.
====================================================================== */
function CASFindControlInDoc(docToSearch,nameToFind)
{
  var curForm;
  var curCtl;
  var i;

  for(i=0;i<docToSearch.forms.length;i++)
  {
    curForm = docToSearch.forms[i];
    curCtl  = curForm.elements[nameToFind];
    if(curCtl != null)
      return curCtl;
  }
}

/* ======================================================================
FUNCTION: 	CASPopupCommit(win,value)
INPUT:          win: window object of popup.  Name must equal target control
                     on the opener.
                value:Value to set back to opener.name
RETURNS:	nothing	
DESC:           Place this call in the event you want to commit the value.
                It is the caller's responsibility to pluck out the name and
                value so as to allow for maximum flexibility.  This function
                has been expanded to support comma separated lists in both name
                and value.  Obviously this means that the values in question
                cannot contain commas, however since this tool is meant for
                code lookups, there should be none.
====================================================================== */
function CASPopupCommit(win,value) 
{
  var hiddenname = win.name;
  var hidden;
  var parentDoc = win.opener.document;
  var valueArray = value.split(",");
  var i;
  var ctl;
  
  //trim our values
  //for(i=0;i<valueArray.length;i++)
  //  valueArray[i] = valueArray[i].replace(" ", "");

  //Search opener for matching names.
  hidden = CASFindControlInDoc(parentDoc, hiddenname);
  if(hidden != null)
  {
    //First trim our names
    var nameArray = hidden.value.split(",");
    for(i=0;i<nameArray.length;i++)
    {
      nameArray[i] = nameArray[i].replace(" ", "");
      ctl = CASFindControlInDoc(parentDoc, nameArray[i]);
      if(ctl != null)
      {
        ctl.value = valueArray[i];
      }
    }
  }
  
  win.close();
}


/* ======================================================================
FUNCTION: 	CASPopupSelect(url,target)
INPUT:      	Url with page to call, field to which a value needs 
		to be returned
RETURNS:	nothing	
DESC:           Place this call in the event you wish to trigger the popup
                window.  it will create a popup window with a name equal to
                the field you are browsing.  Later, the child window will
                set your value.
====================================================================== */
function CASPopupSelect(url,targetname) 
{
  var l= 10;
  var t = 10;
  var w = 500;
  var h = 325;

  var windowprops = "location=no,scrollbars=no,menubars=no,toolbars=no,resizable=yes" +
  ",left=" + l + ",top=" + t + ",width=" + w + ",height=" + h;
  window.open(url,targetname,windowprops);
}

/* ==========================================================================
FUNCTION:	checkListBox(ctlName)
INPUT:	ctlName - name of the field for which need to check existence
            in the error box.
RETURNS:	option index if finds a match, otherwise 0;
DESC:		Function to check if the list box containing the error
		messages already have a message for the specified 
		control.  If there is a message it will return the index
		of the option, otherwise it will return 0 to the calling 
     		function
============================================================================ */
function checkListBox(ctlName,text)
{
  var i=0;

  for(i=0;i < document.forms[0].ErrorMessages.options.length;i++)
  {
    if(document.forms[0].ErrorMessages.options[i].value == ctlName)
    {
      if(text.length == 0)
      {
        document.forms[0].ErrorMessages.options[i].value = document.forms[0].ErrorMessages.options[document.forms[0].ErrorMessages.options.length - 1].value;
        document.forms[0].ErrorMessages.options[i].text =  document.forms[0].ErrorMessages.options[document.forms[0].ErrorMessages.options.length - 1].text;
        document.forms[0].ErrorMessages.options.length--;
        if(navigator.appName.search("Explorer") > -1)
        {
          if(document.forms[0].ErrorMessages.options.length == 0)
            document.forms[0].ErrorMessages.style.visibility = "hidden";
        }
      }
      else
      {
        document.forms[0].ErrorMessages.options[i].value = ctlName;
        document.forms[0].ErrorMessages.options[i].text = text;
      }

      return true;	
    }
    else if(document.forms[0].ErrorMessages.options[i].value == "DELETEME")
    {
      document.forms[0].ErrorMessages.options[i].value = ctlName;
      document.forms[0].ErrorMessages.options[i].text = text;
      return true;
    }
  }   
  return false;
}

/* ==================================================================
FUNCTION: 	clearHistory()
INPUT:	none
RETURNS:	nothing
DESC:		tries to over ride the history of the browser session and 
		forces on the user a specific page.
==================================================================== */
function clearHistory()
{
 location.replace(document.URL);
}

/* ======================================================================
FUNCTION:	DetectBrowser()
INPUT:	none		
RETURNS:	Browser type		
DESC:		detects which browser is being used						
====================================================================== */
function DetectBrowser()
{
  if(navigator.appName.search("Explorer") > -1) return "E";
  if(navigator.appName.search("Netscape") > -1) return "N";
  return "O";
}

/* ======================================================================
FUNCTION: 	outputError()
INPUT:		field name (ctlName) and error message (text)
RETURNS:	nothing
DESC: 		loads the error message box if it doesn't exist and outputs
			errors from Java error object into the display box on the
			error frame; also used as the JavaScript error handling 
			mechanism
====================================================================== */
function outputError (ctlName, text) 
{
 var i;
 var j=0;
 var option=0;

// if(navigator.appName.search("Explorer") > -1)
// {
   for(i=0; i < document.forms[0].elements.length; i++)
   {
     if (document.forms[0].elements[i].name == "ErrorMessages")
     {
       j = document.forms[0].ErrorMessages.options.length;
	
       if (!(checkListBox(ctlName,text)))
       {
         document.forms[0].ErrorMessages.options[j] = new Option(text, ctlName);
       }
	  
       if(navigator.appName.search("Explorer") > -1)
       {
         if (document.forms[0].ErrorMessages.style.visibility = "hidden")
           document.forms[0].ErrorMessages.style.visibility = "visible";
       }
     }
   }
// }
}

/* ================================================================
FUNCTION:	setErrorFocus()
INPUT:		none
RETURNS:	nothing
DESC:		This function gets the value of the control in error 	
		from the list box and set the curson and focus 
		back on the field
================================================================ */
function setErrorFocus()
{
var errors = document.forms[0].ErrorMessages;
var ctlName;
var i;
var frm = document.forms[0];

for(i=0;i<errors.options.length;i++)
  if(errors.options[i].selected)
    {
    ctlName = errors.options[i].value;     
    break;
    }

if(ctlName!=" ")
  {
  for(i=0;i<frm.elements.length;i++)
    if(frm.elements[i].name == ctlName)
      { 
      frm.elements[i].focus();
//      frm.elements[i].blur();
      frm.elements[i].select();
      break;
      }
  }
}

/* =================================================================
FUNCTION	ValidDigits(value)
INPUT:		value that needs to be checked
RETURNS:	true or false
DESC:		checks if the value contains only numbers
=================================================================*/
function ValidDigits(val)
{
var ch="";
var i=0;
var valid = true;
 
  for(i=0; i < val.length; i++)
   {
    ch = val.charAt(i);
    if ((ch < "0" || ch > "9") && (ch != "." && ch != "$"))
      valid = false;
  }
  return valid;
}


