(function() {
	var window = this;

	cllc =
	{
		exists: true, // Indicates that the CLLC core has loaded and is required to use any other module.
		page_is_ready: false, // Will be set to true once all DOM ready events have been logged and executed.
		init: function() {
			// Allow console logging across all browsers
			try { console.log('console ready'); } catch(e) { var console = { log: function() {} }; }
			
			// Initialize the dom_ready queue of functions
			cllc.dom_ready(function() { /* This is a blank call to dom_ready simply to ensure the queue initializes */ });
		},
		
		// function dom_ready
		// Runs the specified function as soon as the DOM is fully rendered in the browser.
		// PARAMS
		//     fn: [required] The function to run. If fn is a string then it will be eval()'ed.
		//     options: [optional] A single variable that will be passed to fn when its run.
		dom_ready: (function() {
			// dom_ready is a closure to prevent access to the queue of operations in flight except through this function. 
			
			// Array of markers, each indicating a function to be run when the DOM is ready.
			var operations_in_flight = [];
			
			// function dom_ready closure
			// The actual function which is publicly accessible.
			// Runs the specified function with optional "options" argument as soon as the browser detects the DOM to be built.
			return function(fn, options) {
				options = options || {}; // Default value for options argument is an empty object

				// If a string is passed in then wrap it in a function which will eval the assumed-valid string.
				if (typeof(fn) == "string") {
					var function_string = fn;
					fn = function() { eval(function_string); };
				}
				
				// Log that there is now a function in the queue.
				operations_in_flight.push(true);
				
				// Bind the function to the queue of functions to be called when the DOM is ready
				jQuery(document).ready(function() {
					fn.call(window, options);
					
					// The function is now done, remove it from the queue
					operations_in_flight.pop();
					
					// If the queue is empty then the page is now settled and ready for anything.
					// Trigger the "settled" event.
					if (operations_in_flight.length == 0
						&& !cllc.page_is_ready) {

						jQuery(document).trigger('settled');
						
						// Mark the page as ready so that any further calls to page_ready fire immediately
						cllc.page_is_ready = true;
					}
				});
			};
		})(),
		
		// function page_ready
		// Runs the specified function as soon as all critical DOM-dependent functions have run.
		// PARAMS
		//     fn: [required] The function to run. If fn is a string then it will be eval()'ed.
		//     options: [optional] A single variable that will be passed to fn when its run.
		page_ready: function(fn, options) {
			options = options || {}; // Default value for options argument is an empty object

			// If a string is passed in then wrap it in a function which will eval the assumed-valid string.
			if (typeof(fn) == "string") {
				var function_string = fn;
				fn = function() { eval(function_string); };
			}

			// If the page is not yet marked as ready for general usage, bind this function for later calling
			if (!cllc.page_is_ready) {
				jQuery(document).bind('settled', function() {
					fn.call(window, options);
				});
			}
			// If the page is ready for general usage, simply call this function immediately
			else {
				fn.call(window, options);
			}
		},
		
		// function standard_error_handler
		// Runs the standard error handler which merely logs errors to the console. Typically called via catch{} blocks.
		// PARAMS
		//     error: [required] The thrown Error() object or a string describing the error
		standard_error_handler: function(error) {
			// If a string was provided, simply log the error string
			if (typeof(error) == "string" || typeof(error) == "STRING") {
				var error_msg = 'error: '+error;
			}
			// If an Error() was thrown, log its name and message.
			// If the browser provides it, also log the file name and line number of the error.
			else {
				var error_msg = "error ("+error.name;
				if (error.lineNumber) {
					error_msg += ", line "+error.lineNumber+", "+error.fileName;
				}
				error_msg += "): "+error.message;
			}
			console.log(error_msg);
		},
		
		// function get_environment
		// Returns the subdomain of the current page in lowercase.
		// PARAMS
		//     treat_dev_as_test: [optional] If set to true then "test" will be returned when on the dev environment
		get_environment: function(treat_dev_as_test) {
			var host = window.location.host.toLowerCase().split('.'),
				environment = host[0];
			
			// Handle "http://brand.com"
			if (environment == cllc.constants.get('brand_id')) {
				environment = "www";
			}
			else if (treat_dev_as_test && environment == "iwov-prod") {
				environment = "test";
			}
			
			return environment;
		},
		// function get_protocol
		// Returns the http protocol of the current page.
		get_protocol: function() {
			var cur_protocol = window.location.protocol;
			return cur_protocol;
		}
	};

	cllc = window.cllc;
})();

cllc.dom_ready(cllc.init);
cllc.dom_ready(getUserData);