/**
 * Functions used in more than one place in the Signup Wizard
 *
 * Copyright 2004-2005 Google Inc.  All Rights Reserved
 */

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

/**
 * Given an array of DOM ids, this object provides methods to simplify showing
 * only one at a time.
 */
wzShared.viewSwapper = function(ids) {
  if (!ids || !ids.length) {
    throw "Must provide array of dom IDs";
  }
  this.ids = ids;
};

/**
 * Show the element with the given id, and hide all others in this.ids
 */
wzShared.viewSwapper.prototype.showOnly = function(idToShow) {
  for (var i = 0; i < this.ids.length; i++) {
    var id = this.ids[i];
    if (id != idToShow) {
      this.hide(id);
    }
  }
  this.show(idToShow);
}

/**
* Exposes dom element with given id. This convenience method can be applied to
* any id, whether or not it is managed by the receiving swapper, and has no
* effect on any other elements
*/
wzShared.viewSwapper.prototype.show = function(idToShow) {
  var elm = document.getElementById(idToShow);
  elm.style.display = "";
}

/**
* Hides dom element with given id. This convenience method can be applied to
* any id, whether or not it is managed by the receiving swapper, and has no
* effect on any other elements
*/
wzShared.viewSwapper.prototype.hide = function(idToHide) {
  var elm = document.getElementById(idToHide);
  elm.style.display = "none";
}

/**
* Set a timeout to call {@link #wzShared.fixFireFoxFooter} after this
* event loop is over
*/
wzShared.queueFixFireFoxFooter = function() {
  setTimeout(wzShared.fixFireFoxFooter, 100);
}

/**
 * When elements on our pages are shown/hidden, FireFox fails to
 * reposition the footer area. It's related somehow to our use of td's
 * with height 100%. This method fixes that by hiding and showing it.
 */
wzShared.fixFireFoxFooter = function() {
  var footer = document.getElementById("wzFooter");
  footer.style.display="none";
  footer.style.display="";

  // Sometimes shaking the footer still leaves a greate white space
  // at the bottom of the page. In that case, add a <div id=wzFireFoxFix/>
  // element to page, and this function will attempt shake that element
  var fireFoxFix = document.getElementById("wzFireFoxFix");
  if (fireFoxFix) {
    fireFoxFix.style.display="";
    fireFoxFix.style.display="none";
  }
}

wzShared.ltrim = function(s) {
  return s.replace(/^\s+/,'');
}

wzShared.rtrim = function(s) {
  return s.replace(/\s+$/,'');
}

wzShared.trim = function(s) {
  return wzShared.ltrim(wzShared.rtrim(s));
}

wzShared.countDoubleByteChars = function(s) {
  var c = 0;
  for (var i = 0; i < s.length; i++) {
    if (s.charAt(i) > '\u00FF') {
      c++;
    }
  }
  return c;
}

/**
 * Helper function to verify if value,text is present in selected list.
 * This function is used by one2two() for verifying if the value being
 * moved is already present in the destination.
 */
wzShared.checkForPresenceInSelect2 = function(optVal, text, selList) {
  for (i = 0; i < selList.length; i++) {
    if (selList.options[i].value == optVal) return true;
    if (selList.options[i].text == text) return true;
  }
  return false;
}

/**
 * Logic for moving a multi-select from element1 to element2
 */
wzShared.one2two = function() {
  var memberList = gGetElementById('sourceList');
  var selectedList = gGetElementById('destList');
  var len = memberList.length;
  // Ignore any selections that are made to "------"
  for (var i = 0; i < len; ++i) {
    if (memberList.options[i].selected == true) {
      memberList.options[i].selected = false;
      if (memberList.options[i].text.indexOf("-----") == 0) {
        continue;
      }
      if (wzShared.checkForPresenceInSelect2(memberList.options[i].value, memberList.options[i].text, selectedList) == false) {
        selectedList.options[selectedList.length] = new Option(memberList.options[i].text, memberList.options[i].value);
      }
    }
  }
}

/**
 * Removes all selected options from a multi-select element with ID
 * 'destList'. (If that element is ever changed into a single select,
 * this method may unexpectedly delete some non-selected options.)
 */
wzShared.two2one = function() {
  wzShared.removeSelectedFromMultiSelect('destList');
}

/**
 * Removes all selected options from a multi-select element with the
 * given ID.
 */
wzShared.removeSelectedFromMultiSelect = function(elementId) {
  var list = gGetElementById(elementId);
  for (var i = list.length -1; i >= 0; i--) {
    if (list.options[i].selected == true) {
      list.options[i] = null;
    }
  }
}

/**
 * Returns a message with the specified ID.  This ID should refer to a hidden
 * <span> element in the GXP that includes the JavaScript
 *
 * @param msgId DOM Id of a message span
 * @param oSoft optional param to defeat exception thrown if msgId can't be
 * resolved.
 */
wzShared.getMessage = function(msgId, oSoft) {
  var span = document.getElementById(msgId);
  if  (!span && !oSoft) {
    throw 'No message found with id "' + msgId + '"';
  }
  if (!span || !span.firstChild) return "";

  return span.firstChild.data;
}

/**
 * Returns the main form on this wizard page
 */
wzShared.getMainForm = function() {
  return document.getElementById("wzMainForm");
}

/**
 * Given an url, perhaps with query parameters, update or add the
 * named parameter with the given value. Clobbers an existing value.
 * Names and values are properly encoded, so caller should be careful not to
 * do so redundantly.
 *
 * NB--does not yet work properly on URLs that have "#" anchor fragments
 */
wzShared.updateUrlWithParam = function(oldUrl, name, value) {
  value = encodeURIComponent(value);
  name = encodeURIComponent(name);
  var nameValue = name + "=" + value;
  var nameIndex = 0;

  // Split the previous request into url and query params

  var oldUrlAndArgs = oldUrl.split('?');
  var oldUrlBase = oldUrlAndArgs[0];
  var newArgs;

  if (oldUrlAndArgs.length == 1) {
    newArgs = new Array();
  } else {
    // There were some arguments, preserve them

    newArgs = oldUrlAndArgs[1].split('&');

    // Make note of where name was last time, if anywhere

    for (var i = 0; i < newArgs.length; i++) {
      if (newArgs[i].split('=')[0] == name) break;
    }
    // If we didn't find name, i is array length, so
    // we'll wind up appending new nameValue end of the array
    nameIndex = i;
  }

  // Set the value of name in the new query params

  newArgs[nameIndex] = nameValue;

  // Put the new request URL together

  var newUrl = oldUrlBase;

  for (var i = 0; i < newArgs.length; i++) {
    newUrl += ((i == 0) ? '?' : '&');
    newUrl += newArgs[i];
  }

  return newUrl;
};

wzShared.removeElement = function(elm) {
   elm.parentNode.removeChild(elm);  
}

/**
 * Sets the default Submit button for the main form.
 * The default is the last button however, if the element firstButtonDefault
 * is present the first button is set as the default.
 */
wzShared.setDefaultSubmitButtonForForm = function() {
  var firstButtonDefault = document.getElementById("firstButtonDefault");
  if (!firstButtonDefault) {
    AW_formUtil.setDefaultSubmitForFormToLast(wzShared.getMainForm());
  }
}

wzShared.init = function() {
  var add = document.getElementById("wzShared-AddButton");
  if (add) {
    add.onclick = wzShared.one2two;
  }
  var remove = document.getElementById("wzShared-RemoveButton");
  if (remove) {
    remove.onclick = wzShared.two2one;
  }

  wzShared.setDefaultSubmitButtonForForm();
}

AW_Utils.addEvent(window, "onload", wzShared.init);

/**
 * @deprecated Replaced by {@link AW_Utils.addEvent}
 */
function wzAddLoadEvent(func) {
  AW_Utils.addEvent(window, "onload", func);
}

