// Create root object
var Slightly = {};

Slightly.application = Slightly.application || {};

Slightly.application = function()
{
   var release = "1.0";
   var debug = false;
   
   return {

   };
}();

Slightly.util = Slightly.util || {};

Slightly.util = function()
{
   return {

      createId: function()
      {
         return new Date().getTime();
      }

   };
}();

Slightly.resources = Slightly.resources || {};

Slightly.resources = function()
{
   var loadedResources = {};

   return {

      loadStylesheet: function(url, callback, scope)
      {
         var link = document.createElement("link");
         link.rel = "stylesheet";
         link.type = "text/css";
         link.href = url + this._getUrlSuffix();
         if(loadedResources[url] && callback)
         {
            callback.call(scope ? scope : this);
         }
         else
         {
            loadedResources[url] = true;
            this._createNode(link, callback, scope);
         }
      },

      loadScript: function(url, callback, scope)
      {         
         var script = document.createElement("script");
         script.type="text/javascript";         
         script.src = url + this._getUrlSuffix();
         if(loadedResources[url] && callback)
         {
            callback.call(scope ? scope : this);
         }
         else
         {
            loadedResources[url] = true;
            this._createNode(script, callback, scope);
         }
      },

      _getUrlSuffix: function()
      {
         var urlSuffix = "?" + Slightly.application.release;
         if(Slightly.application.debug)
         {
            urlSuffix = "?" + new Date().getTime();
         }
         return urlSuffix;
      },

      _createNode: function(node, callback, scope)
      {
         // Handle Script loading
         if (callback) {
            var done = false;

            // Attach handlers for all browsers
            node.onload = node.onreadystatechange = function(){
               if ( !done && (!this.readyState ||
                              this.readyState == "loaded" || this.readyState == "complete") ) {
                  done = true;
                  callback(scope ? scope : this);
               }
            };
         }

         // Insert the node so it gets loaded
         var head = document.getElementsByTagName("head")[0];
         head.appendChild(node);
      }

   };
}();

Slightly.events = Slightly.events || {};

Slightly.events = function()
{
   var eventListenerMap = {};
   
   return {

      dispatch: function(name, event)
      {
         var listeners = eventListenerMap[name];
         if(listeners)
         {
            for(key in listeners)
            {  
               var listener = listeners[key];
               listener.fn.call(listener.scope ? listener.scope : this, name, event);
            }
         }
      },

      listen: function(name, fn, scope)
      {
         var listeners = eventListenerMap[name];
         if(listeners == null)
         {
            listeners = [];
         }
         eventListenerMap[name] = listeners;
         listeners.push({
            fn: fn,
            scope: scope
         });
      }
      
   };
}();

Slightly.components = function()
{
   var nameComponentMap = {};
   var idComponentMap = {};
   
   return {

      register: function(id, name, component)
      {
         // by name
         var components = nameComponentMap[name];
         if(components == null)
         {
            components = [];
         }
         components.push(component);
         nameComponentMap[name] = components;
         
         // by id
         var c = idComponentMap[id];
         if(c)
         {
            alert("A component has already been registered with id '" + id+ "'");
            return;
         }                  
         idComponentMap[id] = component;
      },

      getById: function(id)
      {
         return idComponentMap[id];
      },

      getByName: function(name)
      {
         var components = nameComponentMap[name];
         return typeof components ? components : [];
      }
      
   };
}();
