/**
 * message.js v1.0.0, Wed February 21 11:28:05 +0100 2007
 * 
 * Copyright (c) 2007 Christian Schaefer (http://prototyp.ical.ly)
 * 
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 * 
 * For details, see the prototyp.ical.ly blog entry on message.js
 * http://prototyp.ical.ly/index.php/2007/02/21/messaging-object-interaction-on-custom-events
 */

/* setting up namespace for this to avoid clashes */
var ns = window;['ly','ical','prototyp','util'].each(function(p){if(!ns[p])ns[p]={};ns=ns[p]});
/* done */

var __EVENT_CALLBACKS_START__ = '__event_callbacks_start__';
var __EVENT_CALLBACKS_END__ = '__event_callbacks_end__';   

ly.ical.prototyp.util.message = function()
{
  var _callbacks = {
    __EVENT_CALLBACKS_START__:[],
    __EVENT_CALLBACKS_END__:[]
  };   

  var _states = 0;   

  var _loading = function(state)
  {
    if(0 > state) this._states = 0;
    var _event = arguments[1] || false;
    if(_event && _callbacks[_event] && (
      (1 == _states && _event == __EVENT_CALLBACKS_START__) ||
      (!_states && _event == __EVENT_CALLBACKS_END__)))
    {
      _callbacks[_event].each(function(cb){cb.call(this, _event);});
    }
  };

  return {
    send:function(name)
    {
      name = name.toLowerCase();
      _loading(++_states, __EVENT_CALLBACKS_START__);
      var argv = arguments;
      if(_callbacks[name])
      {
        _callbacks[name].each(function(callback)
        {
          _states++;
          if(false !== callback.apply(this, argv)) _states--;
        });
	  }
      _loading(--_states, __EVENT_CALLBACKS_END__);
    },
    responders:{
      register:function(responder)
      {
        Object.keys(responder).each(function(key)
        {
          var name = key.toLowerCase().replace(/^on/,'');
          if(!_callbacks[name]) _callbacks[name] = [];
          _callbacks[name].push(responder[key]);
        });
      },
      unregister:function(responder)
      {
        Object.keys(responder).each(function(key)
        {
          var name = key.toLowerCase().replace(/^on/,'');
          if(!_callbacks[name]) return;
          _callbacks[name] = _callbacks[name].splice(_callbacks[name].indexOf(responder[key]),1);
        });
      },
      end:function()
      {
        _loading(--_states, __EVENT_CALLBACKS_END__);
      }
    }
  };
}();
