/**
	@name rio
	@namespace
	
	The rio namespace is the root of the entire framework, through which you can access all of the classes and 
	namespaces.
	
	<br />
	
	<h2>Namespaces</h2>
	
	<ul>
		<li>apps - contains instances of rio.Application</li>
		<li>components - contains instances of rio.Component</li>
		<li>models - contains instances of rio.Model</li>
		<li>pages - contains instances of rio.Page</li>
		<li>environment - configuration for the current environment</li>
		<li>environments - configurations varying by environment</li>
		<li>console - stuff related to the development console</li>
		<li>boot - configuration related to the application boot process</li>
	</ul>
	
	<h2>Classes</h2>
	
	<ul>
		<li>AIM - manages AJAX file uploads</li>
		<li>Application - root of application instances</li>
		<li>Attr - root of most rio classes (Application, Component, Model, Page)</li>
		<li>Binding - represents a bindable attribute</li>
		<li>Tag - a collection of methods for building HTML tags</li>
		<li>Utils - a collection of random helper methods</li>
	</ul>
	
	<h2>Methods</h2>
	<ul>
		<li>log - adds a log message to the rio console</li>
	</ul>
	
	<h2>Fields</h2>
	<ul>
		<li>app - the currently running application instance</li>
	</ul>

	@author Jason Tillery
	@copyright 2008-2009 Thinklink LLC
*/
var w = window;
(function() {
	if (!window.console) { window.console = { log: alert }; }
	
	var initialWindowKeys = Object.keys(window);
	
	var bootOptions = window.bootOptions || {};

	Object.extend(rio, {
		components: {},
		models: {},
		apps: {},
		pages: {},
		console: {},
		themes: {},
		log: Prototype.emptyFunction,
		boot: {
			root: "/javascripts/",
			appRoot: bootOptions.appRoot || "",
			rioPath: bootOptions.rioPath || "lib/",
			prototypePath: bootOptions.prototypePath || "prototype/",
			prototypePollution: [
				"$", "$$", "$A", "$F", "$H", "$R", "$break", "$continue", "$w", "_eventID", "Abstract", "Ajax", "Autocompleter", "Builder", "Class", "Draggable", "Draggables", "Droppables", "Effect", "Element", "Enumerable", "Field", "Form", "Hash", "Insertion", "ObjectRange", "PeriodicalExecuter", "Position", "Prototype", "Selector", "Sortable", "SortableObserver", "Template", "Toggle", "Try"
			],
			googleAnalyticsPollution: ["gaGlobal", "gaJsHost", "_gat", "pageTracker"],
			noConsole: bootOptions.noConsole,
			initialWindowKeys: initialWindowKeys
		}
	});

	$$("script").each(function(script) {
		var src = script.src;
		if(src.match(/boot\.js/) && src.indexOf('?') != -1) {
			var options = src.split('?')[1].split(',');
			if (options.length >= 1) { rio.boot.appName = options[0]; }
			if (options.length >= 2) { rio.boot.environment = options[1]; }
			if (options.length >= 3) { rio.boot.bootCompressed = (options[2] == "compressed"); }
		}
	});
	
	Object.extend(rio.environment, rio.environments[rio.boot.environment]);
	Object.extend(rio.boot, rio.environment.boot);

	if (bootOptions.noConsole === undefined) {
		rio.boot.noConsole = (rio.environment.console == undefined) ? false : !rio.environment.console;
	}
	
	rio.boot.loadedFiles = [];
	rio.require = function(fileName, force) {
		if (!rio.boot.loadedFiles.include(fileName)) {
			if (rio.boot.bootCompressed && force) {
				rio.boot.loadedFiles.push(fileName);
				document.write('<script type="text/javascript" src="' + rio.boot.root + fileName + '.js"></script>');
			} else if (!rio.boot.bootCompressed) {
				rio.boot.loadedFiles.push(fileName);
				var path = rio.boot.root + fileName + ".js";
				new Ajax.Request(path + "?" + Math.random(), {
					asynchronous: false,
					method: "get",
					evalJSON: false,
					evalJS: false,
					onSuccess: function(response) {
						try {
							w.eval(response.responseText);
						} catch(e) {
							console.log(Object.toJSON(e));
						}
					},
					onFailure: function() {
						alert("Failed loading file: " + path);
					}
				});
			}
		}
	};
	rio.boot.loadFiles = function(fileNames, force) {
		fileNames.each(function(f) { 
			rio.require(f, force);
		});
	};

	rio.boot.prototypeScripts = [
		rio.boot.prototypePath + "effects",
		rio.boot.prototypePath + "dragdrop",
		rio.boot.prototypePath + "controls",
		rio.boot.prototypePath + "builder"
	];
	rio.boot.rioScripts = [
		rio.boot.rioPath + "protohack",
		rio.boot.rioPath + "spec",
		rio.boot.rioPath + "cookie",
		rio.boot.rioPath + "file",
		rio.boot.rioPath + "event.simulate",
		rio.boot.rioPath + "tag",
		rio.boot.rioPath + "utils", 
		rio.boot.rioPath + "rsh",
		rio.boot.rioPath + "swfobject",
		rio.boot.rioPath + "juggernaut",
		rio.boot.rioPath + "ajax_file_upload",
		rio.boot.rioPath + "delayed_task", 
		rio.boot.rioPath + "layout_manager", 
		rio.boot.rioPath + "attr",
		rio.boot.rioPath + "benchmark",
		rio.boot.rioPath + "parameters",
		rio.boot.rioPath + "collection_entity",
		rio.boot.rioPath + "form",
		rio.boot.rioPath + "id", 
		rio.boot.rioPath + "model", 
		rio.boot.rioPath + "theme",
		rio.boot.rioPath + "component", 
		rio.boot.rioPath + "../components/base",
		rio.boot.rioPath + "template",
		rio.boot.rioPath + "js_template",
		rio.boot.rioPath + "page", 
		rio.boot.rioPath + "application",
		rio.boot.rioPath + "console"
	];
	rio.boot.loadFiles(rio.boot.prototypeScripts, true);

	if (rio.boot.bootCompressed) {
		rio.require(rio.boot.rioPath + "compressed/rio", true);
		if (rio.boot.environment == "development") { 
			rio.require(rio.boot.rioPath + "spec", true);
			rio.require(rio.boot.rioPath + "benchmark", true);
			rio.require(rio.boot.rioPath + "event.simulate", true);
			rio.require(rio.boot.rioPath + "console", true); 
		}
		rio.require(rio.boot.appRoot + "apps/compressed/" + rio.boot.appName, true);
	} else {
		rio.boot.loadFiles(rio.boot.rioScripts);

		rio.require(rio.boot.appRoot + "apps/" + rio.boot.appName);
	};
	
	if (rio.environment.supportSelenium) {
		rio.require(rio.boot.rioPath + "seleniumExtensions", true);
	}
	
	Event.observe(window, 'load', function() {
		window.initialOptions = window.initialOptions || {};
		// rio.boot.finalWindowKeys = Object.keys(window);
		// rio.boot.pollution = rio.boot.finalWindowKeys.reject(function(key) {
		// 	return $A(rio.boot.initialWindowKeys).include(key) || 
		// 		$A(rio.boot.prototypePollution).include(key) || 
		// 		$A(rio.boot.googleAnalyticsPollution).include(key);
		// }.bind(this));
		// rio.log("Window is tainted by - " + rio.boot.pollution.size() + " - entries.");
		// rio.boot.pollution.each(function(key) {
		// 	rio.log(key);
		// });
		rio.app = new rio.apps[rio.boot.appName](initialOptions);
		rio.app.launch();
	}.bind(this));
})();
