//<script type="text/javascript">

//function su13formInit() {1;}

/* Calendar date selection interation and checking
    - Boolean   isBizDayQ(dateObj) Predicate for confirming date is business day; extensible proc
    - DateObj   offsetBizDays(dateObj,offsetDays) produces business day offset from today (or nearest business day in requested direction).
    - undef     checkDateStart(field) sets field to formatted date, and static (hidden) form field to unixtime
    - undef     checkDateEnd(field) sets field to formatted date
    - Boolean   checkTS(field) onchange handler -- confirms, formats, and provides conforming time of day
    - undef     signalrequired(event, elemCBox, pairedTxtID) oncheck handler -- sets paired text field value to * or "" according to checkbox
    - undef     clickCBOX(event, elemCBox, pairedTxtID, pairedTxtTabIndex) onclick handler -- checkbox+field pairs 
    - undef     clickTXT(event, elemTxt, pairedCBoxID, ourTabIndex) onclick handler -- checkbox+field pairs
    - undef     changeTXT(event, elemTxt, pairedCBoxID) onchange handler -- checkbox+field pairs 
*/ 
// return Boolean. Can subst. elaborate calendar checking. Util proc for lookbackBizDays().
function isBizDayQ(dateObj) {
    var theWkDay = dateObj.getDay();
    return !(theWkDay == 0 || theWkDay == 6);
}

// return Date object
function offsetBizDays(dateObj,offsetDays) {
    var theD = new Date(dateObj.valueOf());
    var day_msecs = 86400000; // 24hours
    while (! isBizDayQ(theD) )
	theD.setTime(theD.getTime() + day_msecs);
    if (offsetDays < 0) {
	day_msecs *= -1; 
        offsetDays *= -1;
    }
    while (offsetDays > 0) {
	theD.setTime(theD.getTime() + day_msecs);
	if (isBizDayQ(theD)) --offsetDays;
    }
    return theD;
}

// return: undef; side-effect: sets the called date field to formated date, and the constant date field to unix string.
/* Note: Although the date fields help the user in input, we don't try to shift to their current timezone.
 *       As such, the date-offsets shown during form entry might not precisely match actual specifications.
 *       Instead, the unixstring *does* capture this information, and is used in server-side form validation processing.
 *       The result on the webconfirmation, and email, does reflect these specific time/date calculations.
 */ 
function checkDateStart(field){  //want something convertable to month, dd, yyyy
    if (!isDangerousUA()) {
        var theDate = Date.parseDate(field.value,"%B %e, %Y");
        field.value = theDate.print("%B %e, %Y");
        var startUnixField = document.getElementById("id_datestart_unix");
        startUnixField.value = theDate.print("%s");
}   }

// return: undef; side-effect: sets specified field to formatted date
function checkDateEnd(field){  //want something convertable to month, dd, yyyy
    if (!isDangerousUA()) {
        var theDate = Date.parseDate(field.value,"%B %e, %Y");
        field.value = theDate.print("%B %e, %Y");
}   }

// return: boolean 
// Note: this is an fully-valid 2822 check; but certain MTA and UA disallowed some resulting structures.
//       Except, of course, for TLDs, which are limited to 2-5 chars, and are (obviously) not confirmed.
function checkEmail(field){ //confirm field meets RFC2822 and referenced standards for email address
   var theEmail = field.value;   
   if (theEmail.length = 0) return; //okay, except for required or not
   var dq = /^[^"']/; //"
   var lclpart = /^[a-zA-Z0-9!#$%&'*+-/=?^_`{|}~]+([.][a-zA-Z0-9!#$%&'*+-/=?^_`{|}~]+)*$/;
   var dompart = /^([a-zA-Z0-9!#$%&'*+-/=?^_`{|}~]+[.])+[a-zA-Z0-9!#$%&'*+-/=?^_`{|}~]{2,5}$/;
   var addrparts;
   addrparts = theEmail.split("@"); 
   if (theEmail.match(dq) == null) {alert("Provide unquoted email address."); return false; }
   if (addrparts.length != 2) {alert("Email address must include (a single) @ and domain."); return false;}
   if (addrparts[0].match(lclpart) == null) {alert("Improper email address: local part."); return false;} 
   if (addrparts[1].match(dompart) == null) {alert("Improper email address: domain."); return false;}  
   }

// return: boolean; side-effect: field is processed and reformated in a conforming meridiem-time format.
/* Note: Purpose is to allow users flexibility in time entry. A large range of entries are supported,
 *       including 24hour time, and single-digit times (which supply an assumes meridiem for 'obvious' ranges).
 *       The result is guaranteed to (a) reject the input, or 
 *       (b) to be in %l:%M%P form (e.g., 4:02pm or 10:40am) 
 * Single error message, hinting at flexibility. (Preferrably omit if there is no later dependent processing.)
 * Expressly no attempt to declare capability/teach user-it should just know what is meant.
 * However, with respect to "Checking" times, there is no effort here to confirm that a time here will be
 *       consistent with another time (such as end timestamps falling after beginning timetamps).
 */
function checkTS(field){ // just tod/hours, not complete a time stamp.
  if (!isDangerousUA()) {
      var theTS = field.value;
      var patTime = /^(2[0-3]|[01]?\d)[ :]*([0-5]\d)?(?!\d)\s*([apAP])?/;
      var matchTime = theTS.match(patTime);
      var HH, MM, AP, hour, mins, meridiem;
      var minsSt = String("%");
      if (matchTime != null) {
         HH = matchTime[1];
         MM = matchTime[2] === undefined ? null : matchTime[2];
         AP = matchTime[3] === undefined ? null : matchTime[3];
         if (HH.substring(0, 1) == '0') { meridiem = 'a'; hour = (HH == 0) ? 12 : HH[1];
         } else if (HH >= 13) { meridiem = "p"; hour = HH - 12;
         } else {
            hour = HH;
            if (!AP) meridiem = ((hour >= 12) || (hour <= 5)) ? "p" : "a";
            else meridiem = AP.toLowerCase();
         }
         mins = MM | 0;
         minsSt += mins;
         minsSt = (minsSt.length == 2) ? minsSt.replace(/%/,'0') : minsSt.substr(1,2);
         field.value = hour + ":" + minsSt + meridiem + "m"; // hour:mins meridiem;
      }
      else {alert("Improper time. You might try something similar to 3:45pm or 1545."); field.value=""; return false;}
      }
  }

// return: undef; side-effect: indicated paired item will be set to indicate it is a required field
/* Typically: the identified paired text span is empty, and has a CSS style which will result in the desired indication
 *    <span class="required" id="rqtevsta"></span>
 */
function signalrequired(event, elemCBox, pairedTxtID){
    var elemTxt = document.getElementById(pairedTxtID);
    elemTxt.innerHTML = elemCBox.checked ? "*" : "";
}

//To manage the checkbox,textinput couplets ... old-style event handler decls
/*   Supports broad scope of interaction modalities: clicks on text, clicks on checkbox, changes to text, 
 *       expected taborder behavior, prompting of field purpose, confirmation of positive entry 
 *       guiding users without requiring alert boxes or specific numeric/text entry.
 *   Flexible entry supports users who provide text rather than numbers, but excludes
 *       simple(-minded) UA-side time-of-entry validation. The result is improved interaction model.
 */ 
/* Notes: does not handle all cases, still requires form validation (but more direct)
 *   The cbox is defined with (event,this,-id-of-paired-textinput-,-tabindex-of-textinput-)
 *   The textinput is defined with: tabindex="-1" and value="copies" (or other obvious, and linked for submission validation)
 *     and, class=class-with-color-for-disabled
 *     and, onchange (event,this,-id-of-paired-checkbox-)
 *     and, onclock (event,this,-id-of-paired-checkbox-,-tabindex-of-textinput-)
 */
function clickCBOX(event, elemCBox, pairedTxtID, pairedTxtTabIndex) {
  var elemTxt = document.getElementById(pairedTxtID);
  //we assume we have pairedTextTabIndex, but we might not :-)
  if(elemCBox.checked){
    elemTxt.value = "1"; elemTxt.select();
    elemTxt.tabIndex = pairedTxtTabIndex;
    elemTxt.className = "elemTextEnabled";
    elemTxt.focus();
  } else {
    elemTxt.className = "elemTextDisabled";
    elemTxt.value = "copies"; elemTxt.tabIndex = -1;
  }}
function clickTXT(event, elemTxt, pairedCBoxID, ourTabIndex) {
  var elemCBox = document.getElementById(pairedCBoxID);
  if (elemCBox.checked) {
    elemTxt.select();
  } else {
    elemCBox.checked = true;
    elemTxt.className = "elemTextEnabled";
    if (elemTxt.value == "copies" ) elemTxt.value = 1;
    elemTxt.select(); elemTxt.tabIndex = ourTabIndex;
  }}
function changeTXT(event, elemTxt, pairedCBoxID) {
  var elemCBox = document.getElementById(pairedCBoxID);
  if (elemTxt.value == 0 || elemTxt.value == "") {
    elemCBox.checked = false;
    elemTxt.className = "elemTextDisabled";
    elemTxt.value = "copies";
    elemTxt.tabIndex = -1;
  }}


//</script>

