/**
 * Lithium Technologies
 * @author: Adam Ayres adam.ayres@lithium.com 
 * @date: 03-21-09
 * 
 * Methods triggered automatically when the DOM has completely loaded.
 */

;(function($LITH) {

$LITH(function() {
	
	/**
	* Hides all elements with the CSS class of LITHIUM.Css.BASE_JS_HIDDEN then removes
	 * the class name. This enables us to then do a Element#show() and Element#hide() as
	 * needed through JS and not have the element intially show up during page load.
	 */
	$LITH("." + LITHIUM.Css.BASE_JS_HIDDEN).hide().removeClass(LITHIUM.Css.BASE_JS_HIDDEN);
	
	/**
	 * Performs the fade effect on all elements with the CSS class of LITHIUM.Css.BASE_EFFECT_HIGHLIGHT_START. 
	 */
	$LITH("." + LITHIUM.Css.BASE_EFFECT_HIGHLIGHT_START).delay(500)
		.switchClass(LITHIUM.Css.BASE_EFFECT_HIGHLIGHT_START, LITHIUM.Css.BASE_EFFECT_HIGHLIGHT_END, 1000);
	
	/**
	 * Special handling for IE for scrolling to an element that has the CSS class 
	 * LITHIUM.Css.BASE_FEEDBACK_SCROLL_TO. This is typically handled using a fragment
	 * ID, however IE strips the request of the fragment ID during redirects. 
	 */
	if ($LITH.browser.msie) { 
		var element = $LITH("a." + LITHIUM.Css.BASE_FEEDBACK_SCROLL_TO).eq(0);
		if (element) {
			var position = element.offset(); 
			window.scrollTo(position.top, position.left);
		}
	}	
	
	/**
	 * Runs all of the functions that have been registered with LITHIUM.Loader.onLoad 
	 * one dom has been loaded as well as all of the common scripts. 
	 */
	 LITHIUM.Loader.setLoaded(); 
	 $LITH.each(LITHIUM.Loader.getOnLoadFunctions(), function(index, func) {
	 	func();
	 });
});

})(LITHIUM.jQuery);

/**
 * Deprecated, please use LITHIUM.Debug instead.  This should
 * only be used in the component classes via the JavaScriptDebugSupport
 * service.
 */
LITHIUM.ArgumentChecks = {
	checkObjectFields: function(obj, fieldToTypeMap) {
		this.checkNotNull(
			'obj', obj,
			'fieldToTypeMap',fieldToTypeMap
		);
		
		var errorBuffer = [];
		
		for(var field in fieldToTypeMap) {
			if(obj[field] === undefined) {
				errorBuffer.push('object is missing the field \'' + field + '\'');
			} else if(!(typeof obj[field] === fieldToTypeMap[field])) {
				var errorMsg = 'object\'s field \'' + field + '\' has incorrect type of \'' + (typeof obj[field]) + '\'; expected type: *' + fieldToTypeMap[field] + '*';
				errorBuffer.push(errorMsg);
			}
		}
		
		if(errorBuffer.length > 0) {
			var msg = 'LITHIUM.ArgumentChecks.checkObjectFields: ' + errorBuffer.join('--');
			throw new Error(msg);
		}
		
	},
	checkNotNull: function(label1, field1) {
		var nullList = [];
		
		if(arguments.length % 2 != 0) {
			throw new Error('LITHIUM.ArgumentChecks.checkNotNull: arguments must be of even length; number of arguments passed-in: ' + argument.length);
		}
		for(var i=0; i < arguments.length; i++) {
			if(arguments[i] === null || arguments[i] === undefined) {
				if(i % 2 == 0) {
					throw new Error('LITHIUM.ArgumentChecks.checkNotNull: Null label at index ' + i);
				} else {
					nullList.push('LITHIUM.ArgumentChecks.checkNotNull: argument *' + arguments[i-1] + '* is null/undefined');
				}
			}
		}
		
		if(nullList.length > 0) {
			throw new Error(nullList.join('--'));
		}
	},
	/* TODO: number of arguments on required methods */
	isImplementor: function(candidate, requiredMethodsArray) {
		var errors = [];
				
		for(var i=0; i < requiredMethodsArray.length; i++) {
			var method = requiredMethodsArray[i];
			if(candidate[method] === undefined) {
				errors.push(method + ' is not defined on candidate object');
			} else if(typeof candidate[method] != 'function') {
				errors.push(method + ' is defined on object but is not a method');
			}
		}
		
		if(errors.length > 0) {
			throw new Error(errors.join('--'));
		}
	}
};