if(typeof(pengagExternals) == "undefined")
{
	pengagExternals = {};
}

if(typeof(pengag)=="undefined")
{
	pengag = {};
	pengag.basePath = "http://coffee-miles.de/peng/";
	//pengag.basePath = "http://localhost/peng_buchDemo/";
	pengag.standarMajor = 2;
	pengag.standardMinor = 0;
	pengag.standardPrefix = "v2.0";
	pengag.standardSuffix = "-2.0";
	pengag.standardContext = "core20";
	pengag.foundDivs = 0;
	
	// Enable / disable firebug console debug output. 
	pengag.debug = false;
	pengag.warnings = false;
	pengag.errors = false;
	pengag.infos = false;
	
	// Wrapper around console.info for easy disabling / enabling of log messages. 
	pengag.log = function(object)
	{
		if (pengag.debug && window.console && window.console.firebug)
			console.debug(object);
	}
	
	pengag.warn = function(object)
	{
		if (pengag.warnings && window.console && window.console.firebug)
			console.warn(object);
	}
	
	pengag.error = function(object)
	{
		if (pengag.errors && window.console && window.console.firebug)
			console.error(object);
	}
	
	pengag.info = function(object)
	{
		if (pengag.infos && window.console && window.console.firebug)
			console.info(object);
	}
	
	pengag.cloneArray = function(array)
	{
		var newArray = new Array();
		for(var i = 0; i < array.length; i++)
		{
			newArray.push(array[i]);
		}
		return newArray;
	}
	
	/**
	 * tests if the object is defined and creates it with
	 * value. all objects in the chain befor the last object
	 * are created as an empty object.
	 **/
	pengag.createIfNotDefined = function(array, value)
	{
		pengag.log("create if not defined: ");
		pengag.log(array);
		pengag.log(value);
		var objects = pengag.cloneArray(array);
		objects.pop();
		

		while(!pengag.testChainDefined(objects))
		{
			pengag.log("CREATE IF NOT DEFINED: creating empty objects");
			pengag.setAtChainBrocken(objects, new Object());
		}
		
		if(!pengag.testChainDefined(array))
		{
			pengag.log("CREATE IF NOT DEFINED: setting value");
			var created = pengag.setAtChainBroken(array, value);
			pengag.log("CREATE IF NOT DEFINED: new object created");
			pengag.log(created);		
		}
	}
	
	/**
	 * tests like pengag.testChainDefined if the object is defined
	 * and returns the first undefined object in the chain
	 **/
	pengag.chainBrokenAt = function(array)
	{
		pengag.log("test chain broken at: ");
		pengag.log(array);
		var actChain = window;
		for(var i = 0; i < array.length; i++)
		{
			actChain = actChain[array[i]];
			if(typeof(actChain) == "undefined")
			{
				pengag.log(actChain);
				pengag.log("not defined");
			}
			else
			{
				pengag.log(actChain);
				pengag.log("defined");
			}
			if(typeof(actChain) == "undefined")return actChain;
		}
	}
	
	pengag.setAtChainBroken = function(array, value)
	{
		pengag.log("create chain broken at: ");
		pengag.log(array);
		var pref;
		var actChain = window;
		for(var i = 0; i < array.length; i++)
		{
			//we must store the last defined object becaus we lose scope when nect actChain is undefined 
			pref = actChain;
			actChain = actChain[array[i]];
			if(typeof(actChain) == "undefined")
			{
				pengag.log(actChain);
				pengag.log("not defined");
			}
			else
			{
				pengag.log(actChain);
				pengag.log("defined");
			}
			if(typeof(actChain) == "undefined")
			{
				pengag.log("create");
				//add the undefined object to the last defined
				pref[array[i]] = value;
				return pref[array[i]];
			}
		}
	}
	
	/**
	 * tests if the ocjects in the array are all defined as on variable.
	 * beginning at the first element they are concatenated to an object
	 * and tested if they are defined 
	 **/
	pengag.testChainDefined = function(array)
	{
		pengag.log("testing chain: ");
		pengag.log(array);
		var actChain = window;
		for(var i = 0; i < array.length; i++)
		{
			actChain = actChain[array[i]];
			if(typeof(actChain) == "undefined")
			{
				pengag.log(actChain);
				pengag.log("not defined");
			}
			else
			{
				pengag.log(actChain);
				pengag.log("defined");
			}
			if(typeof(actChain) == "undefined")return false;
		}
		return true;
	}
	
	pengag.contains = function (array, value)
	{
		for (var i = 0; i < array.length; i++)
		{
			if(array[i] == value) return true;
		}
		return false;
	}
	
	//needs jquery as $ to load scripts
	pengag.CPendingScriptPool = function ()
	{
		var my = this;
		
		this.pendingScripts = new Array();
		
		this.addScript = function(scriptUrl, undefCheck, callback, args, scope)
		{
			var existent = findScript(scriptUrl);
			if(existent == null)
			{
				pengag.log("script " + scriptUrl + " non-existsent in pool");
				var newScript = new pengag.CPendingScript();
				newScript.scriptUrl = scriptUrl;
				newScript.undefCheck = undefCheck;
				newScript.addCallback(callback, args, scope);
				my.pendingScripts.push(newScript);
				newScript.load();
			}
			else
			{
				pengag.log("script " + scriptUrl + " existsent in pool");
				existent.addCallback(callback, args, scope);
			}
		}
		
		var findScript = function (url)
		{
			for (var i = 0; i < my.pendingScripts.length; i++)
			{
				if(my.pendingScripts[i].scriptUrl == url) return my.pendingScripts[i];
			}
			return null;
		}
	}
	
	pengag.CCallback = function (func, args, scope)
	{
		var my = this;
		
		this.func = func;
		this.args = args;
		this.scope = scope;
		
		this.execute = function ()
		{
			my.func.apply(my.scope, my.args);
		}
	}
	
	pengag.CPendingScript = function ()
	{
		var my = this;
		this.scriptUrl;
		this.undefCheck;
		var callbacks = new Array();
		this.loaded = false;
		
		this.addCallback = function (func, args, scope)
		{
			var newCallback = new pengag.CCallback(func, args, scope);
			if(my.loaded)
			{
				pengag.log("script " + my.scriptUrl + " already loaded -> callback");
				newCallback.execute();
			}
			else
			{
				pengag.log("script " + my.scriptUrl + " got new callback");
				callbacks.push(newCallback);
			}
		}
		
		this.load = function ()
		{
			if(!pengag.testChainDefined(my.undefCheck))
			{
				pengag.log("script " + my.scriptUrl + " not defined -> load");
				$.getScript(my.scriptUrl, function(){onScriptLoaded()});
			}
			else
			{
				pengag.log("script " + my.scriptUrl + " already defined");
				onScriptLoaded();
			}
		}
		
		var onScriptLoaded = function ()
		{
			pengag.log("script " + my.scriptUrl + " loaded");
			my.loaded = true;
			while(callbacks.length > 0)
			{
				callbacks.pop().execute();					
			}
		}
	}
	
	pengag.scriptPool = new pengag.CPendingScriptPool();
	
	pengag.onReadyToParse = function()
	{
		if (typeof(window.swfobject) != "undefined" && typeof(window.swfobject.createSWF) == "undefined")
		{
			throw new Error("Embedded SWFObject is to old. Minimum required: 2.1");
		}
		pengag.scriptPool.addScript(
			"http://ajax.googleapis.com/ajax/libs/swfobject/2.1/swfobject.js", 
			["swfobject"], 
			pengag.parsePage, 
			[], 
			window);
	}
	
	pengag.parsePage = function ()
	{
		//we search all config divs
		$('div.pengConfig').each(
		function (i) 
		{
			var homePath;
			var homePathDiv = $('div.homePath', this).text();
			if(homePathDiv == "")
			{
				homePath = pengag.basePath;
			}
			else
			{
				homePath = homePathDiv;
			}
			var packName = $('div.package', this).text();
			var version = $('div.majorVersion', this).text()+"."+$('div.minorVersion', this).text();
			var versionContext = "v"+$('div.majorVersion', this).text()+$('div.minorVersion', this).text()
			pengag.scriptPool.addScript(
				homePath + "v" + version + "/js/packages/" + packName + "-" + version + ".js",
				["pengag",versionContext,"C"+packName],
				pengag.onPackageLoaded,
				[this, homePath, packName, version, versionContext],
				window);
	    });
	}
	
	pengag.onPackageLoaded = function (configDiv, homePath, packName, version, versionContext)
	{
		var targetContext;
		var targetPrefix;
		var targetSuffix;
		
		//TODO: define optional variable class to make the follwoing reusable
		if(!pengag.testChainDefined(["pengag", versionContext, "C"+packName, "targetContext"]))
		{
			targetContext = pengag.standardContext;
		}
		else
		{
			targetContext = pengag[versionContext]["C"+packName].targetContext;
		}
		if(!pengag.testChainDefined(["pengag", versionContext, "C"+packName, "targetPrefix"]))
		{
			targetPrefix = pengag.standardPrefix;
		}
		else
		{
			targetPrefix = pengag[versionContext]["C"+packName].targetPrefix;
		}
		if(!pengag.testChainDefined(["pengag", versionContext, "C"+packName, "targetSuffix"]))
		{
			targetSuffix = pengag.standardSuffix;
		}
		else
		{
			targetSuffix = pengag[versionContext]["C"+packName].targetSuffix;
		}
		
		pengag.scriptPool.addScript(
			homePath + targetPrefix + "/js/core/peng" + targetSuffix + ".js",
			["pengag", targetContext],
			pengag.instantiateDiv,
			[configDiv, packName, versionContext],
			window);
	}
	
	pengag.instantiateDiv = function(configDiv, packName, versionContext)
	{
		pengag.foundDivs++;
		if($(configDiv).attr("id")=="")
		{
			$(configDiv).attr("id","pengag"+pengag.foundDivs);
		}
		pengag[versionContext]["C"+packName].loadFromPengConfig(configDiv);
	}
	
	pengag.bootLoadFunction = function ()
	{
		if (window.jQuery != null)
		{
			var vt = jQuery.fn.jquery.split(".");
			var vm = "1.0.4".split(".");
			if (vt[0] < vm[0])
			{
				throw new Error("Embedded JQuery is to old. Minimum required: 1.0.4 , got " + jQuery.fn.jquery);
			}
			if (vt[0] == vm[0] && vt[1] < vm[1])
			{
				throw new Error("Embedded JQuery is to old. Minimum required: 1.0.4 , got " + jQuery.fn.jquery);
			}
			if (vt[0] == vm[0] && vt[1] == vm[1] && vt[2] < vm[2])
			{
				throw new Error("Embedded JQuery is to old. Minimum required: 1.0.4 , got " + jQuery.fn.jquery);
			}
			else
			{
				//loaded from head with jquery
				//document.ready can be used
				if(!pengag.testChainDefined(["pengagExternals","embedBoot"]))
				{
					pengag.log("loaded from head with jquery");
					$(document).ready(function(){pengag.onReadyToParse();});
				}
				//loaded from flash with jquery
				//there are no divs, just start to parse, following starters will directly add their divs to Manager
				//starters wich tried too early will be parsed now
				else
				{
					pengag.log("loaded from flash with jquery");
					pengag.onReadyToParse();
				}
			}
		}
		else
		{
			pengag.bootLoadJQuery();
		}
	}
	
	pengag.bootLoadJQuery = function ()
	{
		var head = document.getElementsByTagName("head");
		if (!head || !(head = head[0]))
			throw new Error("Peng: no head tag found on page.");
		
		var script = document.createElement("script");
		head.appendChild(script);
		script.type = "text/javascript";
		script.src = "http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js";
		pengag.waitForJQuery();
	}
	
	pengag.waitForJQuery = function ()
	{
		if(window.jQuery != null)
		{
			pengag.onJQueryLoaded();
		}
		else
		{
			window.setTimeout("pengag.waitForJQuery()", 100);
		}
	}
	
	pengag.onJQueryLoaded = function ()
	{
		//loaded from head without jquery
		//onLoad can be used
		if(!pengag.testChainDefined(["pengagExternals","embedBoot"]))
		{
			pengag.log("loaded from head without jquery");
			var prev_onload = window.onload;
			window.onload = function ()
			{
				if(prev_onload) prev_onload();
				pengag.onReadyToParse();
			}
		}
		//loaded from flash without jquery
		//there are no divs, just start to parse, following starters will directly add their divs to Manager
		//starters wich tried too early will be parsed now
		else
		{
			pengag.log("loaded from flash without jquery");
			pengag.onReadyToParse();
		}
	}
	
	pengag.bootLoadFunction();
}