/**
 * Akyla 
 *
 * This class handless the loading of headerElements and keeping 
 * project wide settings which should be accessed by widegets.
 * Also a list of predefined modules are present which can be loaded with 
 * a convenience method.
 *
 * Every project should subclass/singletonize this class from a project setting javascript file.
 * An example is :
 * 
 	var Akyla = new (Class.create(Prototype_Akyla,
  	{
		preferences : 
		{
			baseUrl : "/~oz/akylaSubject" // baseUrl of the project
		},
		loadDefaultSettings : function()
		{
			this.setSetting("Akyla.JSON.extendAkylaAjax",true);
		}
	}))();
 */
var Prototype_Akyla = Class.create(
{
	/**
	 * Project wide prefererences : This holds only the baseUrl atm.
	 * TODO : make sure this class gets its baseUrl from the AkylaEngine counterpart from the php
	 * backend
	 */
	preferences : 
	{
		baseUrl : ""
	},
	/**
	 * Constructor
	 *
	 * Sets default settings and loads default modules after calling the function loadDefaultSettings
	 * TODO : build in checks for to be loaded modules by default
	 */
	initialize : function(settings)
	{
		this.Widget = {}; // More widgets will be added. Creating a container here
		this.Form = {};
		if (typeof settings == "undefined")
		{
			settings = {};
		}
		this.settings = new $H({
				"Akyla.Prototype.JSON.extendAkylaAjax" : false,
				"Akyla.Logger.enabled" : true,
				"Akyla.loadSynchronizedJS" : true
			}).merge(settings);
		this.loadDefaultSettings();
		if (this.localization)
		{
			this.injectTranslations(this.localization);
		}
	},
	/**
	 * Loads default project specific settings
	 */
	loadDefaultSettings : function ()
	{
		// Load Default Settings here
	},

	/**
	 * Loads a module from the predefined this.modules variable
	 */
	loadModule : function (module)
	{
		//console.log(module+" loading");
		if (typeof this.modules[module] != "undefined" )
		{
			this.loadHeaderElement(this.modules[module]);
		}
	},
	/**
	 * Sets a project wide setting
	 * @param string name Name of the setting
	 * @param mixed value Value of the setting
	 */
	setSetting : function (name,value)
	{
		this.settings.set(name,value);
	},
	/**
	 * Gets a project wide setting
	 * @param string name Name of the setting
	 * @return mixed Value of the setting
	 */
	getSetting : function (name)
	{
		return this.settings.get(name);
	},
	/**
	 * Checks if a header requirement already exists
	 * @param object headerRequirement Header requirement which needs to be checked
	 * @param HTMLElement header Header of the html document which should be checked
	 * @return boolen True if the headerRequirement alread exists in header, false otherwise
	 */
	isExistingHeaderElement : function(headerRequirement, header)
	{
		var headerTagAttrLookup = {
			"link" : "href",
			"script" : "src"
		};
		var tag = headerRequirement.tag;
		var attribute = headerTagAttrLookup[tag];

		// Doing this here as well as this function can be used seperately from loadHeaderElement
		if (typeof header == "undefined")
		{
			header = $$("head").first();
		}
		if (headerRequirement.tag == "script")
		{
			return (header.select("script[src="+headerRequirement.attributes[attribute]+"]").size() + header.select("script[datasource="+headerRequirement.attributes[attribute]+"]").size()) > 0;
		}
		else
		{
			return header.select("link[href="+headerRequirement.attributes[attribute]+"]").size() > 0;
		}
	},
	/**
	 * Loads a header element into the header
	 * @param object headerRequirement Header requirement which needs to be checked
	 * @param HTMLElement header Header of the html document which should be checked
	 * @uses isExistingHeaderElement
	 */
	loadHeaderElement : function(headerRequirement,header, callback)
	{
		if (typeof header == "undefined")
		{
			header = $$("head").first();
		}
		if (!this.isExistingHeaderElement(headerRequirement,header))
		{
			if (this.getSetting("Akyla.loadSynchronizedJS") && headerRequirement.tag == "script")
			{
				this.loadSynchronizedJS(headerRequirement,header, callback);
			}
			else
			{
				var requirement = new Element(headerRequirement.tag, headerRequirement.attributes);
				$(header).insert({ bottom : requirement});
				if (typeof callback == "function")
				{
					callback();
				}
			}
		}
		else
		{
			if (typeof callback == "function")
			{
				callback();
			}
		}
	},
	loadSynchronizedJS : function(headerRequirement, header, callback)
	{
		if (headerRequirement.tag.toLowerCase() == "script")
		{
			new Ajax.Request(headerRequirement.attributes.src,
				{
					method : "get",
					onSuccess : function (transport)
					{
						var requirement = new Element("script", {type : "text/javascript", dataSource : headerRequirement.attributes.src}).update(transport.responseText);
						if (typeof header == "undefined")
						{
							header = $$("head").first();
						}
						$(header).insert({bottom : requirement});
					},
					onComplete : callback
				});
		}
	},
	/**
	 * Merges translations to the current translations
	 *
	 * @param Object translations Translations to be merged
	 *
	 */
	injectTranslations : function(translations)
	{
		for (locale in translations)
		{
			if (typeof this.localization[locale] == "undefined")
			{
				this.localization[locale] = {};
			}
			for (translation in translations[locale])
			{
				this.localization[locale][translation] = translations[locale][translation];
			}
		}
	},
	/**
	 * Holder for messages to be translated
	 */
	localization : 
	{
	},
	/**
	 * Translates a message from to locale "locale"
	 *
	 * @param string message Message to be translated
	 * @param string locale Locale the message should be translated to
	 */
	translate : function (message, locale)
	{
		if (typeof locale == "undefined")
		{
			locale = Akyla.preferences.localization.locale;
		}
		if (typeof this.localization[locale] == "undefined" || typeof this.localization[locale][message] == "undefined")
		{
			return message;
		}
		else
		{
			return this.localization[locale][message];
		}
	}	
});



