// lib_core.js - Main library of common javascript code and "global" variables

/*** Global Variable Declarations ***/
  /* KEY:
   * WR: Writable - You can specify custom values for these.
   * RO: Read Only - Do NOT attempt to set these directly!
   */

  // General Variables
  var mainImagePath = "";            // (WR) What directory holds all website images?
  var diagIsDisplayed = false;       // (RO) Is the F12 diagnostic display active?
  var holidays = new Array();        // (WR) List of business holidays, for date/time functions.
  // Clickgrab Variables
  var watchFormForChanges = "";      // (WR) What form should be monitored for changes? (blank = all forms)
  var msgBoxText;                    // (WR) Text that should appear when the user clicks an "unsafe" link
  var inProductAdvisor = false;      // (WR) Set to true if page is part of the PA flow
  var inLoanAction = false;          // (WR) Set to true if page is part of the import process
  var clickAttempted;                // (RO) Has a click been attempted while catchClicks is active?
  var lastCaughtEvent;               // (RO) Handle to last captured click event
  var trapLinks = false;             // (RO) Used by menu system to determine if catchClicks is in use
  var pendingLink = "";              // (RO) Used by menu system to determine what links should be followed
  // Form Validation Variables
  var dialogActive = false;          // (RO) Is there currently a custom dialog box open?
  var pendingErrorsShown = false;    // (RO) Have pending errors been shown yet?
  var pendingInfoShown = false;      // (RO) Has pendgin info been shown yet?
  var pendingAlertsShown = false;    // (RO) Have pending alerts been shown yet?
  var submitAttempted = false;       // (RO) Has there been a form submission attempted?
  // Keygrab Variables
  var enterAttempted;                // (RO) Has the enter key been used to submit a page?
  // Context Help Variables
  var progInd = true;                // (RW) Should the progress indicator be used when using blank.html?
  var helpInUse = false;             // (RO) This should be controlled only by lib_help.js
  // Login/Logout Variables
  var AutoLogoutAction = "";         // (WR) Landing page after logout
  var CurrentPage = "";              // (WR) URL-ready name of the page currently in use
  var LogoutPage = "";               // (WR) Which page should be used as the logout page?
  var HitID = "";                    // (WR) Current web hit value
  var SessionID = "";                // (WR) Current session ID value
  var StateInfo = "";                // (WR) Current state info value (SessionID + HitID, pre-formatted)
  var sessionCheckInterval = 300000; // (WR) Time between activity checks (default: 5 minutes)
  // Popup Detector Variables (override before calling openPopup() to change behavior)
  var pageTarget = "";               // (WR) Used by newURL parameter in openPopup(), and the new window
  var pageText = "Please wait...";   // (WR) Text to be displayed while the popup page loads in blank.html
  var popupMessage = "";             // (WR) Error message for popup detector
  var progInd = true;                // (WR) Should the progress indicator be used during loading?
  var newWin;                        // (RO) Handle to the new popup window
  // Popup Window Handles (these are for popup windows that are used commonly)
  var winReprice = null;             // (WR) Handle to the Reprice window (normally for update_pricing.html)
  var SummaryWin = null;             // (WR) Handle to the PA Summary window (normally for pa_summary.html)
  var winTest = null;                // (WR) Handle to the Popup-Tester window (normally for zz-popwindow.html)
  var popWin = null;                 // (WR) Handle to the Delete TBD window (normally for delete_tbd.html)
/*** end global variables ***/


/*** String manipulation functions (common to most libraries) ***/
  // ltrim(string) : Returns a copy of a string without leading spaces.
  function ltrim(str) {
    str = str.replace(/^\s+/g, "");
    return str;
  }

  // rtrim(string) : Returns a copy of a string without trailing spaces.
  function rtrim(str) {
    str = str.replace(/\s+$/g, "");
    return str;
  }

  // trim(string) : Returns a copy of a string without leading or trailing spaces.
  function trim(str) {
    // do a left trim first
    str = ltrim(str);
    // then do a right trim
    str = rtrim(str);
    return str;
  }

  // doTrim(thisElement) : Reassigns a trimmed string back to the form element.
  function doTrim(thisElement) {
    if (thisElement && thisElement.type != "file") {
      thisElement.value = trim(thisElement.value);
    }
  }

  // removeLinks(thisString) : Remove HREF tags from a link, and return only the inner text.
  function removeLinks(thisString) {
    str = thisString.replace(/<a.+>(.+)<\/a>/gi, "$1");
    return str;
  }

  // removeScripts(thisString) : Remove all SCRIPT tags and their contents.
  function removeScripts(thisString) {
    str = thisString.replace(/((<[\s\/]*script\b[^>]*>)([^>]*)(<\/script>))/gi, "");
    return str;
  }

  // removeComments(thisString) : Remove all COMMENT (<!-- -->) tags and their contents.
  function removeComments(thisString) {
    str = thisString.replace(/<\!--(.+)-->/g, "");
    return str;
  }

  // removeWhitespace(thisString) : Remove all excess whitespace (replace with single space).
  function removeWhitespace(thisString) {
    str = thisString.replace(/\r+/g, " ");
    str = thisString.replace(/\n+/g, " ");
    str = thisString.replace(/\s+/g, " ");
    return str;
  }

  // fixNumber(obj) : Strips commas and non-numeric values, returns float value
  function fixNumber(obj) {
    val = obj.value;
    if (val=='') return '';
    return parseFloat(val.split(',').join(''));
  }

  // regexCheck(string,pattern) : Returns whether a given string matches the given pattern.
  function regexCheck(teststring,pattern) {
    var returnVar = true;
    if (teststring != null && teststring != undefined && !pattern.test(teststring)) {
      returnVar = false;
    }
    return returnVar;
  }

  // trimCommas(myString) : Commonly used to clean up a comma-delimited list.
  function trimCommas(myString) {
    // Remove leading commas
    myString = myString.replace(/^\,+/g, "");
    // Remove trailing commas
    myString = myString.replace(/\,+$/g, "");
    return myString;
  }
  
  // stripCharsInBag(myString,pattern) : Strips characters that matches the given pattern and returns the string.
   function stripCharsInBag(myString,pattern){ 
    var i;
    var returnString = ""; 
    for (i = 0; i < myString.length; i++) {
       var c = myString.charAt(i);
       if (pattern.indexOf(c) == -1) returnString += c;
    }
    return returnString;
  }
/*** end of string manipulation functions ***/


/*** Cookie manipulation functions (includes supporting functions) ***/
  // Array.indexOf( value, begin, strict ) - Return index of the first element that matches value
  if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(v,b,s) {
      for( var i = +b || 0, l = this.length; i < l; i++ ) {
        if( this[i]===v || s && this[i]==v ) { return i; }
      }
      return -1;
    }
  }

  // Array.unique( strict ) - Remove duplicate values
  if (!Array.prototype.unique) {
    Array.prototype.unique = function(b) {
      var a = [], i, l = this.length;
      for( i=0; i<l; i++ ) {
        if( a.indexOf( this[i], 0, b ) < 0 ) { a.push( this[i] ); }
      }
      return a;
    }
  }

  // Simple function for setting a cookie
  function createCookie(cookieName, cookieValue, expDays) {
  	var path = "/";
  	var newdate = new Date();
  	newdate.setTime(newdate.getTime()+(1000*60*60*24*expDays));
  	var expires = newdate.toGMTString();
  	document.cookie = cookieName + "=" + cookieValue + "; expires=" + expires + "; path=" + path + ";";
  }

  // Delete a cookie by setting an expired cookie by the same name
  function deleteCookie(cookieName) {
    createCookie(cookieName,"",-1);
  }

  // Read all the values from a given cookie, by name
  function readCookie(cookieName) {
    var nameEQ = cookieName + "=";
    var cookieArray = document.cookie.split(";");
    for(var i=0;i < cookieArray.length;i++) {
      var thisCookie = trim(cookieArray[i]);
      if (thisCookie.indexOf(nameEQ) == 0) {
        return thisCookie.substring(nameEQ.length,thisCookie.length);
      }
    }
    return null;
  }
/*** end of cookie manipulation functions ***/


/*** Object manipulation functions (easy access to some form field data) ***/
  // Dynamically add a list of values to a select field
  function addSelectOption(whatValue,whatName,whatField,defaultSelect) {
  	var lastElement = whatField.length;
  	if (whatValue == defaultSelect) {
  	  eval( "whatField.options[lastElement] = new Option(whatName,whatValue,true,true);" );
  	  whatField.selectedIndex = lastElement;
  	} else {
      eval( "whatField.options[lastElement] = new Option(whatName,whatValue);" );
    }
  }

  // Add a value to a selection list
  function addValue(whatField) {
  	var lastElement = document.forms['MTForm'][whatField].options.length;
  	var newVal = prompt("Enter a new " + whatField + " value.", "");
  	if (newVal != "" && newVal != null) {
  	  eval( "document.forms['MTForm']." + whatField + ".options[lastElement] = " + "new Option('" + newVal + "','" + newVal + "')");
  	  document.forms['MTForm'][whatField].selectedIndex = lastElement;
    }
  }

  // Get value of the selected radio button (returns empty if nothing selected)
  function getSelectedRadioValue(radioObj) {
  	if(!radioObj) { return ""; }
  	var radioLength = radioObj.length;
  	if(radioLength == undefined) {
  		if(radioObj.checked) {
  			return radioObj.value;
  		} else {
  			return "";
  	  }
  	}
  	for(var i = 0; i < radioLength; i++) {
  		if(radioObj[i].checked) {
  			return radioObj[i].value;
  		}
  	}
  	return "";
  }

  // Get all available fields in a form, returns an array
  function getFormFields(myForm) {
    var thisID;
    var thisType;
    var fieldArray = new Array();
    if (myForm) {
      for (var i=0; i<myForm.length; i++) {
        with (myForm.elements[i]) {
          thisID = getAttribute('id');
    	    thisType = getAttribute('type');
    	    if (!regexCheck(thisType,/^(hidden|button)$/)) {
    	      // Only return visible/editable fields, not buttons or hidden values
    	      fieldArray.push(thisID);
    	    }
        }
      }
    }
    return fieldArray;
  }

  // Get all available forms on the page
  function getForms() {
    var formList = document.getElementsByTagName("form"); // Gather all possible formss.
    return formList;
  }

  // Easy dropdown-combo population system
  function populateCombo(destElement,selectedParent) {
    if (selectedParent != "") {
    	selectedParent = selectedParent.replace(/-/g, "_");
    	var selectedArray = eval( "Array_" + selectedParent );
    	while (selectedArray.length < destElement.options.length) {
    	    destElement.options[(destElement.options.length - 1)] = null;
    	}
    	for ( var i=0; i < selectedArray.length; i++ ) {
    	    eval( "destElement.options[i] = " + "new Option" + selectedArray[i] );
    	}
    	if ((destElement.options.length - 1) == 1) {
    	    destElement.selectedIndex = 1;
    	}
    }
  }
  function updateForm() {
    // Outdated, but used function--remove whenever possible.
    return true;
  }
/*** end object manipulation ***/


/*** Location functions (find mouse/field position on-screen) ***/
  // Form field geometry detection functions (finds position of an object on the screen)
  function findPosX(obj) {
    var curleft = 0;
    if (obj.offsetParent) {
      while (obj.offsetParent) {
        curleft += obj.offsetLeft;
        obj = obj.offsetParent;
      }
    } else if (obj.x) {
      curleft += obj.x;
    }
    return curleft;
  }
  function findPosY(obj) {
    var curtop = 0;
    if (obj.offsetParent) {
      while (obj.offsetParent) {
        curtop += obj.offsetTop;
        obj = obj.offsetParent;
      }
    } else if (obj.y) {
      curtop += obj.y;
    }
    return curtop;
  }

  // Set the browser to run captureMousePosition whenever the mouse is moved
  document.onmousemove = captureMousePosition;

  // Global variables
  var xMousePos = 0; // Horizontal position of the mouse on the screen
  var yMousePos = 0; // Vertical position of the mouse on the screen
  var xMousePosMax = 0; // Width of the page
  var yMousePosMax = 0; // Height of the page
  var winMaxWidth = screen.width;
  var winMaxHeight = screen.height;

  function captureMousePosition(evt) {
    // When the page scrolls in Netscape, the event's mouse position
    // reflects the absolute position on the screen. innerHight/Width
    // is the position from the top/left of the screen that the user is
    // looking at. pageX/YOffset is the amount that the user has
    // scrolled into the page. So the values will be in relation to
    // each other as the total offsets into the page, no matter if
    // the user has scrolled or not.

    // When the page scrolls in IE, the event's mouse position
    // reflects the position from the top/left of the screen the
    // user is looking at. scrollLeft/Top is the amount the user
    // has scrolled into the page. clientWidth/Height is the height/
    // width of the current page the user is looking at. So, to be
    // consistent with Netscape (above), add the scroll offsets to
    // both so we end up with an absolute value on the page, no
    // matter if the user has scrolled or not.

    if (evt) {
      xMousePos = evt.pageX;
      yMousePos = evt.pageY;
      xMousePosMax = window.innerWidth + window.pageXOffset;
      yMousePosMax = window.innerHeight + window.pageYOffset;
    } else {
      xMousePos = window.event.x + document.body.scrollLeft;
      yMousePos = window.event.y + document.body.scrollTop;
      xMousePosMax = document.body.clientWidth + document.body.scrollLeft;
      yMousePosMax = document.body.clientHeight + document.body.scrollTop;
    }

    // Comment out the line below to HIDE the coords in the status bar.
    // window.status = "xMousePos=" + xMousePos + ", yMousePos=" + yMousePos + ", xMousePosMax=" + xMousePosMax + ", yMousePosMax=" + yMousePosMax + ", Width=" + screen.width + ", Height=" + screen.height;
  }
/*** end location functions ***/


/*** Element Manipulations Functions ***/
  // Returns a handle to an HTML element, either by ID or by Name.
  function getHdl(elementID) {
    var tmpHandle = null;
    if (document.getElementById(elementID)) {
      tmpHandle = document.getElementById(elementID);
    } else if (document.getElementsByName(elementID)) {
      tmpHandle = document.getElementsByName(elementID);
    }
    if (tmpHandle.length == 0) { tmpHandle = null; }
    return tmpHandle;
  }

  // Allow easy access to properties of an HTML element, and perform certain actions using a single call.
  function initElement(elementID) {
    this.handle = getHdl(elementID); // Handle to the element, within this object.

    this.hidden = function() {
      if (this.handle) { this.handle.style.visibility = "hidden"; }
    } // this.makeHidden()

    this.visible = function() {
      if (this.handle) { this.handle.style.visibility = "visible"; }
    } // this.makeVisible()

    this.collapse = function() {
      if (this.handle) { this.handle.style.display = "none"; }
    } // this.collapse()

    this.expand = function() {
      if (this.handle) { this.handle.style.display = "block"; }
    } // this.expand()

    this.inline = function() {
      if (this.handle) { this.handle.style.display = "inline"; }
    } // this.inline()
  } // initElement

  function closeDivs(whatPrefix) {
    var divList = document.getElementsByTagName("div"); // Gather all possible div's.
    var thisDiv;
    var divID;
    for(i=0;i<divList.length;i++) {
      thisDiv = divList[i]; // Get a simple handle to the div.
      divID = thisDiv.getAttribute('id'); // Check if the DIV has an ID attribute.
      if (divID && regexCheck(divID,whatPrefix)) {
        thisDiv.style.display = "none";
      }
    }
  }
/*** end element manipulations ***/


/*** Date/Time Functions ***/
  // Holiday/Business Day Logic
  function isHoliday(myDate) {
    if (!(myDate instanceof Date)) { return false; }
    var strDate = convertDateToProgressString(myDate);
    for (var i = 0; i < holidays.length; i++) {
      if (holidays[i] == strDate) { return true; }
    }
    return false;
  }

  // Holiday/Business Day Logic
  function isBusinessDay(myDate) {
    if (!(myDate instanceof Date)) { return false; }
    if (myDate.getDay() != 0 && myDate.getDay() != 6 && !isHoliday(myDate)) {
      return true;
    } else {
      return false;
    }
  }

  // Work with Progress Date String Formats Logic
  function convertProgressStringToDate(myDateString) {
    var strMonth = "";
    var strDay   = "";
    var strYear  = "";
    var firstIdx = 0;
    var lastIdx  = 0;
    var intYear  = 0;

    if (myDateString == "" || myDateString == "mm/dd/yyyy") { return undefined; }

    // Verify Valid Date string received
    firstIdx = myDateString.indexOf("/");
    lastIdx  = myDateString.lastIndexOf("/");
    if (firstIdx == -1 || lastIdx == -1 || firstIdx == lastIdx) { return undefined; }

    // Verify Month, Day and Year are numeric
    strMonth = myDateString.substring(0,firstIdx);
    strDay   = myDateString.substring(firstIdx + 1,lastIdx);
    strYear  = myDateString.substr(lastIdx + 1);
    if (isNaN(strMonth) || isNaN(strDay) || isNaN(strYear)) { return undefined; }

    // Account for 2 digit year
    intYear = Number(strYear);
    if (intYear < 1000) { intYear+=2000; }

    // Return Date Object, JS Months 0 - 11
    return new Date(intYear,Number(strMonth) - 1,Number(strDay));
  }

  // Work with Progress Date String Formats Logic
  function convertDateToProgressString(myDate) {
    // Return if not Date
    if (!(myDate instanceof Date)) { return "mm/dd/yyyy"; }

    // JS Months 0 - 11
    var strMonth = String(myDate.getMonth() + 1);
    var strDay   = String(myDate.getDate());
    if (strMonth.length < 2) { strMonth = "0" + strMonth; }
    if (strDay.length < 2) { strDay = "0" + strDay; }
    return strMonth + "/" + strDay + "/" + String(myDate.getFullYear());
  }
/*** end date/time manipulations ***/


/*** Special Functions ***/
  // Stop all processing in the browser
  function stopProcessing(evt) {
    try { evt.stopPropagation(); } catch (e) { /* Die quietly if not supported. */ }
    try { evt.preventDefault(); } catch (e) { /* Die quietly if not supported. */ }
    try { event.cancelBubble = true; } catch (e) { /* Die quietly if not supported. */ }
    try { event.returnValue = false; } catch (e) { /* Die quietly if not supported. */ }
    return false;
  }

  // Hide any messages in the status bar
  function hideStatus() {
    window.status = "";
    return true;
  }

  // Stop processing during an onsubmit (event handle is passed)
  function handleSubmit(evt) {
    stopProcessing(evt);
  }

  // Default stub for function, to prevent errors on pages that do not use it
  function goSubmit() {
    submitAttempted = true;
    return false;
  }

  // Stub function to forward TRUE print requests to the actual print function, doPrint()
  function goPrint(whatAction) {
    if (whatAction == "print") {
      doPrint(); // Only print if the function was specifically called with that action.
    }
  }

  // Display a message to the user before printing documents (showLandscapeHint can be overridden)
  var showLandscapeHint = false;
  function doPrint() {
    if (showLandscapeHint) {
      alert("For the best results, change your print layout/orientation to 'landscape' mode.");
    }
    window.print();
  }

  // Toggle the F12 diagnostic on/off
  function toggleDiagnostics(whatAction) {
    var diagObj = document.getElementById("diagnostics");
    if (!diagObj) { return false; }
    if (diagIsDisplayed == true || whatAction == "hide") {
      diagObj.style.display = "none";
      diagIsDisplayed = false;
    } else {
      diagObj.style.display = "inline";
      diagIsDisplayed = true;
    }
    return true;
  }
/*** end special functions ***/


/*** googlefix - fixes odd field colors resulting from google toolbar install ***/
  if (window.attachEvent) { window.attachEvent("onload",restoreStyles); }

  function restoreStyles() {
    var inputList = document.getElementsByTagName("input");
    for(i=0;i<inputList.length;i++) {
      if (inputList[i].style.backgroundColor == "#FFFF0A") {
        inputList[i].style.backgroundColor = "";
      }
    }
    var selectList = document.getElementsByTagName("select");
    for(i=0;i<selectList.length;i++) {
      if (selectList[i].style.backgroundColor == "#FFFF0A") {
        selectList[i].style.backgroundColor = "";
      }
    }
  }
/*** end googlefix ***/

// Set a global flag that indicates this library has been loaded by the browser.
var LIB_CORE_LOADED = true;

// End library