function DateDiff(earlyDate,laterDate) {
   // returns number of days between two date objects
   var earlySecs=earlyDate.getTime();
   var laterSecs=laterDate.getTime();
   return Math.floor ((((((laterSecs-earlySecs)/1000)/60)/60)/24));
}

// attributes
function GetAttribute(ctl, vsAttr, voDefault) {
   if ((ctl != null) && (ctl.attributes[vsAttr])) {
      return ctl.attributes[vsAttr].value;
   }
   return voDefault;
}

// style/class management
function RemoveClassName(ctl, vsName) {
   if (ctl.className == null) return;

   // Remove the given class name from the element's className property.
   var aNewList = new Array();
   var aCurList = ctl.className.split(" ");

   for (var i = 0; i < aCurList.length; i++) {
      if (aCurList[i] != vsName) aNewList.push(aCurList[i]);
   }

   ctl.className = aNewList.join(" ");
}

// QueryString management
function AppendQueryString(vsUrl, vsQueryString) {
   if ((vsQueryString == null) || (vsQueryString == '')) return vsUrl;

   var n = vsQueryString.indexOf('=');
   if (n < 0) return vsUrl;

   var s = vsQueryString.substring(0, n);
   if ((vsUrl.indexOf('&' + s + '=') >= 0) || (vsUrl.indexOf('?' + s + '=') >= 0)) return vsUrl;

   return vsUrl + ((vsUrl.indexOf('?') < 0) ? '?' : '&') + vsQueryString;
}

function RemoveQueryString(vsUrl, vsQueryKey) {
   if ((vsQueryKey == null) || (vsQueryKey == '')) return vsUrl;

   var n = vsUrl.indexOf('&' + vsQueryKey + '=');
   if (n < 0) n = vsUrl.indexOf('?' + vsQueryKey + '=');

   if (n >= 0) {
      var s = vsUrl.substring(n + 2 + vsQueryKey.length);
      vsUrl = vsUrl.substring(0, n + 1);
      n = s.indexOf('&');
      if (n >= 0) vsUrl += s.substring(n + 1);
      var c = vsUrl.substring(vsUrl.length - 1, vsUrl.length);
      if ((c == '?') || (c == '&')) vsUrl = vsUrl.substring(0, vsUrl.length - 1);
   }

   return vsUrl;
}

function ReplaceQueryString(vsUrl, vsQueryString) {
   if ((vsQueryString == null) || (vsQueryString == '')) return vsUrl;

   var n = vsQueryString.indexOf('=');
   if (n < 0) return vsUrl;

   var s = RemoveQueryString(vsUrl, vsQueryString.substring(0, n));
   s = AppendQueryString(s, vsQueryString);
   return s;
}

// positioning methods
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;
}

// display of windowed controls
function ShowHideDDL(visibility) {
   for (i = 0; i < document.forms[0].elements.length; i++) {
      if (document.forms[0].elements[i].type.indexOf('select') == 0)
         document.forms[0].elements[i].style.visibility = visibility;
   }
}

// Control to Click on Enter
function ControlToClickOnEnter(e, ctlName){ 
   var ctl = document.getElementById(ctlName);

   if (ctl != null) {
      if (navigator.appName.indexOf("Netscape") > (-1)) {
            if (e.keyCode == 13) {
            ctl.click();
            return false;
         }
      }

      if (navigator.appName.indexOf("Microsoft Internet Explorer") > (-1)) {
            if (event.keyCode == 13) {
            event.cancelBubble = true;
            event.returnValue = false;
            ctl.click();
            return false;
         }
      }
   }
}

function IgnoreBackspaceNavigation(evt) {
   var e;
   var ctl;
   var key;

   if (navigator.appName.indexOf('Microsoft Internet Explorer') >= 0) {
      e = window.event;
      ctl = event.srcElement;
      key = event.keyCode;
   }
   else {
      e = evt;
      ctl = evt.target;
      key = evt.which;
   }

   var b = (ctl.tagName.toUpperCase() == 'INPUT');
   if (b) b = (ctl.type == 'text') || (ctl.type == 'password') || (ctl.type == 'file');
   if (!b) b = (ctl.tagName.toUpperCase() == 'TEXTAREA');

   if (!b && (key == 8)) {
      if (e.cancelBubble) e.cancelBubble = true;
      if (e.returnValue) e.returnValue = false;
      if (e.stopPropagation) e.stopPropagation();
      return false;
   }
}

// delete confirmation
function ConfirmDelete(sMessage,img) {
   var sOldImage = '';
   if (img != null) {
      sOldImage = img.src;
      img.src = INTEGRA_CLIENT_PATH + 'delete-ani.gif';
   }
   if ((sMessage == null) || (sMessage == '')) sMessage = 'Are you sure you want to delete this item?';
   var x = confirm(sMessage);
   if (img != null) img.src = sOldImage;
   return x;
}

function ConfirmGridDelete(sMessage,trName,tblName) {
   var tr = document.getElementById(trName);
   var tbl = document.getElementById(tblName);
   var sItemCss;

   if (tr != null) {
      sItemCss = tr.className;
      if (tbl != null) tr.className = tbl.SelCss;
   }

   if ((sMessage == null) || (sMessage == '')) sMessage = 'Are you sure you want to delete this item?';
   var x = confirm(sMessage);
   if (tr != null) tr.className = sItemCss;
   return x;
}

// grid methods
function GridSelectionCheck(sPrefix,sSuffix,bValue) {
   var bOkToCheck;
   var i;
   var n;
   var ctl;
   var sCtlName;
   var sOnClick;

   sPrefix = sPrefix.toUpperCase();
   sSuffix = sSuffix.toUpperCase();

   for (i = 0; i < document.forms[0].elements.length; i++) {
      ctl = document.forms[0].elements[i];
      sCtlName = ctl.name.toUpperCase();
      bOkToCheck = false;

      if (sCtlName.indexOf(sPrefix) == 0) {
         if (sSuffix != '') {
            n = sCtlName.lastIndexOf(sSuffix);
            if (n >= 0) sCtlName = sCtlName.substring(n);
            if (sCtlName == sSuffix) bOkToCheck = (ctl.checked != bValue);
         }
         else bOkToCheck = (ctl.checked != bValue);

         if (bOkToCheck) {
            try {
               ctl.checked = bValue;
               sOnClick = ctl.attributes["onclick"].value;
               if ((sOnClick != null) && (sOnClick != "")) eval(sOnClick);
            }
            catch (ex) {
               // ignore
            }
         }
      }
   }

   return false;
}

// date validation (.NET validator)
function ValidateDateNET(source, arguments) {
   try {
      var ctl = document.getElementById(source.controltovalidate);
      var bPromptPersist = (ctl.attributes["PromptPersist"].value == 'True');
      var sPromptText = '';

      if (bPromptPersist && ctl.attributes["PromptText"]) {
         sPromptText = ctl.attributes["PromptText"].value;
      }

      if (bPromptPersist && (sPromptText.toUpperCase() == arguments.Value.toUpperCase())) {
         ctl.value = sPromptText;
         arguments.IsValid = true;
         return true;
      }
      else {
         var dtDate = ValidateDate(arguments.Value);

         if (dtDate != null) {
            var sDisplayFmt = ctl.attributes["DisplayFormat"].value;
            ctl.value = FormatDate(dtDate, sDisplayFmt);
            arguments.IsValid = true;
            return true;
         }
         else if (ctl.value == '') {
            arguments.IsValid = true;
            return true;
         }
         else {
            arguments.IsValid = false;
            return false;
         }
      }
   }
   catch (ex) {
      arguments.IsValid = false;
      return false;
   }
}

// date & time validation (for Grid)
function ValidateDateGrid(ctl) {
   var bIsValid = true;

   try {
      var dtDate = ValidateDate(ctl.value);

      if (dtDate != null) {
         var sDisplayFmt = ctl.attributes["DisplayFormat"].value;
         ctl.value = FormatDate(dtDate, sDisplayFmt);
      }
   }
   catch (ex) {
      bIsValid = false;
   }

   return bIsValid;
}

// time validation (.NET validator)
function ValidateTimeNET(source, arguments) {
   try {
      var ctl = document.getElementById(source.controltovalidate);
      var bPromptPersist = (ctl.attributes["PromptPersist"].value == 'True');
      var sPromptText = '';

      if (bPromptPersist && ctl.attributes["PromptText"]) {
         sPromptText = ctl.attributes["PromptText"].value;
      }

      if (bPromptPersist && (sPromptText.toUpperCase() == arguments.Value.toUpperCase())) {
         ctl.value = sPromptText;
         arguments.IsValid = true;
         return true;
      }
      else {
         var dtTime = ValidateTime(arguments.Value);

         if (dtTime != null) {
            var sDisplayFmt = ctl.attributes["DisplayFormat"].value;
            ctl.value = FormatTime(dtTime, sDisplayFmt);
            arguments.IsValid = true;
            return true;
         }
         else if (ctl.value == '') {
            arguments.IsValid = true;
            return true;
         }
         else {
            arguments.IsValid = false;
            return false;
         }
      }
   }
   catch (ex) {
      arguments.IsValid = false;
      return false;
   }
}

// date range validation (.NET validation)
function ValidateDateRangeNET(source, arguments) {
   try {
      var ctl = document.getElementById(source.controltovalidate);
      var bPromptPersist = (ctl.attributes["PromptPersist"].value == 'True');
      var sPromptText = '';

      if (bPromptPersist && ctl.attributes["PromptText"]) {
         sPromptText = ctl.attributes["PromptText"].value;
      }

      if (bPromptPersist && (sPromptText.toUpperCase() == arguments.Value.toUpperCase())) {
         arguments.IsValid = true;
         return true;
      }
      else {
         var dtDate = ValidateDate(arguments.Value);

         if (dtDate != null) {
            var ctl = document.getElementById(source.controltovalidate);
            var i = ctl.id.lastIndexOf("_");
            if (i >= 0) i = ctl.id.lastIndexOf("_", i - 1);
            var sPrefix = (i >= 0) ? ctl.id.substring(0, i + 1) : "";

            var dt;
            var dtMinDate = new Date(source.MinValue);
            var dtMaxDate = new Date(source.MaxValue);

            var sMinCtl = source.MinValueCtl;
            var sMaxCtl = source.MaxValueCtl;

            if (sMinCtl != '') {
               var ctlMin = document.getElementById(sPrefix + sMinCtl + '_txt');
               if (ctlMin != null) {
                  dt = ValidateDate(ctlMin.value);
                  if (dt != null) dtMinDate = dt;
               }
            }

            if (sMaxCtl != '') {
               var ctlMax = document.getElementById(sPrefix + sMaxCtl + '_txt');
               if (ctlMax != null) {
                  dt = ValidateDate(ctlMax.value);
                  if (dt != null) dtMaxDate = dt;
               }
            }

            arguments.IsValid = ((dtDate >= dtMinDate) && (dtDate <= dtMaxDate));
            return arguments.IsValid;
         }
      }
   }
   catch (ex) {
      arguments.IsValid = false;
      return false;
   }
}

function StripPunctuation(sStr, bAllowLetters, bAllowNumbers, bAllowSpaces) {
   var i;
   var c;
   var sNew = '';

   for (i = 0; i < sStr.length; i++) {
      c = sStr.substring(i, i + 1).toUpperCase();

      if ((bAllowLetters && (c >= 'A') && (c <= 'Z')) || 
          (bAllowNumbers && (c >= '0') && (c <= '9')) || 
          (bAllowSpaces && (c == ' '))) {
         sNew += c;
      }
   }

   return sNew;
}

function ValidateDate(sDate) {
   try {
      var dt = new Date();
      if (sDate == '') return null;
      if (sDate.toLowerCase() == 'n') return dt;

      var dtTime = null;
      var nMonth, nDay, nYear;
      var sMonth, sDay, sYear;
      var bSpaceDelim = false;

      // strip off weekday
      var i = sDate.indexOf(",");
      if (i >= 0) sDate = sDate.substring(i + 1);
      
      // assume: month day [year] format
      var i1 = sDate.indexOf("/");
      if (i1 == -1) i1 = sDate.indexOf("-");
      if (i1 == -1) i1 = sDate.indexOf(".");
      if (i1 == -1) { i1 = sDate.indexOf(" "); bSpaceDelim = true; }
      if (i1 == -1) {
         // no punctuation -- assume MMddyyyy format
         sDate = StripPunctuation(sDate, true, true, false);
         sYear = dt.getFullYear().toString();

         switch (sDate.length) {
            case 1:
               switch (sDate.toLowerCase()) {
                  case 't':
                     sDay   = dt.getDate().toString();
                     nMonth = dt.getMonth() + 1;
                     sMonth = nMonth.toString();
                     break;

                  case 'y':
                     nDay   = dt.getDate() - 1;
                     sDay   = nDay.toString();
                     nMonth = dt.getMonth() + 1;
                     sMonth = nMonth.toString();
                     break;

               }

               break;

            case 2:
               sMonth = sDate.substring(0, 1);
               sDay   = sDate.substring(1, 2);
               break;

            case 3:
               sMonth = sDate.substring(0, 2);
               sDay   = sDate.substring(2);

               if (sMonth.substring(0, 1) == '0') {
                  sMonth = sMonth.substring(1);
               }
               else {
                  nMonth = parseInt(sMonth);

                  if (nMonth > 12) {
                     sMonth = sDate.substring(0, 1);
                     sDay   = sDate.substring(1);
                  }
               }

               break;

            case 4:
               sMonth = sDate.substring(0, 2);
               sDay   = sDate.substring(2, 4);
               break;

            case 6:
            case 8:
               sMonth = sDate.substring(0, 2);
               sDay   = sDate.substring(2, 4);
               sYear  = sDate.substring(4);
               break;
         }

         if (sMonth.substring(0, 1) == '0') sMonth = sMonth.substring(1);
         if (sDay.substring(0, 1)   == '0') sDay   = sDay.substring(1);
         while ((sYear.length > 0) && (sYear.substring(0, 1) == '0')) sYear = sYear.substring(1);

         nMonth = parseInt(sMonth);
         nDay   = parseInt(sDay);
         nYear  = parseInt(sYear);

         if (nYear < 100) {
            var nCentury = parseInt(dt.getFullYear().toString().substring(0, 2) + '00');
            if (nYear > 50) nCentury -= 100;
            nYear += nCentury;
            sYear = nYear.toString();
         }

         sMonth = nMonth.toString();
         sDay   = nDay.toString();
         sYear  = nYear.toString();
      }
      else {
         var i2 = sDate.indexOf("/", i1 + 1);
         if (i2 == -1) i2 = sDate.indexOf("-", i1 + 1);
         if (i2 == -1) i2 = sDate.indexOf(".", i1 + 1);
         if (i2 == -1) {
            i2 = sDate.indexOf(" ", i1 + 1);

            if ((i2 >= 0) && !bSpaceDelim) {
               dtTime = ValidateTime(sDate.substring(i2 + 1));
               sDate = sDate.substring(0, i2);
               i2 = -1;
            }
         }

         sMonth = sDate.substring(0, i1).toLowerCase();

         if ((sMonth == 't') || (sMonth == 'y')) {
            nDay   = dt.getDate() - (sMonth == 'y' ? 1 : 0);
            sDay   = nDay.toString();
            nMonth = dt.getMonth() + 1;
            sMonth = nMonth.toString();
            sYear  = dt.getFullYear().toString();
            dtTime = ValidateTime(sDate.substring(i1 + 1));
         }
         else if (i2 >= 0) {
            var i3 = sDate.indexOf(" ", i2 + 1);
            if (i3 >= 0) {
               dtTime = ValidateTime(sDate.substring(i3 + 1));
               sDate = sDate.substring(0, i3);
            }

            sDay = sDate.substring(i1 + 1, i2);
            sYear = sDate.substring(i2 + 1);
            while ((sYear.length > 0) && (sYear.substring(0, 1) == '0')) sYear = sYear.substring(1);
            if (sYear.length == 0) sYear = '0';

            try {
               nYear = parseInt(sYear);

               if (nYear < 100) {
                  var nCentury = parseInt(dt.getFullYear().toString().substring(0, 2) + '00');
                  if (nYear > 50) nCentury -= 100;
                  nYear += nCentury;
                  sYear = nYear.toString();
               }
            }
            catch (ex) {
               sYear = dt.getFullYear();
            }
         }
         else {
            sDay = sDate.substring(i1 + 1);
            sYear = dt.getFullYear().toString();
         }
      }

      try {
         var s = sMonth.substring(0, 1);
         var b = (s >= "0") && (s <= "9");

         if (dtTime != null) s = ' ' + FormatTime(dtTime, 'hh:mm:ss tt');
            else s = '';

         dt = new Date(sMonth + (b ? '/' : ' ') + sDay + (b ? '/' : ', ') + sYear + s);
         return dt;
      }
      catch (ex) {
         return null;
      }
   }
   catch (ex) {
      return null;
   }
}

function ValidateTime(sTime) {
   try {
      if (sTime == '') return null;

      var i1 = sTime.indexOf(":");
      if (i1 < 0) i1 = sTime.indexOf(".");
      if (i1 < 0) i1 = sTime.indexOf("-");
      if (i1 < 0) {
         var sHour, sMin;
         var sSec = '0';
         var sTT = '';
         i1 = sTime.indexOf(" ");

         if (i1 >= 0) {
            sTT = sTime.substring(i1 + 1);
            sTime = sTime.substring(0, i1);
         }

         switch (sTime.length) {
            case 2:
               sHour = sTime.substring(0, 1);
               sMin  = sTime.substring(1, 2);
               break;

            case 3:
               sMin  = sTime.substring(2);
               i1 = parseInt(sTime.substring(0, 2));
               if (i1 > 12) {
                  if (sTT == '') {
                     i1 -= 12;
                     if (i1 > 12) {
                        sHour = sTime.substring(0, 1);
                        sMin  = sTime.substring(1);
                     }
                     else {
                        sHour = i1.toString();
                     }
                  }
                  else {
                     sHour = sTime.substring(0, 1);
                     sMin  = sTime.substring(1);
                  }
               }
               else {
                  sHour = sTime.substring(0, 2);
               }
               break;

            case 4:
               sHour = sTime.substring(0, 2);
               sMin  = sTime.substring(2);
               break;

            case 6:
               sHour = sTime.substring(0, 2);
               sMin  = sTime.substring(2, 4);
               sSec  = sTime.substring(4);
               break;

            default: return null;
         }

         sTime = sHour + ':' + sMin + ':' + sSec + ' ' + sTT;
      }
      else {
         sTime = sTime.replace(".", ":");
         sTime = sTime.replace("-", ":");
      }

      var dt = new Date(Date.parse('01/01/2000 ' + sTime));
      return dt;
   }
   catch (ex) {
      alert(ex);
      return null;
   }
}

function FormatDate(dtDate, sFormat) {
   var i;
   var sResult = sFormat;
   
   if (isNaN(dtDate.getMonth())) return '';

   // check for full month name
   i = sResult.indexOf('MMMM');
   if (i >= 0) {
      var asFullMonth = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
      sResult = sResult.substring(0, i) + 'asFullMonth[dtDate.getMonth()]' + sResult.substring(i + 4);
   }

   // check for abbreviated month name
   i = sResult.indexOf('MMM');
   if (i >= 0) {
      var asAbbrevMonth = new Array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
      sResult = sResult.substring(0, i) + asAbbrevMonth[dtDate.getMonth()] + sResult.substring(i + 3);
   }

   // check for two-digit month number
   i = sResult.indexOf('MM');
   if (i >= 0) {
      var nMonth = dtDate.getMonth() + 1;
      sResult = sResult.substring(0, i) + ((nMonth < 10) ? '0' : '') + nMonth.toString() + sResult.substring(i + 2);
   }

   // check for one-digit month number
   i = sResult.indexOf('M');
   if (i >= 0) {
      var nMonth = dtDate.getMonth() + 1;
      sResult = sResult.substring(0, i) + nMonth.toString() + sResult.substring(i + 1);
   }

   // check for full weekday
   i = sResult.indexOf('dddd');
   if (i >= 0) {
      var asFullWeekday = new Array('Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday');
      sResult = sResult.substring(0, i) + asFullWeekday[dtDate.getDay()] + sResult.substring(i + 4);
   }

   // check for abbreviated weekday
   i = sResult.indexOf('ddd');
   if (i >= 0) {
      var asAbbrevWeekday = new Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
      sResult = sResult.substring(0, i) + asAbbrevWeekday[dtDate.getDay()] + sResult.substring(i + 3);
   }

   // check for two-digit day
   i = sResult.indexOf('dd');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + ((dtDate.getDate() < 10) ? '0' : '') + dtDate.getDate().toString() + sResult.substring(i + 2);
   }

   // check for one-digit day
   i = sResult.indexOf('d');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + dtDate.getDate().toString() + sResult.substring(i + 1);
   }

   // check for four-digit year
   i = sResult.indexOf('yyyy');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + dtDate.getFullYear().toString() + sResult.substring(i + 4);
   }

   // check for four-digit year
   i = sResult.indexOf('yy');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + dtDate.getFullYear().toString().substring(2) + sResult.substring(i + 2);
   }

   // check for four-digit year
   i = sResult.indexOf('y');
   if (i >= 0) {
      var sYear = dtDate.getFullYear().toString();
      var nYear = parseInt(sYear.substring(2));
      sResult = sResult.substring(0, i) + nYear.toString() + sResult.substring(i + 1);
   }

   sResult = FormatTime(dtDate,sResult);
   return sResult;
}

function FormatTime(dtTime, sFormat) {
   var i;
   var sResult = sFormat;
   var nHour = dtTime.getHours();

   if (isNaN(nHour)) return '';

   // check for two-digit hour (24-hour format)
   i = sResult.indexOf('HH');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + ((nHour < 10) ? '0' : '') + nHour.toString() + sResult.substring(i + 2);
   }

   // check for one-digit hour (24-hour format)
   i = sResult.indexOf('H');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + nHour.toString() + sResult.substring(i + 1);
   }

   if (nHour > 12) nHour -= 12;

   // check for two-digit hour (12-hour format)
   i = sResult.indexOf('hh');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + ((nHour < 10) ? '0' : '') + nHour.toString() + sResult.substring(i + 2);
   }

   // check for one-digit hour (12-hour format)
   i = sResult.indexOf('h');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + nHour.toString() + sResult.substring(i + 1);
   }

   // check for two-digit minute
   i = sResult.indexOf('mm');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + ((dtTime.getMinutes() < 10) ? '0' : '') + dtTime.getMinutes().toString() + sResult.substring(i + 2);
   }

   // check for one-digit minute
   i = sResult.indexOf('m');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + dtTime.getMinutes().toString() + sResult.substring(i + 1);
   }

   // check for one-digit second
   i = sResult.indexOf('ss');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + ((dtTime.getSeconds() < 10) ? '0' : '') + dtTime.getSeconds().toString() + sResult.substring(i + 2);
   }

   // check for one-digit second
   i = sResult.indexOf('s');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + dtTime.getSeconds().toString() + sResult.substring(i + 1);
   }

   // check for two-character lowercase AM/PM
   i = sResult.indexOf('tt');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + ((dtTime.getHours() < 12) ? 'am' : 'pm') + sResult.substring(i + 2);
   }

   // check for one-character lowercase AM/PM
   i = sResult.indexOf('t');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + ((dtTime.getHours() < 12) ? 'a' : 'p') + sResult.substring(i + 1);
   }

   // check for two-character uppercase AM/PM
   i = sResult.indexOf('TT');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + ((dtTime.getHours() < 12) ? 'AM' : 'PM') + sResult.substring(i + 2);
   }

   // check for one-character uppercase AM/PM
   i = sResult.indexOf('T');
   if (i >= 0) {
      sResult = sResult.substring(0, i) + ((dtTime.getHours() < 12) ? 'A' : 'P') + sResult.substring(i + 1);
   }

   return sResult;
}

// number validation (.NET validator)
function ValidateNumberNET(source, arguments) {
   var ctl = document.getElementById(source.controltovalidate);
   var sNewValue = '';

   try {
      var bPromptPersist = (ctl.attributes["PromptPersist"].value == 'True');
      var sPromptText = '';

      if (bPromptPersist && ctl.attributes["PromptText"]) {
         sPromptText = ctl.attributes["PromptText"].value;
      }

      if (bPromptPersist && (sPromptText.toUpperCase() == arguments.Value.toUpperCase())) {
         sNewValue = sPromptText;
         arguments.IsValid = true;
      }
      else {
         var s = arguments.Value;
         while (s.substring(s.length - 1, s.length) == ' ') { s = s.substring(0, s.length - 1); }

         if (s == '') {
            sNewValue = (ctl.attributes["AllowBlank"].value == 'True') ? '' : '0';
            arguments.IsValid = true;
         }
         else {
            var dNum = ValidateNumber(s);

            if (!isNaN(dNum)) {
               var nDec = parseInt(ctl.attributes["Decimals"].value);
               var bRound = (ctl.attributes["Round"].value == 'True');
               var bCommas = (ctl.attributes["ShowCommas"].value == 'True');
               var bCurrency = (ctl.attributes["ShowCurrency"].value == 'True');
               var sNegDisplay = ctl.attributes["NegDisplay"].value;

               arguments.IsValid = true;

               if (!bRound) {
                  s = dNum.toString();
                  i = s.indexOf(".");
                  s = s.substring(i + 1);
                  if (s.length() > nDec) arguments.IsValid = false;
               }

               if (arguments.IsValid) sNewValue = FormatNumber(dNum, nDec, sNegDisplay, bCommas, bCurrency);
            }
            else {
               arguments.IsValid = false;
            }
         }
      }
   }
   catch (ex) {
      arguments.IsValid = false;
   }

   if (arguments.IsValid) ctl.value = sNewValue;
   return arguments.IsValid;
}

// number validation (for Grid)
function ValidateNumberGrid(ctl) {
   var bIsValid = true;
   var sNewValue = '';

   try {
      var s = ctl.value;
      while (s.substring(s.length - 1, s.length) == ' ') { s = s.substring(0, s.length - 1); }

      if (s == '') {
         sNewValue = (ctl.attributes["AllowBlank"].value == 'True') ? '' : '0';
         bIsValid = true;
      }
      else {
         var dNum = ValidateNumber(s);

         if (!isNaN(dNum)) {
            var nDec = parseInt(ctl.attributes["Decimals"].value);
            var bRound = (ctl.attributes["Round"].value == 'True');
            var bCommas = (ctl.attributes["ShowCommas"].value == 'True');
            var bCurrency = (ctl.attributes["ShowCurrency"].value == 'True');
            var sNegDisplay = ctl.attributes["NegDisplay"].value;

            bIsValid = true;

            if (!bRound) {
               s = dNum.toString();
               i = s.indexOf(".");
               s = s.substring(i + 1);
               if (s.length() > nDec) bIsValid = false;
            }

            if (bIsValid) sNewValue = FormatNumber(dNum, nDec, sNegDisplay, bCommas, bCurrency);
         }
         else {
            bIsValid = false;
         }
      }
   }
   catch (ex) {
      bIsValid = false;
   }

   if (bIsValid) ctl.value = sNewValue;
   return bIsValid;
}

// number range validation (.NET validation)
function ValidateNumberRangeNET(source, arguments) {
   try {
      var ctl = document.getElementById(source.controltovalidate);
      var bPromptPersist = (ctl.attributes["PromptPersist"].value == 'True');
      var sPromptText = '';

      if (bPromptPersist && ctl.attributes["PromptText"]) {
         sPromptText = ctl.attributes["PromptText"].value;
      }

      if (bPromptPersist && (sPromptText.toUpperCase() == arguments.Value.toUpperCase())) {
         arguments.IsValid = true;
         return true;
      }
      else {
         var dNum = ValidateNumber(arguments.Value);

         if (!isNaN(dNum)) {
            var i = ctl.id.lastIndexOf("_");
            if (i >= 0) i = ctl.id.lastIndexOf("_", i - 1);
            var sPrefix = (i >= 0) ? ctl.id.substring(0, i + 1) : "";

            var d;
            var dMinValue = parseFloat(source.MinValue);
            var dMaxValue = parseFloat(source.MaxValue);

            var sMinCtl = source.MinValueCtl;
            var sMaxCtl = source.MaxValueCtl;

            if (sMinCtl != '') {
               var ctlMin = document.getElementById(sPrefix + sMinCtl + '_txt');
               if (ctlMin != null) {
                  d = ValidateNumber(ctlMin.value);
                  if (!isNaN(d)) dMinValue = d;
               }
            }

            if (sMaxCtl != '') {
               var ctlMax = document.getElementById(sPrefix + sMaxCtl + '_txt');
               if (ctlMax != null) {
                  d = ValidateNumber(ctlMax.value);
                  if (!isNaN(d)) dMaxValue = d;
               }
            }

            arguments.IsValid = ((dNum >= dMinValue) && (dNum <= dMaxValue));
            return arguments.IsValid;
         }
      }
   }
   catch (ex) {
      arguments.IsValid = false;
      return false;
   }
}

function ValidateNumber(sValue) {
   var sNewValue = '';
   var c;
   var bFoundMinus = false;
   var i;

   // strip commas and dollar signs (they confuse the parser)
   // also strip negative symbols and parentheses, record that the number is negative
   for (i = 0; i < sValue.length; i++) {
      c = sValue.substring(i, i + 1);

      if (c == "(") c = "-";

      if (c == "-") {
         bFoundMinus = true;
         c = ")";
      }

      if ((c != ",") && (c != "$") && (c != ")")) {
         if (((c < "0") || (c > "9")) && (c != ".")) return NaN;

         sNewValue += c;
      }
   }

   if (bFoundMinus) sNewValue = '-' + sNewValue;

   try {
      var d = parseFloat(sNewValue);
      return d;
   }
   catch (ex) {
      return NaN;
   }
}

function FormatNumber(dNum, nDec, sNegDisplay, bCommas, bCurrency) {
   if (isNaN(dNum)) return '';

   var sNum = '';
   var sDec = '';
   var i;
   var bIsNegative = (dNum < 0);

   dNum = Math.abs(dNum);

   // handle rounding to correct decimal place
   if (nDec >= 0) {
      var sZeros = '000000000000000'   // 15 zeros
      var nMult = parseInt('1' + sZeros.substring(0, nDec));
      dNum = (Math.round(dNum * nMult)) / nMult;

      // now add trailing zeros
      sNum = dNum.toString();
      i = sNum.indexOf(".");

      if (i >= 0) {
         sDec = sNum.substring(i);
         sNum = sNum.substring(0, i);
      }
      else sDec = '.';

      while (sDec.length < nDec + 1) sDec += '0';

      if (sDec != '.') sNum += sDec;
   }
   else {
      sNum = dNum.toString();
   }

   if (bCommas) {
      var nLen;

      // strip decimals for now (they are an unknown length)
      i = sNum.indexOf(".");

      if (i >= 0) {
         sDec = sNum.substring(i);
         sNum = sNum.substring(0, i);
      }
      else {
         sDec = '';
      }

      // add comma in thousands place
      if (dNum >= 1000) {
         nLen = sNum.length
         sNum = parseInt('' + (dNum / 1000)) + ',' + sNum.substring(nLen - 3, nLen)
      }

      // add comma in millions place
      if (dNum >= 1000000) {
         nLen = sNum.length
         sNum = parseInt('' + (dNum / 1000000)) + ',' + sNum.substring(nLen - 7, nLen)
      }

      // re-add decimals
      sNum += sDec;
   }

   if (sNum.substring(0, 1) == ".") sNum = '0' + sNum;

   if (bIsNegative) {
      switch (sNegDisplay) {
         case 'Parens':
            sNum = '(' + (bCurrency ? '$' : '') + sNum + ')';
            bCurrency = false;
            break;

         case 'Postfix': sNum += '-'; break;
         default: sNum = '-' + sNum; break;
      }
   }

   if (bCurrency) sNum = '$' + sNum;
   return sNum;
}

// phone number validation
function ValidatePhoneNET(source, arguments) {
   var ctl = document.getElementById(source.controltovalidate);
   var bPromptPersist = (ctl.attributes["PromptPersist"].value == 'True');
   var sPromptText = '';

   if (bPromptPersist && ctl.attributes["PromptText"]) {
      sPromptText = ctl.attributes["PromptText"].value;
   }

   if (bPromptPersist && (sPromptText.toUpperCase() == arguments.Value.toUpperCase())) {
      ctl.value = sPromptText;
      arguments.IsValid = true;
      return true;
   }
   else {
      var sPhone = checkPhone(arguments.Value);

      if (sPhone != '') ctl.value = sPhone;
      return true;
   }
}

function checkPhone(sPhone) {
   var tempStr = sPhone;
   var tempLen = tempStr.length;
   var tempNum = '';

   if (tempLen == 0) return '';
     
   while (tempLen > 0) {
      tempChr = tempStr.substring(0,1)
      if (tempChr >= '0' && tempChr <= '9') { tempNum = tempNum + tempChr; }

      tempStr2 = tempStr.substring(1,tempLen);
      tempLen--;
      tempStr = tempStr2;
   }

   // tempNum = tempNum.substring(0, tempNum.length);
   if (tempNum.length != 10) {
		   // alert("Please enter the correct number of digits including the area code.");
		   // txtObj.focus();
		   return '';
   } 
   else {
	 	   tempStr = tempNum.substring(0, 3) + '-' + tempNum.substring(3, 6) + '-' + tempNum.substring(6, 10);
      // txtObj.value = tempStr;
      return tempStr;
   }
}

// SSN validation
function ValidateSSNNET(source, arguments) {
   var ctl = document.getElementById(source.controltovalidate);
   var bPromptPersist = (ctl.attributes["PromptPersist"].value == 'True');
   var sPromptText = '';

   if (bPromptPersist && ctl.attributes["PromptText"]) {
      sPromptText = ctl.attributes["PromptText"].value;
   }

   if (bPromptPersist && (sPromptText.toUpperCase() == arguments.Value.toUpperCase())) {
      ctl.value = sPromptText;
      arguments.IsValid = true;
      return true;
   }
   else {
      var sSSN = checkSSN(arguments.Value);

      if (sSSN != '') ctl.value = sSSN;
      return true;
   }
}

function checkSSN(sSSN) {
   var tempStr = sSSN;
   var tempLen = tempStr.length;
   var tempNum = "";

   if (tempLen == 0) return '';
     
   while (tempLen > 0) {
      tempChr = tempStr.substring(0,1)
      if ((tempChr >= "0") && (tempChr <= "9")) tempNum += tempChr;

      tempStr2 = tempStr.substring(1,tempLen);
      tempLen--;
      tempStr = tempStr2;
   }

   tempNum = tempNum.substring(0, tempNum.length);

   if (tempNum.length != 9) {
		   // alert("Please enter the correct number of digits.");
		   // txtObj.focus();
		   return '';
   } 
   else {
	 	tempStr = tempNum.substring(0, 3) + '-' + tempNum.substring(3, 5) + '-' + tempNum.substring(5, 9);
      // txtObj.value = tempStr;
      return tempStr;
   }
}

// alien ID validation
function ValidateAlienNET(source, arguments) {
   var ctl = document.getElementById(source.controltovalidate);
   var bPromptPersist = (ctl.attributes["PromptPersist"].value == 'True');
   var sPromptText = '';

   if (bPromptPersist && ctl.attributes["PromptText"]) {
      sPromptText = ctl.attributes["PromptText"].value;
   }

   if (bPromptPersist && (sPromptText.toUpperCase() == arguments.Value.toUpperCase())) {
      ctl.value = sPromptText;
      arguments.IsValid = true;
      return true;
   }
   else {
      var sAlienID = checkAlienID(arguments.Value);

      if (sAlienID != '') ctl.value = sAlienID;
      return true;
   }
}

function checkAlienID(sAlienID) {
   var tempStr = sAlienID;
   var tempLen = tempStr.length;
   var tempNum = "";

   if (tempLen == 0) return '';
     
   while (tempLen > 0) {
      tempChr = tempStr.substring(0,1)
      if ((tempChr >= "0") && (tempChr <= "9")) tempNum += tempChr;

      tempStr2 = tempStr.substring(1,tempLen);
      tempLen--;
      tempStr = tempStr2;
   }

   tempNum = tempNum.substring(0, tempNum.length);

   if (tempNum.length != 9) {
		   // alert("Please enter the correct number of digits.");
		   // txtObj.focus();
		   return '';
   } 
   else {
	 	// tempStr = tempNum.substring(0, 3) + '-' + tempNum.substring(3, 5) + '-' + tempNum.substring(5, 9);
      // txtObj.value = tempStr;
      return tempNum;
   }
}

// zip code validation
function ValidateZipNET(source, arguments) {
   var ctl = document.getElementById(source.controltovalidate);
   var bPromptPersist = (ctl.attributes["PromptPersist"].value == 'True');
   var sPromptText = '';

   if (bPromptPersist && ctl.attributes["PromptText"]) {
      sPromptText = ctl.attributes["PromptText"].value;
   }

   if (bPromptPersist && (sPromptText.toUpperCase() == arguments.Value.toUpperCase())) {
      ctl.value = sPromptText;
      arguments.IsValid = true;
      return true;
   }
   else {
      var sZip = checkZip(arguments.Value);

      if (sZip != '') ctl.value = sZip;
      return true;
   }
}

function checkZip(sZip) {
   var tempStr = sZip;
   var tempLen = tempStr.length;
   var tempNum = "";

   if (tempLen == 0) return '';
     
   while (tempLen > 0) {
      tempChr = tempStr.substring(0,1)

      if ((tempChr >= "0") && (tempChr <= "9")) tempNum += tempChr;

      tempStr2 = tempStr.substring(1,tempLen);
      tempLen--;
      tempStr = tempStr2;
   }

   tempNum = tempNum.substring(0, tempNum.length);

   if ((tempNum.length == 5) && (tempNum.length != 9)) {
		// alert("Please enter the correct number of digits (5 or 9).");
		// txtObj.focus();
		return '';
   } 
   else {
		if (tempNum.length == 9) tempStr = tempNum.substring(0, 5) + '-' + tempNum.substring(5, 9);
         else tempStr = tempNum.substring(0, 5);
        
      // txtObj.value = tempStr;
      return tempStr;
   }
}

function LUHN(sCardNum) {
	var n;
	var nSum = 0;

   for (var i = 1; i <= sCardNum.length; i++) {
      n = parseInt(sCardNum.substring(sCardNum.length - i, sCardNum.length - i + 1));

      // every other digit is multiplied by 2
      // add the resulting digits (not number)
      // subtracting 9 does the trick
      // ex. 6 * 2 = 13, so add 1 + 3 (or 13 - 9) = 4
      if ((i % 2) == 0) {
         n *= 2;
         if (n > 9) n -= 9;
      }

      nSum += n;
   }

   return ((nSum % 10) == 0) ? true : false;
}

function ValidateCreditCardNET (source, arguments) {
   try {
      var ctl = document.getElementById(source.controltovalidate);
      var bPromptPersist = (ctl.attributes["PromptPersist"].value == 'True');
      var sPromptText = '';

      if (bPromptPersist && ctl.attributes["PromptText"]) {
         sPromptText = ctl.attributes["PromptText"].value;
      }

      if (bPromptPersist && (sPromptText.toUpperCase() == arguments.Value.toUpperCase())) {
         ctl.value = sPromptText;
         arguments.IsValid = true;
         return true;
      }
      else {
         var s = arguments.Value;
         var sNew = "";
         var c;
         var sDelimiter = source.attributes["Delimiter"].value;
         var bPerformChecksum = (source.attributes["PerformChecksum"].value == 'True');

         if (sDelimiter == null) sDelimiter = ' ';

         // reset format message
         var sErrMsg = source.attributes["OrigMsg"].value;
         //source.attributes["FormatMessage"].value = '&nbsp;' + sErrMsg;

         for (var i = 0; i < s.length; i++) {
            c = s.substring(i, i + 1);
            if (((c < "0") || (c > "9")) && (c != " ") && (c != "-") && (c != ".")) {
               arguments.IsValid = false;
               break;
            }
            else if ((c >= "0") && (c <= "9")) sNew += c;
         }
         // validate general length
         if (arguments.IsValid) {
            arguments.IsValid = (sNew.length >= 13) && (sNew.length <= 16);
            sErrMsg = 'Must be 13 to 16 digits';
         }

         var sMasterCard = ',51,52,53,54,55,';
         var sDinersClub = ',300,301,302,303,304,305,';

         // validate lengths of known card types
         if (arguments.IsValid) {
            // VISA
            if (sNew.substring(0, 1) == '4') {
               arguments.IsValid = (sNew.length == 13) || (sNew.length == 16);
               sErrMsg = 'VISA must be 13 or 16 digits';
            }
            // Discover
            else if (sNew.substring(0, 4) == '6011') {
               arguments.IsValid = (sNew.length == 16);
               sErrMsg = 'Discover must be 16 digits';
            }
            // MasterCard
            else if (sMasterCard.indexOf(',' + sNew.substring(0, 2) + ',') >= 0) {
               arguments.IsValid = (sNew.length == 16);
               sErrMsg = 'MasterCard must be 16 digits';
            }
            // American Express
            else if ((sNew.substring(0, 2) == '34') || (sNew.substring(0, 2) == '37')) {
               arguments.IsValid = (sNew.length == 15);
               sErrMsg = 'AMEX must be 15 digits';
            }
            // Diner's Club/Carte Blanche
            else if ((sNew.substring(0, 2) == '36') || (sNew.substring(0, 2) == '38') || 
                     (sDinersClub.indexOf(',' + sNew.substring(0, 3) + ',') >= 0)) {
               arguments.IsValid = (sNew.length == 14);
               sErrMsg = 'Diner\'s Club must be 14 digits';
            }
            // Australian BankCard
            else if (sNew.substring(0, 4) == '5610') {
               arguments.IsValid = (sNew.length == 16);
               sErrMsg = 'Aus BankCard must be 16 digits';
            }
            // enRoute
            else if ((sNew.substring(0, 4) == '2014') || (sNew.substring(0, 4) == '2149')) {
               bPerformChecksum = false;
               arguments.IsValid = (sNew.length == 15);
               sErrMsg = 'enRoute must be 15 digits';
            }
            else if ((sNew.substring(0, 4) == '2131') || (sNew.substring(0, 4) == '1800')) {
               arguments.IsValid = (sNew.length == 15);
               sErrMsg = 'JCB(1) must be 15 digits';
            }
            else if (sNew.substring(0, 1) == '3') {
               arguments.IsValid = (sNew.length == 16);
               sErrMsg = 'JCB(3) must be 16 digits';
            }
         }

         // perform checksum using LUHN formula (mod 10)
         if (arguments.IsValid && bPerformChecksum) {
            arguments.IsValid = LUHN(sNew);
            sErrMsg = 'Checksum failed';
         }

         if (arguments.IsValid) {
            ctl.value = sNew.substring(0,  4) + sDelimiter + sNew.substring(4, 8) + sDelimiter + 
                        sNew.substring(8, 12) + sDelimiter + sNew.substring(12);
         }
         else {
            source.innerHTML = '&nbsp;' + sErrMsg;
         }

         return arguments.IsValid;
      }
   }
   catch (ex) {
      arguments.IsValid = false;
      return false;
   }
}

// NumberBox spinner methods
function SpinCheck(nb) {
   var txt = document.getElementById(nb.id + '_txt');

   var curValue = parseInt(txt.value);
   var minValue = parseInt(txt.MinValue);
   var maxValue = parseInt(txt.MaxValue);

   var imbUp = document.getElementById(nb.id + '_imbSpinUp');
   var imbDn = document.getElementById(nb.id + '_imbSpinDown');

   if (imbUp != null) {
      imbUp.disabled = (curValue >= maxValue);
      imbUp.src = INTEGRA_CLIENT_PATH + (imbUp.disabled ? 'up-dis.gif' : 'up.gif');
   }

   if (imbDn != null) {
      imbDn.disabled = (curValue <= minValue);
      imbDn.src = INTEGRA_CLIENT_PATH + (imbDn.disabled ? 'down-dis.gif' : 'down.gif');
   }
}

function SpinNumber(nb,val) {
   var txt = eval(document.forms[0].elements[nb.id + '_txt']);

   var curValue = parseInt(txt.value);
   var minValue = parseInt(txt.MinValue);
   var maxValue = parseInt(txt.MaxValue);

   curValue += val;
   if (curValue > maxValue) curValue = maxValue;
   if (curValue < minValue) curValue = minValue;

   txt.value = curValue.toString();
   SpinCheck(nb);
}
