/* rsn_global2.js
 * global constants and methods for RSN Javascript modules. Some are declared 
 * without "var" to avoid lexical scoping.
 *
 * Version 1.0 - original version
 *
 * Copyright (2007) Research Now Plc
 */

/* whether the user agent is MSIE or not. Ensure MSIE really is MSIE, and not 
 * just Opera reporting itself as such.
 */
isIE = navigator.userAgent.search(/msie/i) >= 0 &&
       navigator.userAgent.search(/opera/i) < 0;

/* a unique and incrementing integer to identify functions registered in 
 * doOnload(), doOnDomLoad() and doOnSubmit() so they execute in the order 
 * in which they were registered
 */
var seed = 0;

/* a collection of function references to invoke when window.onload occurs. 
 * This happens when the HTML DOM and all referenced js, css and image files 
 * have finished downloading. See doOnLoad().
 */
var onLoadHandlers = new Object();

/* a collection of references to functions that will be invoked when the 
 * XHTML DOM is fully loaded. This happens sooner than window.onload as we 
 * don't have to wait for referenced files to finish downloading too - only 
 * the HTML markup. See donOnDomLoad().
 */
var onDomLoadHandlers = new Object();

/* a collection of function references to invoke when the "next" button is 
 * clicked to submit document.ctlform. Each of these functions must return 
 * true or false to indicate whether they're satisfied to allow form 
 * submission to occur.
 */
var onSubmitHandlers = new Object();


/* registers a function to be executed when window.onload occurs
 * 
 * id - a name for the function so it can be subsequently referenced by 
 *      revokeOnLoad(). Will be used as a key in the onLoadHandlers 
 *      collection
 * fn - a reference to the function
 */
function doOnLoad(id, fn) {
  //var key = seed++ + "_" + id;
  //onLoadHandlers[key] = fn;
  onLoadHandlers[id] = fn;
}

/* removes a function so it won't execute when window.onload occurs
 *
 * id - identifies the function as it was registered with doOnLoad()
 */
function revokeOnLoad(id) {
/*
  var keyFinder = new RegExp( "^\\d+_(" + id + ")" );
  for (var key in onLoadHandlers) {
    var matches = keyFinder.exec(key);
    if (matches != null)
      delete onLoadHandlers[key];
  }
*/
  delete onLoadHandlers[id];
}

/* registers a function to be executed when the DOM loads
 * 
 * id - a name for the function so it can be subsequently referenced by 
 *      revokeOnDomLoad(). Will be used as a key in the onDomLoadHandlers 
 *      collection
 * fn - a reference to the function
 */
function doOnDomLoad(id, fn) { onDomLoadHandlers[id] = fn; }

/* removes a function so it won't execute when the DOM loads
 *
 * id - identifies the function as it was registered with doOnDomLoad()
 */
function revokeOnDomLoad(id) { delete onDomLoadHandlers[id]; }


/* registers a function to be called when the "next" button of a survey page 
 * is clicked. This function should return true or false to indicate whether 
 * it's happy to allow form submission to occur.
 *
 * id - a name for the new function so it can be referenced by 
 *      revokeOnSubmit() if necessary
 * fn - a reference to the function
 */
function doOnSubmit(id, fn) { onSubmitHandlers[id] = fn; }

/* removes a submit handler so it won't execute when the "next" button is 
 * clicked
 *
 * id - the id of the handler to remove
 */
function revokeOnSubmit(id) { delete onSubmitHandlers[id]; }


/* executes all the functions stored in onLoadHandlers */
function execLoadHandlers() {
  for (var id in onLoadHandlers) {
//alert("onLoad: about to invoke:" + id);
    try {
      onLoadHandlers[id].apply( null, [] );
    }
    catch (e) { /* suppress */ }
  }
}

/* executes all the functions stored in onDomLoadHandlers */
function execDomLoadHandlers() {
  for (var id in onDomLoadHandlers) {
//alert("DomLoad: about to invoke:" + id);
    try {
//alert(onDomLoadHandlers[id]);
      onDomLoadHandlers[id].apply( null, [] );
    }
    catch (e) { /* suppress */ }
  }
}

/* attaches a global submit ("next" button) handler that runs all the 
 * functions registered via doOnSubmit(). Only if all the registered handlers 
 * return true will this global handler return true (and hence allow form 
 * submission)
 */
function attachGlobalSubmitHandler() {
  document.ctlform.onsubmit = function() {
    var okToSubmit = true;	// begin optimistically
    for (var id in onSubmitHandlers)
      
      // can't use okToSubmit &= ... because it converts lvalue to numeric
      okToSubmit = okToSubmit && onSubmitHandlers[id].apply( null, [] );
    return okToSubmit;
  };
}

// attach "next" handler which trims all text in open-ends on the page
doOnSubmit( "trimOpens", function() { trimOpens(); return true; } );

// attach the global submit handler when the DOM has fully formed
doOnDomLoad( "__attachGlobalSubmit", attachGlobalSubmitHandler );