/////////////////////////////////////////////////////////////////////////////////
//                                                                             //
//       General Purpose Functions                                             //
//                                                                             //
//The client_library.js library is for generic client-side JavaScript functions//
//that can be used in any web application.  Functions specific to an individual//
//application should be in a library with a name such as appname_library.js.   //
//If you have written a function that you think should be added to             //
//client_library.js submit it to its-webapps for review.  Changes to existing  // 
//functions in client_library.js should be avoided.  If you have a suggested   // 
//change submit it to its-webapps for review.                                   //
/////////////////////////////////////////////////////////////////////////////////

/* =============================================================================
FUNCTION:	formatDate
 
INPUT:  	tempDate: javascript date object

RETURN: 	String in the format YYYY/MM/DD

DESC:		This function formats a date to a string in the format YYYY/MM/DD.
================================================================================= */

function formatDate(tempDate){
   if (tempDate == null || tempDate == "undefined" || tempDate == "")
     return tempDate

      var projDay = tempDate.getDate()
      var projMonth = tempDate.getMonth() + 1  // January = 0 in JavaScript
      var projYear = tempDate.getFullYear()

      if (projYear <= 99)
         projYear = "19" + projYear
      if (projMonth < 10)
         projMonth = "0" + projMonth
      if (projDay < 10)
         projDay = "0" + projDay

       var projectDate =  projYear + "/" + projMonth + "/" + projDay
       return projectDate
}

/* =====================================================================================
FUNCTION:	isEmpty
 
INPUTS:  	string
                
RETURN: 	boolean: true or false

DESC:		Checks whether a string has a length > 0 and is not blank spaces.
                Requires function isWhitespace()
======================================================================================= */
// general purpose function to see if an input value has been entered at all
function isEmpty(inputStr) {

        if (inputStr == null || inputStr.length == 0 || isWhitespace (inputStr)) {
                return true
        }
        return false
}


function isWhitespace(s){
   if (s.length == 0) return (false);

// whitespace characters
var whitespace = " ";

   var i;

    // Search through string's characters one by one
    // until we find a non-whitespace character.
    // When we do, return false; if we don't, return true.

    for (i = 0; i < s.length; i++){   
        // Check that current character isn't whitespace.
        var c = s.charAt(i);

        if (whitespace.indexOf(c) == -1) return false;
    }

    // All characters are whitespace.
    return true;
}



/* =============================================================================
FUNCTION:	IsEmailValid
 
INPUT:  	string

RETURN: 	BOOLEAN

DESC:		Checks string for valid e-mail format
================================================================================= */

function IsEmailValid(emailStr){

   var EmailOk  = true
   var AtSym    = emailStr.indexOf('@')
   var Period    = emailStr.lastIndexOf('.')
   var Space    = emailStr.indexOf(' ')
   var Length   = emailStr.length - 1   // Array is from 0 to length-1

   if ((AtSym < 1) ||                   // '@' cannot be in first position
       (Period <= AtSym+1) ||           // Must be atleast one valid char btwn '@' and '.'
       (Period == Length ) ||           // Must be atleast one valid char after '.'
       (Space  != -1)){                 // No empty spaces permitted
    
      EmailOk = false
   }
   return EmailOk
}


function isWebAddressValid(webStr){
    if (webStr.indexOf('http://') == -1 || webStr.indexOf('.') == -1)
        return (false);
    else
        return (true);
}

/* ======================================================================
FUNCTION:     readOnly
 
INPUT:        element

REQUIREMENTS: The form tag and the element tag MUST have a name attribute with 
              a value.

DESC:         This function ensures that an element will have the same 
              value when it is selected. For example, if a checkbox
              is selected, the value will not change, i.e. it will
              be readonly. Call this function from onChange or onClick handlers,
              whichever applies to your element.

Note:         Does not work in Internet Explorer. For IE use 'disabled'
              attribute in the element tag.

====================================================================== */

function readOnly(elem){
  var type = elem.type;
  //following code gets the parent element which would be an array in
  //case of radios, checkboxes, text boxes and textareas if more than one of
  //them is named the same.
  var elemToCheck = eval('document.' + elem.form.name + '.' + elem.name);

  if (type == 'checkbox' || type == 'radio'){
    if (elemToCheck[0] == undefined){
      elemToCheck.checked = elemToCheck.defaultChecked;
    } else {
      for (var i = 0; i < elemToCheck.length; i++){
        elemToCheck[i].checked = elemToCheck[i].defaultChecked;
      }
    }
  }
  
  if (type == 'password' || type == 'text' || type == 'textarea'){
    if (elemToCheck[0] == undefined){
      elemToCheck.value = elemToCheck.defaultValue;
    } else {
      for (var i = 0; i < elemToCheck.length; i++){
        elemToCheck[i].value = elemToCheck[i].defaultValue;
      }
    }
  }

  if (type == 'select-one' || type == 'select-multiple'){
    for (var k = 0; k < elemToCheck.options.length; k++) {
      elemToCheck.options[k].selected = elemToCheck.options[k].defaultSelected;
    }
  }
}

/* =========================================================================
FUNCTION:	isPosInteger
 
INPUT:  	inputStr: string

RETURN: 	Boolean: true or false

DESC:		Checks whether a string contains only numerical characters.
========================================================================== */

function isPosInteger(inputStr) {

   var oneChar = ""

   for (var i = 0; i < inputStr.length; i++) {
      oneChar = inputStr.charAt(i)
      if (oneChar < "0" || oneChar > "9") {
         return false
      }
   }
   return true
}


/* ======================================================================
FUNCTION:      isPosInt
 
INPUT:         inputStr, len

RETURN:        true or false

DESC:          This function checks to see whether the passed string has 
                  positive numbers for "len" positions.

====================================================================== */

function isPosInt(inputStr, len) {
   len = (!len ? inputStr.length : len)

   if (inputStr.length != len)
       return false;

   for (var i = 0; i < inputStr.length; i++) {
         var oneChar = inputStr.charAt(i)
         if (oneChar < "0" || oneChar > "9") {
               return false
         }
   }
   return true
}


/* ======================================================================
FUNCTION:  validDate
 
INPUT:     year, month, day

RETURN:    true, false 

DESC:      This function checks to see whether or not the date entered is
              valid
====================================================================== */

function validDate (year, month, day) {

  var daysOfMonth = new Object();
  daysOfMonth ['Jan'] = daysOfMonth ['January']   = daysOfMonth [1] = 31;
  daysOfMonth ['Feb'] = daysOfMonth ['February']  = daysOfMonth [2] = 28;
  daysOfMonth ['Mar'] = daysOfMonth ['March']     = daysOfMonth [3] = 31;
  daysOfMonth ['Apr'] = daysOfMonth ['April']     = daysOfMonth [4] = 30;
  daysOfMonth ['May'] = daysOfMonth ['May']       = daysOfMonth [5] = 31;
  daysOfMonth ['Jun'] = daysOfMonth ['June']      = daysOfMonth [6] = 30;
  daysOfMonth ['Jul'] = daysOfMonth ['July']      = daysOfMonth [7] = 31;
  daysOfMonth ['Aug'] = daysOfMonth ['August']    = daysOfMonth [8] = 31;
  daysOfMonth ['Sep'] = daysOfMonth ['September'] = daysOfMonth [9] = 30;
  daysOfMonth ['Oct'] = daysOfMonth ['October']   = daysOfMonth [10] = 31;
  daysOfMonth ['Nov'] = daysOfMonth ['November']  = daysOfMonth [11] = 30;
  daysOfMonth ['Dec'] = daysOfMonth ['December']  = daysOfMonth [12] = 31;

  if (year < 1850)  // adjust that for the limit you want to check
    return false;
  if (month < 1 || month > 12)
    return false;
  if (day < 1)
    return false;
  if (isLeapYear(year) && month==2)
    var dayLimit = 29;
  else
    var dayLimit = daysOfMonth[month];
  if (day > dayLimit)
    return false;
  return true;
}
function isLeapYear (y) {
  return (y % 4 == 0  && (y % 400 == 0 || y % 100 != 0))
}

/* ======================================================================
FUNCTION:      parseValidate
 
INPUT:         date string

RETURN:        true or false

DESC:          

====================================================================== */

function parseValidate (dateStr) {
  var date = dateStr.split('/');
  var year = parseInt (date[0], 10);
  var month = parseInt (date[1], 10);
  var day = parseInt (date[2], 10);

  if (validDate (year, month, day))
      return (true);
  else
      return (false);
}

/*========================================================================
FUNCTION:	mask
 
INPUTS:  	inString : string
                mask     : string
                
RETURN: 	boolean: true or false

DESC:		Compare the input string to the mask
                If the string matches the mask the funtion returns true
                if not, it returns false.
                Requires isNumber(), isAlphabeticChar(), isNumOrChar, isUpperCaseChar()
========================================================================= */

function mask (inString, mask)  {

   lenStr = inString.length;
   lenMsk = mask.length;

   if ((lenStr==0) || (lenMsk==0))
      return false;

   if (lenStr!=lenMsk)
      return false;

   for (count=0; count<=inString.length; count++) {
      strChar = inString.substring(count, count+1);
      mskChar = mask.substring(count, count+1);
      if (mskChar=='#') {
         if(!isNumberChar(strChar))
            return false;
      }else 
         if (mskChar=='?') {
            if(!isAlphabeticChar(strChar))
               return false;
         }else 
            if (mskChar=='!') {
               if(!isNumOrChar(strChar))
                  return false;
            }else 
               if (mskChar=='*') {
                 if(!isUpperCaseChar(strChar))
                   return false;
               }else{
                  if (mskChar!=strChar) 
                     return false;
               }
   }
   return true;
}

/*========================================================================
FUNCTION:	isNumberChar
 
INPUTS:  	inChar : string of length 1
                
RETURN: 	boolean: true or false

DESC:		Checks whether an input character is a number.
                If the character is a number the funtion returns true
                if not, it returns false.
========================================================================= */

function isNumberChar(inChar)  {

var refString="1234567890";

   if(inChar.length != 1) 
      return false;

   if (refString.indexOf(inChar, 0)==-1) 
      return false;

   return true;
}

/*========================================================================
FUNCTION:	isAlphabeticChar
 
INPUTS:  	inChar : string of length 1
                
RETURN: 	boolean: true or false

DESC:		Checks whether an input character is alphabetic. 
                If the character is alphabetic, the funtion returns true.
                If not, it returns false.
========================================================================= */

function isAlphabeticChar (inChar) {

   var refString="abcdefghijklmnopqrstuvwxyz";

   if(inChar.length!=1) 
      return false;
        
   inChar=inChar.toLowerCase();
        
   if (refString.indexOf (inChar.toLowerCase(), 0)==-1) 
      return false;

   return true;
}

/*========================================================================
FUNCTION:	isUpperCaseChar
 
INPUTS:  	inChar : string of length 1
                
RETURN: 	boolean: true or false

DESC:		Checks whether an input character is alphabetic and upper case. 
                If the character is alphabetic and uppercase, the funtion returns true.
                If not, it returns false.
========================================================================= */

function isUpperCaseChar (inChar) {

   var refString="ABCDEFGHIJKLMNOPQRSTUVWXYZ";

   if(inChar.length!=1) 
      return false;
        
   if (refString.indexOf (inChar, 0)==-1) 
      return false;

   return true;
}

/*========================================================================
FUNCTION:	isNumOrChar
 
INPUTS:  	inChar : string of length 1
                
RETURN: 	boolean: true or false

DESC:		Checks whether an input character is alphanumeric.
                If the character is alphanumeric, the funtion returns true.
                If not, it returns false.
========================================================================= */

function isNumOrChar (inChar) {

   var refString="1234567890abcdefghijklmnopqrstuvwxyz";

   if(inChar.length!=1) 
      return false;

   inChar=inChar.toLowerCase();
        
   if (refString.indexOf (inChar, 0)==-1)  
      return false;

   return true;
}

/* ======================================================================
FUNCTION:      trimSpaces
 
INPUT:         String and direction (l for left, r for right);

RETURN:        String without spacess

DESC:          Takes the spacess out in either direction
====================================================================== */

function trimSpaces(str, d) {
	var resultStr = "";
	var i = 0;

	// Return immediately if an invalid value was passed in
	if (typeof(str) == typeof(void(0)) || str == null)	
		return null;

	// Make sure the argument is a string
	str += "";
	
	if (str.length == 0) 
		resultStr = "";
	else {
       if (d == 'r'){
      		// Loop through string starting at the end as long as there
       		// are spaces.
      		i = str.length - 1;
      		while ((i >= 0) && (str.charAt(i) == " "))
   			i--;
 			
      		// When the loop is done, we're sitting at the last non-space char,
      		// so return that char plus all previous chars of the string.
       		resultStr = str.substring(0, i + 1);
       }
       else{
      		// Loop through string starting at the begining as long as there
       		// are spaces.
      		i = 0;
      		while ((i < str.length) && (str.charAt(i) == " "))
   			i++;
 			
      		// When the loop is done, we're sitting at the first non-space char,
      		// so return that char plus all next chars of the string.
       		resultStr = str.substring(i, str.length);
       }
  	}
  	
  	return resultStr;  	
} // end TrimRight


/* ======================================================================
FUNCTION:      isFormDataChanged
 
INPUT:         frm - reference to the form that is to be checked

RETURN:        boolean

DESC:          Checks through all the visible form input element and determines
               if the value has changed since the page has been loaded. If at
               least one of the values has changed the function returns true,
               Otherwise it returns false.
====================================================================== */

function isFormDataChanged(frm) {

  var result = false;

  for (var i=0; i < frm.elements.length; i++) {

    myType = frm.elements[i].type;

    if (myType == 'checkbox' || myType == 'radio') {
      if (frm.elements[i].checked != frm.elements[i].defaultChecked) {
        result = true
      }
    }

    if (myType == 'password' || myType == 'text' || myType == 'textarea') {
      if (frm.elements[i].value != frm.elements[i].defaultValue) {
        result = true
      }
    }

    if (myType == 'select-one' || myType == 'select-multiple') {
      for (var k=0; k < frm.elements[i].options.length; k++) {
        if (myType == 'select-one' && isEmpty(frm.elements[i].options[k].value)){
          continue; //skip checking of options with empty values
        } else if (frm.elements[i].options[k].selected != frm.elements[i].options[k].defaultSelected) {
          result = true
        }
      }
    }

  }

  return result;

}//isFormDataChanged


/* ======================================================================
FUNCTION:      openHelp
 
INPUT:         url - URI or the complete URL
               name - the name you want to assign to this window

DESC:          opens a new window in the top right corner of the screen.
====================================================================== */
function openHelp(relativePage, name){
  XOffset = (screen.availWidth - 400)/2;
  YOffset = (screen.availHeight - 400)/2;
  var win = window.open(relativePage, name, "resizable=1,status=1," + 
            "scrollbars=1,screenX=" + XOffset + ",screenY=" + YOffset + 
            ",top=" + YOffset + ",left=" + XOffset + ",toolbar=0,menubar=0," + 
            "width=400,height=400");
  win.focus();
}

/* ======================================================================
FUNCTION:      openWindow
 
INPUT:         url - URI or the complete URL
               name - the name you want to assign to this window
               props - properties of the new window

DESC:          This is basically a wrapper class to get around the problem
               of "[object window]" appearing in the opener window.
====================================================================== */
function openWindow(url, name, props){
  var win = window.open(url, name, props);
  win.opener = self;
}


/* ======================================================================
FUNCTION:      closeClient
 
DESC:          Checks to see if there was an opener for the calling window
               and if there was and it's not closed, then it sets the focus
               to that opener and closes the calling window's top window.
               If the opener is closed or there wasn't an opener, then it
               simply closes the calling window's top window. You would probably
               use this function in apps that are running in pop-up windows
               or pop-up frames.
====================================================================== */
function closeClient(){
  if (top.opener && !top.opener.closed){
    top.opener.focus();
  }
  top.close();
}

function subtractSecondBoxFromFirstBox (box1, box2){
  for(i=0; i<box1.length; i++){
    for(j=0; j<box2.length; j++){
      if(box2.options[j].value == box1.options[i].value){ 
        //&& box2.options[j].text == box1.options[i].text ){
        box1.options[i].value = "";
        box1.options[i].text = "";
        break;
      }
    }
  }
 sortSelectBox(box1);

}

function addSecondBoxToFirstBox (box1, box2){
  var initialBox1Length = box1.length;
//alert("=" + );
  box1.length += box2.length;
  for(i=0; i<box2.length; i++){ 
    box1.options[i + initialBox1Length].value = box2.options[i].value;
    box1.options[i + initialBox1Length].text = box2.options[i].text;
  }
  sortSelectBox(box1);

}

function emptyBox(box){
  //empty box
  for(i=0; i<box.length; i++){
   box.options[i].value = "";
   box.options[i].text = ""; 
  }
  box.length = 0;
}

function isBoxEmpty(box){
  for(i=0; i<box.length; i++){
   if( !isEmpty(box.options[i].value)){ //|| !isEmpty(box.options[i].text)
     return false;
   } 
  }
  return true;
}

/* ======================================================================
FUNCTION:      addItemToLastSelectBox
DESC:          Adds the item selected in box1 to box2. After that it 
               it deletes the selected item from box1. The sum of the items in
               the two boxes stays always the same.
====================================================================== */
function addItemToLastSelectBox( box1, box2){
  addToLastSelectBox(box1, box2);
//alert("Before remove from last select box");
  removeFromLastSelectBox(box2, box1);
  box1.selectedIndex = -1;
  box2.selectedIndex = -1;
  return;
}

function addToLastSelectBox(availableItems, selectedItems) {
 
  var selectedItem = availableItems.options[availableItems.selectedIndex].value;
  if(isEmpty(selectedItem)){
    return;
  }

  for(i=0; i<selectedItems.length; i++){
   if(selectedItem == selectedItems.options[i].value){
     return;      
    }
  }
     
  selectedItems.length += 1;
  var len = selectedItems.length;

  selectedItems.options[len-1].value = selectedItem;
  selectedItems.options[len-1].text = availableItems.options[availableItems.selectedIndex].text;
//for(i=0; i<selectedItems.length; i++){
   //alert("Before sort: i=" + i + " id=" + selectedItems.options[i].value + " text=" + selectedItems.options[i].text); 
//  }
  sortSelectBox(selectedItems);
//for(i=0; i<selectedItems.length; i++){
  // alert("After sort: i=" + i + " id=" + selectedItems.options[i].value + " text=" + selectedItems.options[i].text); 
//}
  return;  
}

/* ======================================================================
FUNCTION:      removeItemFromLastSelectBox
DESC:          Removes the selected item from box2, but before doing that
               it adds it to box1. The sum of the two boxes remains always the same.
====================================================================== */
function removeItemFromLastSelectBox( box1, box2){
  addToLastSelectBox(box2, box1);
  removeFromLastSelectBox(box1, box2);
  box1.selectedIndex = -1;
  box2.selectedIndex = -1;
  return;
}

function removeFromLastSelectBox(availableItems, selectedItems){//selectedItems, availableItems
//alert ("In removeFromLastSelectBox()");
//alert("selectedItems.options[selectedItems.selectedIndex].value= " + selectedItems.options[selectedItems.selectedIndex].text);
  selectedItems.options[selectedItems.selectedIndex].value="";
  selectedItems.options[selectedItems.selectedIndex].text="";
  selectedItems.options[selectedItems.selectedIndex].selected = false;
  sortSelectBox(selectedItems);
  
  return;  

}

/* ======================================================================
FUNCTION:      reduceAndSort()
DESC:          If the last element to be added to the select box is
               already in the list, then is not added. Otherwise it is added and
               finally the select box is sorted in ascending order
====================================================================== */
function reduceAndSort(selectBox){
var len = selectBox.length;
for(i=0; i<len-1; i++){
      if(selectBox.options[i].value == selectBox.options[len-1].value){
        selectBox.options[len-1].value = "";
        selectBox.options[len-1].text = "";
        len = len -1;
        selectBox.length = len;
        break; 
      }
  }
  sortSelectBox(selectBox);

  return;
}


/* ======================================================================
FUNCTION:      sortSelectBox()
DESC:          Eliminates empty value items from the selectBox. The remaining 
               items are sorted alphabetically in ascending order.
====================================================================== */
function sortSelectBox(selectBox){
  var sortArray = new Array(selectBox.length);
  var length = 0;
//alert("selectBox.length=" + selectBox.length);
  for(i=0; i<selectBox.length; i++){
    if(!isEmpty(selectBox.options[i].value)){
     sortArray[length++] = selectBox.options[i].text + "^" + selectBox.options[i].value; 
    }
  }  
  
  sortArray.length = length;
  sortArray.sort();

  selectBox.length = length;

  for(i=0; i<length; i++){
    var ind = sortArray[i].indexOf('^');  
    selectBox.options[i].text = sortArray[i].substring(0,ind);
    selectBox.options[i].value = sortArray[i].substring(ind+1);
  }
}

/* ======================================================================
FUNCTION:      deleteDate()
DESC:          Deletes an individual date from the adiacent selectbox.
====================================================================== */
function deleteDate(selectBox){
  selectBox.options[selectBox.selectedIndex].value="";
  selectBox.options[selectBox.selectedIndex].text="";
selectBox.options[selectBox.selectedIndex].selected = false;
  sortSelectBox(selectBox);
  if(selectBox.length > 0){
    selectBox.length += 1;
    selectBox.options[selectBox.length-1].value = "";
    selectBox.options[selectBox.length-1].text = "";
    selectBox.options[selectBox.length-1].selected = true;
  }
 
  return;
}

/* ======================================================================
FUNCTION:      goTo
DESC:          Changes the form action attribute to 'url' and submits the form.
====================================================================== */
function goTo(frm, url){
  with(frm){
   action=url;
   target="_self";
   submit();
  }
}

/* ======================================================================
FUNCTION:      logout
DESC:          Warns the user before logging out.
====================================================================== */
function logout(){
  if (confirm("Are you sure you want to quit this application?")) {
      document.forms[0].submit();
   }
}

/* ======================================================================
FUNCTION:      openPopupWindow
DESC:          Opens a new window with a certain name, size (and other parameters).
               It is more useful for getting popups from links (as opposed to buttons, 
               where the "window.open()" function works properly).
               The content will be given by the parameter URL.
====================================================================== */
function openPopupWindow(frm, URL, windowName, parameters){
  newWin = window.open("", windowName, parameters);
  newWin.focus();
  frm.action = URL;
  frm.target = windowName;
  frm.submit();
}

function addPrefix(phone){
    if(isEmpty(phone.value)){
      phone.value = "(403)";
      phone.select();
      phone.focus();
      return;
    }
  }

function isMoreThanXXXDays(frm, XXXDays){
  //  startDate = 2 0 0 3 / 0 9 / 1 8
  //  index:      0 1 2 3 4 5 6 7 8 9
  var startDate = frm.startDate.value;
  var endDate = frm.endDate.value;

  if(isEmpty(startDate) || isEmpty(endDate) ) return;

  year = startDate.substring(0,4);
  yearInt = parseInt(year) + 100;
  month =startDate.substring(5,7);
  day = startDate.substring(8,10);
  var fromSum =Date.UTC(y2k(year),month-1,day,0,0,0);

  year = endDate.substring(0,4);
  yearInt = parseInt(year) + 100;
  month =endDate.substring(5,7);
  day = endDate.substring(8,10);
  var toSum =Date.UTC(y2k(year),month-1,day,0,0,0);

  var XXXSum = XXXDays*24*60*60*1000;

  if(toSum - fromSum > XXXSum){
    return true;
  }else{
    return false;
  }
}

function y2k(number) { return (number < 1000) ? number + 1900 : number; }


