/*
 * The global loader runs five phases. In each phase, the
 * loader will call the corresponding functions of each
 * listening object. Almost all punt objects are listening.
 * Certainly, any object that sends or receives messages
 * or needs to initialize will want to listen.
 *
 * The five phases are the following:
 *     init()
 *     publishTopic(pubSubMessageSystem)
 *     subscribeToTopics(pubSubMessageSystem)
 *     postMessageSubscriptions()
 *     destroy()
 *
 * The first four run in response to the body's onLoad event
 * and follow the order you see here. The destroy() function
 * runs in response to the body's onUnload event. All objects
 * are required to implement init() and destroy() but the other
 * three are optional.
 *
 * init() is where you initialize whatever you want, except
 * for message-related functionality.
 *
 * publishTopic() is where an object publishes a topic, nothing more.
 *
 * subscribeToTopic() is where an object subscribes to a topic.
 *
 * postMessageSubscriptions() should be used by publishers to
 * send messages to subscribers for initialization.
 *
 * destroy() should be used to destroy and cleanup references
 * for garbage collection.
 */

eds.punt.client.GlobalLoader = function(pubSubMessageSystem) {
	var listeners = new Array();
	var numListeners = 0;

	// All listeners must implement the init() method.
	this.addListener = function(listener) {
		listeners[numListeners] = listener;
		numListeners++;
	}

	this.init = function() {

		for (var index in listeners) {
			if ( ! listeners[index].init ) {
				throw listeners[index] + ' does not implement init()';
			}
			listeners[index].init();
		}

		if ( !pubSubMessageSystem ) {
			return;
		}

		for (var index in listeners) {
			var listener = listeners[index];
			if ( listener.publishTopic ) {
				listener.publishTopic(pubSubMessageSystem);
			}
		}
		for (var index in listeners) {
			var listener = listeners[index];
			if ( listener.subscribeToTopics ) {
				listener.subscribeToTopics(pubSubMessageSystem);
			}
		}
		for (var index in listeners) {
			var listener = listeners[index];
			if ( listener.sendInitialMessages) {
				listener.sendInitialMessages();
			}
		}
		for (var index in listeners) {
			var listener = listeners[index];
			if ( listener.postInitialMessages) {
				listener.postInitialMessages();
			}
		}
	}

	this.destroy = function () {

		var index = (listeners.length - 1);

		pubSubMessageSystem.teardown();

		while ( index >= 0 ) {
			if ( ! listeners[index].destroy ) {
				throw listeners[index] + ' does not implement destroy()';
			}

			listeners[index].destroy();
			index--;

		}

		delete listeners;
	}
}
