/*
 * Bit that does custom hiding and showing of elements depending on state of other elements
 */
$(document).ready(function(){
  // note that the osuid field is enabled by default, so that we don't need
  // JavaScript to be enabled to set its disabled attribute (JavaScript is 
  // used for progressive enhancement only.)
  if ($("#discount").val() == "osustudent" || $("#discount").val() == "facstaff") {
    $("#osuconditional").removeClass("screen-reader-hide");
    $("#osuid").removeAttr("disabled");
  } else {
    $("#osuconditional").addClass("screen-reader-hide");
    $("#osuid").attr({disabled: "disabled"});
  }
  
  // rule: presenters don't pay for main event, just for preconference
  if ($("#discount").val() == "presenter" && $("#preconfno").attr("checked") == true) {
    $("#payment").val("none");
    $("#payment").attr({disabled: "disabled"});
  }
  
  // listen for changes in the discount combobox or preconf radio and act accordingly
  // to set focus and disabled states. (No disabling without JavaScript: progressive enhancement.)
  $("#discount").change(function(){
    if ($("#discount").val() == "osustudent" || $("#discount").val() == "facstaff") {
      $("#osuconditional").removeClass("screen-reader-hide");
      $("#osuid").removeAttr("disabled");
    } else {
      $("#osuconditional").addClass("screen-reader-hide");
      $("#osuid").attr({disabled: "disabled"});
    }
    if ($("#discount").val() != "presenter") {
      $("#payment").val("nopay");
      $("#payment").removeAttr("disabled");
    } 
    if ($("#discount").val() == "presenter" && $("#preconfno").attr("checked") == true) {
      $("#payment").val("none");
      $("#payment").attr({disabled: "disabled"});
    }
  });
  
  // reveals or hides message about preconference, using animations
  // if no, make sure message is hidden
  if ( $("#preconfno").attr("checked") ) {
    $("#preconfmessage").hide();
  }
  
  $("#preconfno").click(function() {
    if ( $("#preconfmessage").css("display") == "block") {
      $("#preconfmessage").slideUp("fast");
    }
    if ($("#discount").val() == "presenter") {
      $("#payment").val("none");
      $("#payment").attr({disabled: "disabled"});
      $("#payment").removeClass("error");
    }
  });
  
  $("#preconfyes").click(function() {
    if ( $("#preconfmessage").css("display") == "none") {
      $("#preconfmessage").slideDown("fast");
      $("#preconfmessage").fadeOut("slow");
      $("#preconfmessage").fadeIn("fast");
      $("#preconfmessage").fadeOut("slow");
      $("#preconfmessage").fadeIn("fast");
    }
    $("#payment").val("nopay");
    $("#payment").removeAttr("disabled");
  });
  
});

/*
 * Bit that highlights labels, sub-legends, and fieldset backgrounds
 */
$(document).ready(function(){
  var parents;
  // if an input, textarea, or select gets focus, bold its label and highlight its fieldset
  // using appropriate class, but first remove classes from every other appropriate element
  $("#myform :input").not( $("#myform :submit") ).focus(function() {
    $("label").removeClass("focused");
    $("fieldset").removeClass("focused");
    $("legend").removeClass("focused");
    $(this).parent("label").addClass("focused");
    $(this).prev("label").addClass("focused");
    $(this).parents("fieldset").addClass("focused");
    $(this).parents("fieldset").children("legend").addClass("focused");
  });
 
  // anything checked coming in gets highlighted
  $("#myform :input").each(function() {
    if ( $(this).attr("checked") ) {
      $(this).parent("label").addClass("sticky-focused");
    } else {
      $(this).parent("label").removeClass("sticky-focused");
    }
  });
  
  // fancy way to keep the highlighting on the date of birth label
  // at sign is the attribute selector, which supports very basic regex matching
  $("select[@id^=dob]").focus(function() {
    $("label[@for=dob]").addClass("focused");
  });
  $("select[@id^=dob]").blur(function() {
    $("label[@for=dob]").removeClass("focused");
  });
  
  $("#myform :checkbox").change(function() {
    if ( $(this).attr("checked") ) {
      $(this).parent("label").addClass("sticky-focused");
    } else {
      $(this).parent("label").removeClass("sticky-focused");
      $(this).parent("label").removeClass("focused");
    }
  });
  
  // note: experiment led me here. radios are difficult to work with, this keyword does 
  // not seem to point to the element, as it does with checkboxes
  $("#myform :radio").change(function() {
    if ( $("#preconfyes").attr("checked") ) {
      $("#preconfyes").parent("label").addClass("sticky-focused");
    } else {
      $("#preconfyes").parent("label").removeClass("sticky-focused");
      $("#preconfyes").parent("label").removeClass("focused");
    }
    if ( $("#preconfno").attr("checked") ) {
      $("#preconfno").parent("label").addClass("sticky-focused");
    } else {
      $("#preconfno").parent("label").removeClass("sticky-focused");
      $("#preconfno").parent("label").removeClass("focused");
    }
  });
  

});

/*
 * Bit that handles the validation. Calls on validation_set.js, which contains the 
 * regular expressions for matching and the inline and top error messages
 */
$(document).ready(function() {
  
  /* performs the regular expression check */
  function handleValidity (field) {
    var re = validationSet[field.name]['regex'];
    if (!field.value.match(re)) {
     return field;
    } else {
     return null;
    }
  }
  
   $("#myform").submit(function() {
      /* get a handle to the form */
      frm = document.forms["myform"];
  
      if (!frm) return;
      
      /* holder for the errors at the top of the form */
      var topErrors = new Array();
  
  
      /* loop through the elements in the form */
      for (var i = 0; i < frm.elements.length; i++) {
        if (frm.elements[i].name && validationSet[frm.elements[i].name]) {
  
          /* check if it passes validation, handle to element
             is returned if it fails, null otherwise */
          var failedElem = handleValidity(frm.elements[i]);
  
          /* handle to element in the form where we will
             display a line-level error message */
          var errLabelEm = document.getElementById('error_' + frm.elements[i].name);
         
          /* handle to form element itself and clear its highlight */
          var errInput = document.getElementById(frm.elements[i].name);
          errInput.className = "";
  
          /* empty out the errors EM and hide it */
          if (errLabelEm.childNodes.length > 0) {
            errLabelEm.removeChild(errLabelEm.childNodes[0]);
            errLabelEm.style.visibility = 'hidden';
          }
  
          if (failedElem && errLabelEm) {
            /* get the error messages to display */
            var lineErrMessage = validationSet[failedElem.name]['lineerror'];
            var topErrMessage = validationSet[failedElem.name]['toperror'];
  
            /* push the top error onto the array */
            topErrors.push(topErrMessage);
  
            /* stick the line-error message in the EM of the label
               and make the EM visible */
            var lineErrNode = document.createTextNode(lineErrMessage);
            errLabelEm.appendChild(lineErrNode);
            errLabelEm.style.visibility = 'visible';
            
            /* highlight the input */
            errInput.className = "input-error";
          } 
        } 
      } 
  
      /* handle to the div where we will output our top-of-form error messages */
      if (document.getElementById('errors-container')) {
        var errorsDiv = document.getElementById('errors-container');
        /* make sure div is initially out of sight */
        errorsDiv.style.visibility = 'hidden';
      } else {
        var errorsDiv = null;
      }
  
      /* generate and place the top-of-form error message */
      if (errorsDiv && topErrors.length > 0) {
        /* first clear out the contents */
        if (errorsDiv.childNodes.length > 0) {
          errorsDiv.innerHTML = "";
        }
  
        /* create and place the heading which will take the focus on error */
        var errH3 = document.createElement("h3");
        errH3.setAttribute("id", "errors-heading");
        errAnchor = document.createElement("a");
        errAnchor.setAttribute("href", "#errors-list");
        errAnchor.setAttribute("id", "errors-anchor")
        errAnchorText = document.createTextNode("The form contains the following errors");
        errAnchor.appendChild(errAnchorText);
        errH3.appendChild(errAnchor);
        errorsDiv.appendChild(errH3); 
     
        
        /* create the UL and fill it with the errors accumulated above */
        var errUl = document.createElement('ul');
        errUl.setAttribute("id","errors-list");
        for (var i=0; i<topErrors.length; i++) {
          var errLi = document.createElement('li');
          var errTextNode = document.createTextNode(topErrors[i].toString());
          errLi.appendChild(errTextNode);
          errUl.appendChild(errLi);
        }
  
        /* stick the UL into the div and show it */
        errorsDiv.appendChild(errUl);
        errorsDiv.style.visibility = 'visible';
      }
      
      /* prevent the submit from happening */
      if (topErrors.length > 0) {
        /* accessibility (experimental): force cursor to top-of-form error messages
         * "Errors" message is read by screen reader in: Window Eyes on IE and Firefox 
         * (tested on IE 7 and Fx 2 with W-E 6) and in IE with JAWS. Fx and JAWS: Element
         * gets the focus but is not read until space bar is hit more than once. This
         * appears to be a JAWS rather than Fx problem, since W-E does not have the same
         * problem.
         */
        errAnchor.focus();
        return false;
      }
   });
   
});

