// jOanda namespace with common utility methods

var jOanda = (function() {

  var isReady = false;
  var readyBound = false;
  var readyList = [];

  // Private functions
  function onWindowLoad(func) {
    var prev = window.onload;
    window.onload = function() {
      if (prev) {
        prev();
      }
      func();
    };
  }

  function onload(func)  {
    if (window.addEventListener) {
      window.addEventListener("load", func, false);
    } else if (window.attachEvent) {
      window.attachEvent("onload", func);
    } else {
      onWindowLoad(func);
    }
  }

  // Based on jQuery source code from the trunk as of Sep 9, 2009
  function bindReady() {
    if (readyBound) {
      return;
    }
    readyBound = true;

    if (document.readyState === "complete") {
      ready();
      return;
    }
    // Mozilla, Opera and webkit nightlies currently support this event
    if (document.addEventListener) {
      // Use the handy event callback
      document.addEventListener("DOMContentLoaded", function() {
	document.removeEventListener("DOMContentLoaded", arguments.callee,
                                     false);
	ready();
      }, false);

      // If IE event model is used
    } else if (document.attachEvent) {
      // ensure firing before onload,
      // maybe late but safe also for iframes
      document.attachEvent("onreadystatechange", function() {
	if (document.readyState === "complete") {
	  document.detachEvent("onreadystatechange", arguments.callee);
	  ready();
	}
      });

      // If IE and not an iframe
      // continually check to see if the document is ready
      if (document.documentElement.doScroll && window == window.top) {
        (function() {
	  if (isReady) {
	    return;
	  }

	  try {
	    // If IE is used, use the trick by Diego Perini
	    // http://javascript.nwbox.com/IEContentLoaded/
	    document.documentElement.doScroll("left");
	  } catch(error) {
	    setTimeout(arguments.callee, 0);
	    return;
	  }

	  // and execute any waiting functions
	  ready();
	})();
      }
    }
    // A fallback to window.onload, that will always work
    onload(ready);
  }

  function ready() {
    // Make sure that the DOM is not already loaded
    if (!isReady) {
      // Remember that the DOM is ready
      isReady = true;

      // If there are functions bound, to execute
      if (readyList) {
        // Execute all of them
        var fn, i = 0;
        while ((fn = readyList[i++])) {
          fn.call(document);
        }

        // Reset the list of functions
        readyList = null;
      }
    }
  }


  // Public API
  return {
    // Attach a handler to window onload event
    onload: function(func) {
      onload(func);
    },

    // Attach a handler to DOMContentLoaded event
    onready: function(func) {
      // Attach the listeners
      bindReady();

      // If the DOM is already ready
      if (isReady) {
	// Execute the function immediately
	func.call(document);
	// Otherwise, remember the function for later
      } else {
	// Add the function to the wait list
	readyList.push(func);
      }
    }
  };
})();
