/*
Miscellaneous javascript functions organized into classes

Notes:
- consider getting rid of extra useRegExp logic in getElementsByClassName
and just default to using a regular expression
*/

//============== class definition using the dynamic prototype method: BEGIN ==============
function Form(sFormID) { // constructor function
  this.formID = sFormID;

  // define methods only once
  if (typeof Form._initialized == "undefined") {

    // METHOD DEFINITIONS: BEGIN

    //------------ method: begin -----------------------
    Form.prototype.getSelectedCheckBoxValues = function(checkboxGroupName) {
      // Return the values of the checkboxes that are checked as an array
      // Input variable checkboxGroupName can either be the name of a sinlg checkbox 
      // or multiple checkboxes (in which case the checkbox group name should include
      // [] on the end).
      // Return an empty array if none are checked, or
      // there are no checkboxes found.

      var miscutils_l = new MiscUtils(); // local only version of mutils
      var checkboxes = miscutils_l.getElementsByName(checkboxGroupName);
      var checkedValues = new Array();

      if (!checkboxes) return checkedValues;

      var checkboxesLength = checkboxes.length;
      if (checkboxesLength == undefined) { // single checkbox
		if(checkboxes.checked) {
          checkedValues.push(checkboxes.value);
		}
      } else {
        for (var i = 0; i < checkboxesLength; i++) {
          if(checkboxes[i].checked) {
            checkedValues.push(checkboxes[i].value);
          }
        }
      }

      return checkedValues;

    };
    //------------ method: end -----------------------	


    //------------ method: begin -----------------------
    Form.prototype.getCheckedRadioButtonValue = function(radioGroupName) {
      // return the value of the radio button that is checked
      // return an empty string if none are checked, or
      // there are no radio buttons
      var radioObj = eval("document.getElementById(this.formID)." + radioGroupName);

      if (!radioObj) return "";
      var radioLength = radioObj.length;
      if (radioLength == undefined) {
		if(radioObj.checked) {
			return radioObj.value;
		} else {
			return "";
        }
      } else {
        for (var i = 0; i < radioLength; i++) {
          if(radioObj[i].checked) {
            return radioObj[i].value;
          }
        }
      }
      return "";
    };
    //------------ method: end -----------------------	

    //------------ method: begin -----------------------
    Form.prototype.validate = function(fieldID, vtype, customRegExp, required, defaultValue) {
      /*
       all regular expressions, including customRegExp should match from 
       the beginning of the line to the end of the line, i.e., /^expression$/
       if text field or text area, then check if it is non-blank/default value and is required and then validate with regular expression.
       if select, then just check to see if is non-blank/default value and is required
      */

      var field = document.getElementById(fieldID);
      var tagname = field.tagName.toLowerCase();
      var fieldValue = document.getElementById(fieldID).value;

      // if field is nonblank or nondefault value, check to see if required or not
      if ( (tagname == 'input' && field.getAttribute("type").toLowerCase() == 'text') ||
           field.tagName.toLowerCase() == 'textarea' ) {
         if ( MiscUtils.prototype.trim(fieldValue) == '' || fieldValue == defaultValue ) { // blank/default value
           if ( required ) {
             return false;
           } else {
             return true;
           }
         }
      } else if (tagname == 'select') {
         if ( isNaN(defaultValue) ) {
           alert('Form.prototype.validate - ERROR: supplied defaultValue is NaN - contact webmaster');
           return false;
         }
         if ( field.selectedIndex == parseInt(defaultValue) ) { // default value
           if ( required ) {
             return false;
           } else {
             return true;
           }
         } else {
           return true; // if select, then do not continue and validate with regular expression - not needed
         }
      } else {
         alert('Form.prototype.validate - ERROR: unsupported form field specified - contact webmaster');
         return false;
      }

      switch (vtype) {
         case 'name':
            var regExp = /^[a-zA-Z][a-zA-Z0-9 \.\-\'\,]+$/;
            break;
         case 'email':
            var regExp = /^[\w][\w\,\-\.]*\@[\w]+[\w\-\.]*$/;
            break;
         case 'textfield':
            var regExp = /^[a-zA-Z0-9 \.\-:\/\(\)\'\,\;\"_]+$/;
            break;
         case 'textarea':
            //var regExp = new RegExp("/^.*$/s");  // this didn't work, so added hack below
            return true;  // don't bother validating textarea if non-custom regular expression - not trying to untaint input
            break;
         case 'custom':
            eval('var regExp = ' + customRegExp);
            break;
         default:
           alert('Form.prototype.validate - ERROR: unsupported vtype specified - contact webmaster');
           return false;
      }

      // validate text box field value
      if ( fieldValue.search(regExp) == 0 ) { 
        return true; 
      } else { 
        return false; 
      } 
    };
    //------------ method: end -----------------------	

    // METHOD DEFINITIONS: END

    Form._initialized = true;
  }
} 
//============== class definition using the dynamic prototype method: END ==============

//============== class definition using the dynamic prototype method: BEGIN ==============
function MiscUtils() { // constructor function

//  this.formID = sMiscUtilsID;

  // define methods only once
  if (typeof MiscUtils._initialized == "undefined") {

    // METHOD DEFINITIONS: BEGIN

    //------------ method: begin -----------------------
    MiscUtils.prototype.createTextElement = function(tagName, className, idName, text) {
      var container = document.createElement(tagName);
      if (className != '') container.setAttribute("class", className);
      if (idName != '') container.setAttribute("id", idName);
      var textNode = document.createTextNode(text);
      container.appendChild(textNode);
      return container;
    };
    //------------ method: end -----------------------	

    //------------ method: begin -----------------------
    MiscUtils.prototype.trim = function(str) {
      str = str.replace(/^\s+/, '');
      str = str.replace(/\s+$/, '');
      return str;
    };
    //------------ method: end -----------------------	

    //------------ method: begin -----------------------
    MiscUtils.prototype.getElementsByName = function(name) {
      var allElements = document.getElementsByTagName("*");
      var requestedElements = new Array();
      for (var i=0; i < allElements.length; i++) {
        if (allElements[i].getAttribute("name") == name) {
          requestedElements.push(allElements[i]);
        }
      }

      return requestedElements;
    };
    //------------ method: end -----------------------	

    //------------ method: begin -----------------------
    MiscUtils.prototype.getParentByTagName = function() {
      // get arguments
      var child = arguments[0];
      var parentTagName = arguments[1];
      var class_name = null;
      if (arguments[2] != undefined)  class_name = arguments[2];

      // find parent
      var p = child.parentNode;
      if (class_name == null) { // find just by tagName
        while (p) {
          if (p.nodeType == 1) {
            if (p.tagName.toLowerCase() == 'body')  return null;
            if (p.tagName.toLowerCase() == parentTagName)  return p;
          }
          p = p.parentNode;
        }
      } else { // limit to elements with specified tag name AND class name
        classNameRegExp = new RegExp('\s*' + class_name + '\s*');
        if (document.all) { // IE
          while (p) {
            if (p.nodeType == 1) {
              if (p.tagName.toLowerCase() == 'body')  return null;
              if ( p.tagName.toLowerCase() == parentTagName && classNameRegExp.test(p.className) )  return p;
            }
            p = p.parentNode;
          }
        } else { // good browsers
          while (p) {
            if (p.nodeType == 1) {
              if (p.tagName.toLowerCase() == 'body')  return null;
              if (p.tagName.toLowerCase() == parentTagName && classNameRegExp.test(p.getAttribute("class")))  return p;
            }
            p = p.parentNode;
          }
        }
      }

      return null;
    };
    //------------ method: end -----------------------	

    //------------ method: begin -----------------------
    MiscUtils.prototype.getElementsByClassName = function() {
      // get arguments
      var class_name = arguments[0];
      var useRegExp = false;
      if (arguments.length == 2)  useRegExp = arguments[1];

      var classNameRegExp = new RegExp('\s*' + class_name + '\s*');

      var requestedElements = new Array();
      if (document.all) { // IE
        var allElements = document.all;
        if (useRegExp) {
          for (var i=0; i < allElements.length; i++) {
            if ( classNameRegExp.test(allElements[i].className) ) {
              requestedElements.push(allElements[i]);
            }
          }
        } else {
          for (var i=0; i < allElements.length; i++) {
            if (allElements[i].className == class_name) {
              requestedElements.push(allElements[i]);
            }
          }
        }
      } else { // good browsers
        var allElements = document.getElementsByTagName("*");
        if (useRegExp) {
          for (var i=0; i < allElements.length; i++) {
            if ( classNameRegExp.test(allElements[i].getAttribute("class")) ) {
              requestedElements.push(allElements[i]);
            }
          }
        } else {
          for (var i=0; i < allElements.length; i++) {
            if (allElements[i].getAttribute("class") == class_name) {
              requestedElements.push(allElements[i]);
            }
          }
        }
      }
      return requestedElements;    
    };
    //------------ method: end -----------------------	

    //------------ method: begin -----------------------
    MiscUtils.prototype.getParam = function(param) {
      // get the value for the requested GET parameter from the query string
      var rExp = /\?.*$/;
      var queryString = window.top.location.href.substr(window.top.location.href.search(rExp) + 1);
      rExp = /#/;
      var ind = queryString.search(rExp);
      if (ind != -1) {
        queryString = queryString.substr(0, ind);
      }
      var paramStrings = queryString.split('&');
      var keyVal = new Array();
      var paramValue = '';
      for (var i=0; i < paramStrings.length; i++) {
        keyVal = paramStrings[i].split('=');
        if (keyVal[0] == param) {
          paramValue = keyVal[1];
          break;
        }
      }

      return paramValue;
    };
    //------------ method: end -----------------------	

    //------------ method: begin -----------------------
    MiscUtils.prototype.getViewportDimensions = function() {
      /*
      get the width and height of the browser viewport and return as an array:
      array(viewportWidth, viewportHeight)
      */
      var viewportwidth;
      var viewportheight;

      if (typeof window.innerWidth != 'undefined') { // non-IE browsers (firefox, safari, opera ...)
          viewportwidth = window.innerWidth,
          viewportheight = window.innerHeight
      } else if (typeof document.documentElement != 'undefined'
         && typeof document.documentElement.clientWidth !=
         'undefined' && document.documentElement.clientWidth != 0) {// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
           viewportwidth = document.documentElement.clientWidth,
           viewportheight = document.documentElement.clientHeight
      } else { // older versions of IE
           viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
           viewportheight = document.getElementsByTagName('body')[0].clientHeight
      }

      return new Array(viewportwidth,viewportheight);
    };
    //------------ method: end -----------------------	
	
    //------------ method: begin -----------------------
    MiscUtils.prototype.resizeTo100PercentHeight = function(elem) {
      /*
      resize elem to 100% of available height (as defined by parent element).  This is used to fix CSS height 
	  issues/bugs in browsers.
	  This method currently ignores top and bottom padding of the parent - NEED TO FIX THIS.  Use only if parent
	  has zero padding top and bottom.
      */
      var parent;
	  if (elem.parentNode) {
        parent = elem.parentNode;
		var parentHeight = parent.offsetHeight;
		elem.style.height = parentHeight + "px";
	  } 

/*
      if (typeof window.innerWidth != 'undefined') { // non-IE browsers (firefox, safari, opera ...)
          viewportwidth = window.innerWidth,
          viewportheight = window.innerHeight
      } else if (typeof document.documentElement != 'undefined'
         && typeof document.documentElement.clientWidth !=
         'undefined' && document.documentElement.clientWidth != 0) {// IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
           viewportwidth = document.documentElement.clientWidth,
           viewportheight = document.documentElement.clientHeight
      } else { // older versions of IE
           viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
           viewportheight = document.getElementsByTagName('body')[0].clientHeight
      }

      return new Array(viewportwidth,viewportheight);
*/	  
    };
    //------------ method: end -----------------------		

    // METHOD DEFINITIONS: END

    MiscUtils._initialized = true;
  }
}
//============== class definition using the dynamic prototype method: END ==============
