/**
 * Framework
 * 
 * This file defines very basic functions and variables that are used
 * by all other Javascript files for general packaging and initialization.
 * 
 * NOTICE: Every function in this file has to be usable without any
 * other File loaded (i.e. Prototype). You can also use fallbacks, see
 * addLoadEvent() for an example.
 */

/**
 * Checks value against undefined and empty
 *
 * @author ss
 */
var undef = function(cvar) {
	if(typeof cvar != "undefined" && cvar !== '' && cvar !== null && cvar != false) {
		return false;
	} else {
		return true;
	}
}

/**
 * Works around cross-browser DOM-ready solutions and problems.
 * 
 * @link http://dean.edwards.name/weblog/2006/06/again/#comment86189
 * @author tb
 */
var addLoadEvent = function(lastFunc) {	
	if(addLoadEvent['isReady']) {
		// Document is already loaded, so execute function immediately
		lastFunc();
		return;
	}
	
	// Allows multiple subscriptions to the addLoadEvent
	// 'event handler' by using nested closures. 		
	addLoadEvent['ready'] = (function(priorFunc){
		return function() {
			addLoadEvent['ready'] = function(){};
			if(!arguments.callee.executed) {
				arguments.callee.executed = true; 
				if(priorFunc) priorFunc(); 
				lastFunc();
			}
		}
	})(addLoadEvent['ready']);
	
	// If Prototype is loaded
	if(typeof Prototype != 'undefined') {
		// Use Prototype's dom:loaded implementation
		document.observe('dom:loaded', function() {
			addLoadEvent['isReady'] = true;
			addLoadEvent['ready']();
		});
	} else {
		if(!!(window.attachEvent && !window.opera)) {
			// Support for IE
			var jsOnStatus = "(function(eScript){if(eScript.readyState==='complete'){eScript.parentNode.removeChild(eScript);addLoadEvent.isReady=true;addLoadEvent.ready();}})(this)";
			document.write("<script defer src='//:' onreadystatechange=\""+jsOnStatus+"\"></"+"script>");
		} else {
			// Support for Firefox and Opera 9+
			if(document.addEventListener) document.addEventListener('DOMContentLoaded', function() {
				addLoadEvent['isReady'] = true;
				addLoadEvent['ready']();
			}, false);
			// Support for Safari, KDE and Opera 8.5
			if(/WebKit|Khtml/i.test(navigator.userAgent) || (window.opera && parseInt(window.opera.version()) < 9)) (function(){
				/loaded|complete/.test(document.readyState) ? function() {
					addLoadEvent['isReady'] = true;
					addLoadEvent['ready']();
				} : setTimeout(arguments.callee, 1);
			})(); 	
		}
	}
};

/**
 * Triggers addLoadEvent()'s ready function immediately
 * 
 * @author tb
 */
var triggerDomReady = function() {
	addLoadEvent['isReady'] = true;
	addLoadEvent['ready']();
}

/**
 * Clones a javascript object
 * 
 * @author smo
 * @param  {object} the object that will be cloned
 */
function cloneObject(what) {
    for(var i in what) {
        this[i] = what[i];
    }
}

/**
 * Creates a new package in the defined namespace.
 * 
 * @author tb
 * @param  string   packageNamespace
 * @param  {object} packageObject
 * @param  bool     addConstructAsLoadEvent
 */
var addPackage = function(packageNamespace, packageObject, addConstructAsLoadEvent) {
	var packageNameParts = packageNamespace.split('.');

	// Walk through each but the last package name part
	// and ensure that the corresponding object is initialized
	var parentPackage = window;
	for(var i = 0; i < packageNameParts.length - 1; i++) {
		if(!parentPackage[packageNameParts[i]]) {
			parentPackage[packageNameParts[i]] = {};
		}
		parentPackage = parentPackage[packageNameParts[i]];
	}
	
	// Determine the last package (the one we will fill with
	// functionality)
	var lastPackageNamePart = packageNameParts[packageNameParts.length - 1];
	
	// Check whether it has already been created
	if(!parentPackage[lastPackageNamePart]) {
		// Clone the packageObject
		parentPackage[lastPackageNamePart] = new cloneObject(packageObject);
	}

	if(addConstructAsLoadEvent && typeof parentPackage[lastPackageNamePart].initialize == 'function') {
		// Call the constructor on page load
		addLoadEvent(parentPackage[lastPackageNamePart].initialize);
	}
};

/**
 * Just a dummy function for translation
 *
 * @author ss, tb
 */
var __ = function(str) { return str; };