var SL = SL || {};

/**
 * == Core ==
 * 
 * The Core Section contains functionality importent to all other SL-Libs
**/

/** section: Core
 * SL
 * The SL Namespace
**/

/** section: Core
 * SL.Registry
 * 
 * The Registry, where to put settings for the "defered" creation of GUI-Elements
 * 
 * ##### Examples
 * HTML:
 *     <div id="foo">lots of stuff happening here</div>
 *     <script type="text/javascript">
 *         <!-- 
 *              keep your inline js as small as possible
 *              DO NOT make any work in here (like event-registration, dom-manipulation, etc.)! 
 *         -->
 *         SL.Registry.add('sl.startups.fanyFoo', {'target': 'foo', 'lots': {'of': "other cofig"}, 'goes': "in here"});
 *     </script>
 * 
 * JS some_startup.js:
 *     SL.Registry.get('sl.startups.fanyFoo').each(function (setting) {
 *         // split setting into arguments, and/or merge the with a default options object
 *         new FancyFoo(setting);
 *     });
**/
SL.Registry = (function ()
{
	var values = $A([]);
	var keys = $A([]);

	var worker = new Class(
	{
		/**
		 * SL.Registry#add(key, setting)
		 *     - key (String): An identifier for the setting you want to store
		 *     - setting (mixed): Whatever setting you want to store, usually an Object
		**/
		add: function (key, settings)
		{

			var index = null;
			if (0 > (index = keys.indexOf(key)))
			{
				index = keys.length;
				keys.push(key);
				values[index] = [settings];
			}
			else
			{
				values[index].push(settings);
			}
		},
		
		/**
		 * SL.Registry#get(key) -> mixed (Array)
		 *      - key (String)
		 * 
		 * returns all settings stored for that key. if there are none, returns an empty array
		**/
		get: function (key)
		{
			var index = keys.indexOf(key);
			if (0 <= index)
			{
				return values[index];
			}
			return [];
		},
		
		/**
		 * SL.Registry#has(key) -> boolean
		 * 
		 * returns whether there is a setting for the given key
		**/
		has: function (key)
		{
			return (0 <= keys.indexOf(key));
		},
		
		/**
		 * SL.Registry#toHash() -> Hash
		 * 
		 * returns the Mootool-Hash (which is not a real hash) representation of the registry
		**/
		toHash: function ()
		{
			return $H(values.associate(keys));
		},

		/**
		 * SL.Registry#remove() -> mixed (Array)
		 * 
		 * removes and returns the setting for the given key
		**/
		remove: function (key)
		{
			var index = keys.indexOf(key);
            if (0 <= index)
            {
                var ret = values[index];
                values.erase(ret);
                keys.erase(key);
                return ret;
            }

			return [];
		},
		
		/**
		 * SL.Registry#clearNamespace() -> void
		 * 
		 * removes all keys and values in the given namespace
		**/
		clearNamespace: function (namespace)
		{
			var remove = [];
			var exp = new RegExp('^' + namespace.escapeRegExp() + '(\\.|$)');
			keys.each(function(key) {
				if(exp.test(key)) {
					remove.push(key);
				}
			});
			remove.each(function(key) {
				SL.Registry.remove(key);
			});
		}

	});
	
	return new worker();
})();

/** section: Core
 * SL.HistoryManager
 * The instance of, but not yet started [[HistoryManager]]
 * 
 * Shall be started _last_ in the `startups` section
 * 
 * ##### Example
 *     SL.HistoryManager.set('key', 'value');
 *     // or
 *     SL.HistoryManager.set('anEmptyKey');
**/
SL.HistoryManager = new HistoryManager();

