/**
* <b>Includes (+Dependences):</b>
* <code>
*   <script type="text/javascript" src="/_bsJavascript/core/lang/Bs_Misc.lib.js"></script>
* </code>
* 
* <b>How to use:</b>
* include Bs_Misc.lib.js
* include this class
* include/define your class
* then execute: YourClass.inherits(Bs_Eventable);
* 
* <b>How it works:</b>
* 
* <b>Event-Handling</b> (see {@link attachEvent()}):
* - You can attach code or a callback function for certain events onto this component
*   (events are things like onClick, onChange ... aso) See attachEvent() for a list 
*   of supported events and more details.
*
* Snipit 1) Attaching a callback function:
* <code>
*     var myDropDown_1 = new Bs_Dropdown();
*     myDropDown_1.attachEvent('onChange', yourCallbackFunctionName);
* </code>
* The function you pass should be able to receive a object as parameter.
* The object is an instance of this class and allows you to access it the 
* component that triggered the event:
* <code>
*     function yourCallbackFunctionName(componentObj){
*       // do some stuff.
*     }
* </code>
* = = = =<br>
* Snipit 2) Attaching JS code:
* <code>
*     var checkBox = new Bs_Checkbox();
*     checkBox.attachOnClick("yourFunctionName('foo', 'bar'); alert('hello');");
* </code>
*
* @author     andrej arn <andrej-at-blueshoes-dot-org>
* @package    javascript_core
* @subpackage lang
* @copyright  blueshoes.org
*/

function Bs_Eventable() {}

  /**
  * array holding all the information about attached events. 
  * the structure can be like these:
  * <pre>
  * 1) attach a function directly
  *    syntax:  _attachedEvents['eventName'] = yourFunctionName;
  * 2) attach some javascript code
  *    syntax:  _attachedEvents['eventName'] = "yourCode();";
  *    example: _attachedEvents['eventName'] = "alert('hi'); callSomething('foo');";
  *    just keep in mind that you cannot use vars in that code, because when it 
  *    gets executed that will be another scope (unless the vars are global...)
  * 3) attach multiple things for the same event
  *    syntax:  _attachedEvents['eventName']    = new Array;
  *             _attachedEvents['eventName'][0] = yourFunctionName;
  *             _attachedEvents['eventName'][1] = "yourCode();";
  * </pre>
  * 
  * @access private
  * @var    array (hash, see above)
  * @see    attachEvent();
  this._attachedEvents;
  */
	
  /**
  * Attaches an event like onChange, onMouseOver, onClickCaption ... a.s.o.
  * For a list of the supported events check the manual of the subclass.
  * 
  * @access public
  * @param  string trigger (for example 'onChange')
  * @param  mixed A globalFunctionName OR string of javascript to be evaled (using JS's eval())
  * @return void
  * @see    _attachedEvents
  */
	Bs_Eventable.prototype.attachEvent = function(trigger, yourEvent) {
    if (typeof(this._attachedEvents) == 'undefined') {
      this._attachedEvents = new Array();
    }
    
    if (typeof(this._attachedEvents[trigger]) == 'undefined') {
      this._attachedEvents[trigger] = new Array(yourEvent);
    } else {
      this._attachedEvents[trigger][this._attachedEvents[trigger].length] = yourEvent;
    }
  }
	
  /**
  * Tells if an event is attached for the trigger specified. 
  * @access public
  * @param  string trigger
  * @return bool
  */
	Bs_Eventable.prototype.hasEventAttached = function(trigger) {
    return (this._attachedEvents && this._attachedEvents[trigger]);
  }
	
  /**
  * Fires the events for the trigger specified.
  * @access public
  * @param  string trigger (for example 'onClick')
	* @param  mixed param (passed along if specified.)
  * @return bool (false if a registered event returns false, true on all other cases.)
  */
	Bs_Eventable.prototype.fireEvent = function(trigger, param) {
    if (this._attachedEvents && this._attachedEvents[trigger]) {
      var e = this._attachedEvents[trigger];
      if ((typeof(e) == 'string') || (typeof(e) == 'function')) {
        e = new Array(e);
      }
      for (var i=0; i<e.length; i++) {
        if (typeof(e[i]) == 'function') {
					/*for (var i=1; i<arguments.length; i++) {}*/
					if (typeof(param) != 'undefined') {
	          var status = e[i](this, param);
					} else {
	          var status = e[i](this);
					}
        } else if (typeof(e[i]) == 'string') {
          var status = eval(e[i]);
        } //else murphy
				if (status == false) return false;
      }
    }
		return true;
  }



