// Copyright 2005 Google Inc.
// All rights reserved.

/**
 * Functions which may be used by any GXP.  These functions provide several
 * useful utilities for dealing with forms in pages.

 *
 */

/** namespace */
function AW_formUtil(){};

/**
 * For a given form and submit button, this method will set the
 * onKeydown handler for each text field in the form (as well as the
 * form itself) to click the default submit button.
 * This is necessary when there are multiple
 * submit elements on a form, which would otherwise cause the FIRST
 * submit button to get clicked when enter is pressed.
 * If no submitButton is passed, enter key will not do anything
 * (in other words, the default submmit button will not be clicked).
 *
 * @param frm A reference to the form
 * @param opt_submitButton A reference to the intended default submit button
 *        (optional)
 * @throws string exception if parameters are invalid
 */
AW_formUtil.setDefaultSubmitForForm = function (frm, opt_submitButton) {
  if (!frm)
    throw 'frm is a required parameter';
  if (opt_submitButton && opt_submitButton != null &&
      opt_submitButton.type != 'submit' && opt_submitButton.type != 'button')
    throw 'opt_submitButton not of type submit or button';

  // var submitButton = opt_submitButton? opt_submitButton : null;
  var numElements = frm.elements.length;
  for (var i = 0; i < numElements; ++i) {
    var elmType = frm.elements[i].type;
    if (elmType == 'text' || elmType == 'password' ||
        elmType == 'checkbox' || elmType == 'radio') {
      AW_formUtil.setDefaultSubmitForElement(frm.elements[i], opt_submitButton);
    }
  }
}

/**
 * For a given form, this method will set the
 * onKeydown handler for each text field in the form (as well as the
 * form itself) to click the last submit button.
 * This is necessary when there are multiple
 * submit elements on a form, which would otherwise cause the FIRST
 * submit button to get clicked when enter is pressed.
 *
 * @param frm A reference to the form
 * @throws string exception if parameters are invalid
 */
AW_formUtil.setDefaultSubmitForFormToLast = function (frm) {
  var submit = AW_formUtil.getLastSubmitButton(frm);
  if (submit)
    AW_formUtil.setDefaultSubmitForForm(frm, submit);
}

/**
 * Sets an array of input elements whose keydown events should not
 * be subject to special enter key handling. If the listed fields do
 * not catch the enter key themselves, they will cause the usual default
 * submit button to fire, instead of the one set by {@link
 * #setDefaultSubmitForForm} or {@link #setDefaultSubmitForFormToLast}
 *
 * <p>This is an exception mechanism for forms managed by those two methods.
 * It has no effect on forms that have not been handed to one them. However, it
 * is fine to make this call first.
 *
 * To clear the exceptions list, call this method with the fields parameter set
 * to null.
 */
AW_formUtil.setKeydownExceptionsForForm = function(fields, frm) {
  frm._AW_formUtilExceptions = fields;
}

/**
 * Adds keydown exceptions to a form without clobbering any keydown exceptions
 * that were already set on that form.
 */
AW_formUtil.addKeydownExceptionsToForm = function(fields, frm) {
  var oldFields = AW_formUtil.getKeydownExceptionsForForm(frm);
  if (!oldFields) {
    oldFields = new Array();
  }
  for (var i in fields) {
    oldFields.push(fields[i]);
  }
  AW_formUtil.setKeydownExceptionsForForm(oldFields, frm);
}

/**
* Returns the exceptions list set by {@link #setKeydownExceptionsForForm},
* or null if none has been set.
*/
AW_formUtil.getKeydownExceptionsForForm = function(frm) {
  if (frm._AW_formUtilExceptions) {
    return frm._AW_formUtilExceptions;
  }
  return null;
}

/**
 * Gets the last submit button on a given form.
 *
 * @param frm A reference to the form
 * @throws string exception if parameters are invalid
 */
AW_formUtil.getLastSubmitButton = function (frm) {
  if (!frm)
    throw 'frm is a required parameter';

  for (var i = frm.elements.length - 1; i >= 0; i--) {
    var elm = frm.elements[i];
    if (elm.type == 'submit')
      return elm;
  }
}

/**
 * Given a single form element of type text and a button element
 * of type button or submit, will set the onKeydown handler to click
 * the button when the enter key is pressed.  If there is an existing
 * onKeydown handler, that handler will be retained and called before
 * the submit is clicked.
 *
 * @param frm A reference to the form field element
 * @param opt_submitButton A reference to the intended default submit button
 *        (optional)
 * @throws string exception if parameters are invalid
 */
AW_formUtil.setDefaultSubmitForElement = function(formElement, opt_submitButton) {
  if (!formElement)
    throw 'formElement is a required parameter';
  if (opt_submitButton && opt_submitButton != null &&
      opt_submitButton.type != 'submit' && opt_submitButton.type != 'button')
    throw 'opt_submitButton not of type submit or button';
  AW_Utils.addEvent(formElement, 'onkeydown',
      AW_formUtil.defaultSubmitOnKeydown(opt_submitButton));
}

/**
 * Given a submitButton, returns an onkeydown handler that will click
 * the submitButton when the pressed key is enter, if the receiver is not
 * in its form's exception list.
 *
 * If no submitButton is passed, enter key will not do anything
 * (in other words, the default submmit button will not be clicked).
 *
 * @see #setKeydownExceptionsForForm
 */
AW_formUtil.defaultSubmitOnKeydown = function (opt_submitButton) {
  return function(evt) {
    var e = evt ? evt : event;
    if ((e.keyCode != 13) && (e.keyCode != 3)) {
      return true;
    }

    // In IE we need to use "e.srcElement" rather than "this"
    var srcElement = e.srcElement ? e.srcElement : this;
    var f = srcElement.form;

    if (f) {
      var exceptions = AW_formUtil.getKeydownExceptionsForForm(f);
      if (exceptions) {
        for (var i = 0; i < exceptions.length; i++) {
          if (srcElement == exceptions[i]) {
            return true;
          }
        }
      }
    }

    if (opt_submitButton) {
      opt_submitButton.click();
    }

    return false;
  }
}

/**
* Clears all text and password input fields in a given form.
*/
AW_formUtil.clearTextInputFields = function(frm) {
  if (frm) {
    var frmElements = frm.elements;
    for (var i = 0; i < frmElements.length; ++i) {
      var element = frmElements[i];
      if (element.type == "text" || element.type == "password") {
        element.value = "";
      }
    }
  }
}

