/**
 * Part of JMF Library
 * This file contains base controller class for mvc like programming model
 * @version 0.1b
 * SVN: $Id: base.js 6163 2008-08-14 14:36:31Z mjezierski $
 */

JMF.registerLib('JMF.Controller','$Id: base.js 6163 2008-08-14 14:36:31Z mjezierski $');
JMF.requireLib([
   'JMF.Exception',
   'JMF.Events'
]);
 
/**
 * Controller class
 * @constructor
 * @member JMF.Controller
 */
JMF.Controller = function() {
	this.evHandlers = {};
	this.dbg = JMF._dbg;
};

/**
 * Triggers event processing
 * @member JMF.Controller
 * @param {Mixed} evt Event object or event name. 
 * @param {Object/Optional} evtData If first parameter is evt name, here should be event data
 */
JMF.Controller.prototype.process = function(evt,evtData) {
   if(typeof(evt) === 'string') {
   	evt = JMF.Events.create(evt,evtData);
   }

   this.dbg.flog('{bc:#EFEFEF;}{c:green}{c:blue}{c:green}','Processing &raquo;',evt.type,'&laquo; event');
   
	if(this.evHandlers[evt.type]) {
	  this.dbg.flog('{bc:#EFEFEF;}{c:green}{c:blue}{c:green}','Found: ',this.evHandlers[evt.type].length,' handler(s)');
	  for(var i=0;i<this.evHandlers[evt.type].length;i++) {
	  	this.evHandlers[evt.type][i](evt);
	  	  if(evt.$$stopPropagation) {
	  	  	  break;
	  	  }
	  }	
	} else {
		this.dbg.warn('No handlers found');
	}
};

/**
 * Adds handler to controller
 * @member JMF.Controller
 * @param {String} evtName Event name on behalf of handler will be called
 * @param {Function} handler Event handler
 * NOTE: if there is possibility that event handler will need to be removed it cannot be anonymous function
 */
JMF.Controller.prototype.addHandler = function(evtName,handler) {
   if(typeof(handler) !== 'function') {
   	throw new JMF.Exception(JMF.Exception.EX_INVPARAMS,'Controller handler has to be a function');
   }
   if(!this.evHandlers[evtName]) {
   	this.evHandlers[evtName] = [];
   }	
   this.evHandlers[evtName].push(handler);
};

/**
 * Removes handler from controller
 * @member JMF.Controller
 * @param {String} evtName Event name
 * @param {Function} handler to remove
 */
JMF.Controller.prototype.removeHandler = function(evtName,handler) {
	if(!this.evHandlers[evtName] || typeof(handler) !== 'function') {
		return;
	}
	for(var i=0;i<this.evHandlers[evtName].length;i++) {
	  	if(this.evHandlers[evtName][i].$$GUID === handler.$$GUID) {
	  		this.evHandlers[evtName].splice(i,1);
	  		break;
	  	}
	}
};

/**
 * Calls delayed event processing
 * @member JMF.Controller
 * @param {Mixed} #1 String or Event object
 * @param {Mixed} #2 if type evt is string, then secong parameter should be wevt data, else it should be delay
 * @param {Mixed} #3 delay if first parameter is string
 */
JMF.Controller.prototype.dlProcess = function() {
   var evt = arguments[0];
   var delay; 
   if(typeof(evt) === 'string') {
      var evtData = arguments[1];
      delay = arguments[3] || 0;
      evt = JMF.Events.create(evt,evtData);   	
   } else {
   	delay = arguments[2];
   }

	delay = delay || 0;
	var instance = this;
	setTimeout(function(){instance.process(evt);},delay);
};