/**
 * @author Romain GUILLOT
 * @date 26/07/09
 * @version 0.1
 */

/* global variable named after project  */
var PlemiProject = {}; 

PlemiProject.callbacks = new Array();  // a global array to easier callbacks manipulations

/** 
 * Class callback : manipulates 'persistent' js callback functions (accessible even after page reload)
 */  

PlemiProject.callback = function(event, fn, args)  
{   
    /*this.id = id; @fixme : id feature */
    this.event = event;
    this.fn = fn;
    this.args = args;
      
    PlemiProject.callbacks.push(this);  
    this.init();  
};  

/* Public methods of the 'callback' class */

 PlemiProject.callback.prototype =  
 {  
    /** 
     * Initialization
     */  
    init: function()  
    {   
    	if (!this.fn)
        {
        	plemiLibrary.notify(plemiLibrary.val('err0'), plemiLibrary.val('err1')+'.'+plemiLibrary.val('err3'), plemiLibrary.val('notify_error'));
        	console.info("js error : missing argument fn !");
        	return false;	
        }	       
    	/* args set ? */
        if (this.args)
        {
        	/* yes : we can store the callback as a symfony flash variable : */      	
        	set_flash(this.fn, this.args);
        } else
        {	
        	/* no : we have to catch values from an existent symfony flash var  */
        	this.args = get_flash(this.fn);
        }
        return true;
    },  
    /** 
     * Method set : store new callback as a symfony flash variable
     */  
    set: function()  
    {  
        if (this.checkproperties())
        {	
        	set_flash(this.fn, this.args);
        }	
    },  
     /** 
     * Method checkproperties : check needed properties
     */  
    checkproperties: function()  
    {  
        if (!this.fn)
        {
        	plemiLibrary.notify(plemiLibrary.val('err0'), plemiLibrary.val('err1')+'.'+plemiLibrary.val('err3'), plemiLibrary.val('notify_error'));
        	console.info("js error : missing property fn !");
        	return false;	
        }	
        if (!this.args)
        {
        	plemiLibrary.notify(plemiLibrary.val('err0'), plemiLibrary.val('err1')+'.'+plemiLibrary.val('err3'), plemiLibrary.val('notify_error'));
        	console.info("js error : missing property args !");
        	return false;
        }	
        return true;
    },   
    /** 
     * Execute method : run the callback function (if function exists ...)
     */  
    execute: function()  
    {   
    	var type;
    	eval('type = typeof('+this.fn+')');
        if (this.checkproperties() && (type == 'function'))
        {	
        	var reg = new RegExp('_\!_', "g");
    		eval(this.fn+'('+ this.args.replace(reg, ",")+')');
        }	
		
    }       
    
 };   


PlemiProject.eventcallbacks = new Array();  

/** 
 * Class eventcallback : manage callbacks according to event trigering
 */  

PlemiProject.eventcallback = function()  
{         
    this.ecb = new Array();
    this.jscb = "";
	PlemiProject.eventcallbacks.push(this);  
    this.init();  
}; 

// Méthodes publiques de la classe eventcallback  

 PlemiProject.eventcallback.prototype =  
 {  
    /** 
     * Initialization : catch and parse 'jscallbacks', a 'central' symfony flash variable 
     * that keep the list of callbacks stored as flash variables.
     */  
    init: function()  
    {  
	 	this.jscb = get_flash('jscallbacks');
        if (this.jscb != "")
        {	
	        var tab_ecb = this.jscb.split('_!_'); /* callback string separator */
	        var ecb;
	        /* instantiate every callback */
	        for (var i = 0; tab_ecb[i]; i++) 
	        {   
	        	if (tab_ecb[i] != '')
	        	{	
		        	ecb = tab_ecb[i].split('__'); /* event / function string separator */
		        	if (!this.ecb[ecb[ 0]])
		        	{
		        		this.ecb[ecb[ 0]] = new Array();
		        	}
		        	this.ecb[ecb[ 0]][ecb[ 1]] = new PlemiProject.callback(ecb[ 0], ecb[ 1]);
	        	}	
	        }	 
        }
    },  
    /** 
     * add method 
     */  
    add: function(event, fn, args)  
    {	
    	if (!this.ecb[event])
    	{
    		this.ecb[event] = new Array();
    	}
    	this.ecb[event][fn] = new PlemiProject.callback(event, fn, args);
    	this.jscb = set_flash('jscallbacks', get_flash('jscallbacks') + event + '__' + fn + '_!_');  
    },  
    /** 
     * remove method : remove a callback
     */  
    remove: function(event, fn)
    {
    	if (this.ecb[event] && this.ecb[event][fn])
    	{	
    		delete this.ecb[event][fn];   	
    	}
    	if (this.jscb != "")
    	{
        	var jscb = this.jscb;
        	var reg = new RegExp(event + '__' + fn + '_\!_', "g");
        	jscb = jscb.replace(reg, "");
        	if (jscb != this.jscb)
        	{	
        		this.jscb = set_flash('jscallbacks', jscb);   
    		}
    	}
    },
    /** 
     * cleanup method : remove all callback
     */  
    cleanup: function()
    {
    	for (event in this.ecb)
    	{	
    		for (fn in this.ecb[event])
    		{	
    			delete this.ecb[event][fn];   	
    		}
    	}
    	if (this.jscb != "")
    	{
        	this.jscb = set_flash('jscallbacks', "");   
    	}
    },    
    /** 
     * trigerevent method : triger an event and execute corresponding callbacks
     */  
    trigerevent: function(event)  
    {  
    	var cb;
    	for (cb in this.ecb[event])
    	{
    		this.ecb[event][cb].execute();
    		this.remove(event, this.ecb[event][cb].fn);
    	}
    }    
};  


/* Static methods */  

/** 
 * catch a callback object from his function name :
 */  
PlemiProject.callback.getByFunctionName = function(fn)  
{  
    for (var i = 0; PlemiProject.callbacks[i]; i++)  
    {  
        if (PlemiProject.callbacks[i].fn == fn)  
        {  
            return PlemiProject.callbacks[i];  
        }  
    }  
    return false;  
};  

  
/* Ajax functions */

/** 
 * a generic function to store a js value as a symfony flash variable
 */  
set_flash = function(name, value) {
	var r;
	$.ajax({
	   async: false,		
	   type: 'GET',
	   url: '/fr/ajax/setflash?name='+name+'&value='+value,
	   success: function(isok){
			r = isok;
		   }
     }); /* end of ajax */
	return r;
};

/** 
 * a generic function to get a js value from a symfony flash variable
 */  
get_flash = function(name, del) {
	var r;
	var d = del || "";
	if (d) d = '&del='+d; 
	$.ajax({
	   async: false,	
	   type: 'GET',
	   url: '/fr/ajax/getflash?name='+name+d,
	   success: function(value){
			r =  value;
		   }
     }); /* end of ajax */	
	return r;
};

/* Instantiation */

var myeventcallback = new PlemiProject.eventcallback();



