/**
 * 	To use the framework, include this file first followed by
 *  all files in <modules> and requred files in <classes>
 * 
 * 	Progressive enhancement is provided for in the 
 *  DisplayManager and UI classes.
 *  
 *  TODO: Move the UI class into an external YAML
 *  
 */


var FJ = {
	
	Modules: {},
	Singletons: {},
	
	// event handlers
	head_loaded: function (event) {
		this._dispatch_event('head_loaded', event);
	},
	
	body_loaded: function (event) {
		this._dispatch_event('body_loaded', event);
	},
	
	window_loaded: function (event) {
		this._dispatch_event('window_loaded', event);
	},
	
	_dispatch_event: function (funcname, event) {
		for (var varName in this) {
			var object = this[varName];
			if (object.instances !== undefined) 
				for (var instanceName in object.instances) {
					var instance = object.instances[instanceName];
					if (instance[funcname] !== undefined)
						instance[funcname](event);
				}
		}
	},
	
	// singleton accessors
	get_singleton: function (p_class_name) {
		for (var _name in this.Singletons)
			if (p_class_name == _name) return this.Singletons[_name];
		return null;
	},
	
	set_singleton: function (p_class_name, p_singleton) {
		var _instance = this.get_singleton(p_class_name);
		if (_instance != null) return _instance;
		this.Singletons[p_class_name] = p_singleton;
		return p_singleton;
	},
	
	// utility
	include_ext_js: function(file) {
		if (document.createElement && document.getElementsByTagName) {
			var head = document.getElementsByTagName('head')[0];
			var script = document.createElement('script');
			script.setAttribute('src', file);
			script.setAttribute('type', 'text/javascript');
			
			head.appendChild(script);
		} else {
			alert('Your browser can\'t deal with the DOM standard. That means it\'s old. Go fix it!');
		}
	}
}

var DEBUG = true;
function log() {
	try {
		// firebug / webkit / fauxconsole
		for (var i = 0; i < log.arguments.length; i++) {
			console.log(log.arguments[i]);
		}
	} catch (error) {}
}

Event.observe(window, 'load', FJ.window_loaded.bind(FJ));