/*
**    File: fw_mess.js
**    Created by: Zolotarev Anton (http://sourceforge.net/projects/ajaxos)
**
**    License Information:
**    -------------------------------------------------------------------------
**    Copyright (C) 2005 Zolotarev Anton
**
**    This program is free software; you can redistribute it and/or modify it
**    under the terms of the GNU General Public License as published by the
**    Free Software Foundation; either version 2 of the License, or (at your
**    option) any later version.
**    
**    This program is distributed in the hope that it will be useful, but
**    WITHOUT ANY WARRANTY; without even the implied warranty of
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
**    General Public License for more details.
**    
**    You should have received a copy of the GNU General Public License along
**    with this program; if not, write to the Free Software Foundation, Inc.,
**    59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/

if(!fw.mess)
fw.mess = function(){
    var out = {};
    for(var i in fw.mess) out[i] = (typeof fw.mess[i]);
    out['version'] = "v0.33";
    return out;
}

fw.mess._vready = false;
fw.mess._msHndl = [];
fw.mess._messages = [];
fw.mess._msg = {};

fw.mess._msSleepTo = 200;
fw.mess._msWorkTo = 5;
fw.mess._msThread = 0;

fw.mess.startMsg = function(nhread, sys){
    if(!nhread) nhread = 1;
    this._msThread = sys? nhread : 1;
    for(var i=0;i < nhread;i++){
        if(!this._msHndl[i]) this._msHndl[i] = fw.timer.create('fw.mess._message');
        if(!i || sys) fw.timer.start(this._msHndl[i], this._msWorkTo, true, 0);
    }
    return true;
}

fw.mess.stopMsg = function(nhread, sys){
    if(!nhread || (nhread < 0)) nhread = 0;
    if(!nhread && !sys)  nhread = 1;
    var wrk = this._msHndl.length;
    if(nhread > wrk) return fw.data.error(3,'Work Thread')
    for(var i=nhread;i < wrk;i++){
        fw.timer.stop(this._msHndl[i]);
    }
    this._msThread = nhread;
    return true;
}

fw.mess.clearMsg = function(){
    this._messages = [];
}

fw.mess.closeMsg = function(){
    if(!this._msHndl) return fw.data.error(3);
    
    var res =  fw.timer.close(this._msHndl);
    if(!fw.data.isError(res)){
        this._msHndl = null;
        this.clearMsg();
    }
    return res;
}

fw.mess._message = function(){
	
    var msl = this._messages.length;
    var wrk = this._msHndl.length;
    
    if(msl){
        if((msl - 1) > (this._msThread*5)){
            if(this._msThread < wrk) this.startMsg(this._msThread + 1, true);
        }else{
            this.stopMsg(this._msThread - 1);
        }
        
        
        var mes = this._messages.shift();
        
        //fw.debug.trace(this._msThread+'t '+this._messages.length + 'm : ' + mes.m.join('/'));
        do{
            var ptr = fw.data._path(this._msg, mes.m, false);
            if(ptr && ptr['$'])
            for(var func in ptr['$']){
                if(ptr['$'][func]){
                    var arg = fw.data.combine(ptr['$'][func], mes.a);
                    //fw.exec._Exc(func,arg);
                    fw.eval._evalNative(func, arg);
                    
                   
                    
                }
            }
        }while(mes.m.pop());
        
    }else{
	this.stopMsg(1);
    }
}

fw.mess.MsgM = function(mes){
    mes = fw.data.arr(mes);
    var find = null;
    
    if(this._messages.length){
        var msg = mes.join('/');
        for(var i=0;i < this._messages.length;i++){
            if(msg == this._messages[i].m.join('/')){
                find = i;
                break;
            }
        }
    }
    if(find !== null) this._messages[find].a = fw.data.argm(arguments,1);
    else this._Msg(mes, fw.data.argm(arguments,1));
    
    return true;
}

fw.mess.MsgR = function(mes){
    mes = fw.data.arr(mes);
    
    if(this._messages.length){
        var msg = mes.join('/');
        for(var i=0;i < this._messages.length;i++){
            if(msg == this._messages[i].m.join('/')){
                this._messages[i] = {a:[],m:[]};
                break;
            }
        }
    }
    this._Msg(mes, fw.data.argm(arguments,1));
    
    return true;
}

fw.mess.Msg = function(mes){
    return this._Msg(mes, fw.data.argm(arguments,1));
}

fw.mess._Msg = function(mes,atr){
	

    mes = fw.data.arr(mes);
    if(!fw.data.isArr(mes)) return fw.data.error(2);
    if(!fw.data.isArr(atr)) return fw.data.error(2);
    
    
    this._messages.push({m:mes, a:atr});
    
    //alert(atr);
    return true;
}

fw.mess.attMsg = function(mes,func){
    return this._attMsg(mes,func, fw.data.argm(arguments,2));
}

fw.mess._attMsg = function(mes,func,param){
	
				
    mes = fw.data.arr(mes);
    if(!fw.data.isArr(mes)) return fw.data.error(2);
    if(!fw.data.isStr(func)) return fw.data.error(2);
    if(!fw.data.isArr(param)) return fw.data.error(2);
    
    mes.push('$');
    var ptr = fw.data._path(this._msg, mes, true);
    //if(ptr[func]) return fw.data.error(5);
    ptr[func] = param;
    
          
    return true;
}

fw.mess.detMsg = function(mes,func){
    mes = fw.data.arr(mes);
    if(!fw.data.isArr(mes)) return fw.data.error(2);
    if(func && !fw.data.isStr(func)) return fw.data.error(2);
    
    var ptr = fw.data._path(this._msg, mes, false);
    if(ptr){
        if(!func){
            for(var i in ptr) ptr[i] = null;
        }else{
            ptr['$'][func] = null;
        }
        this._vready = true;
    }
    return true;
}

fw.mess.detMsgP = function(pmes){
    if(!fw.data.isStr(pmes)) return fw.data.error(2);
    
    this._detMsgP(pmes, this._msg);
    return true;
}

fw.mess._detMsgP = function(pmes,ptr){
    if(ptr[pmes]){
            ptr[pmes] = null;
            this._vready = true;
   	}
    for(var i in ptr){
        if((i != '$') && fw.data.isObj(ptr[i]))
        this._detMsgP(pmes,ptr[i]);
    }
}

fw.mess.vacuum = function(){
    if(this._vready) this._msg = fw.data.vacuum(this._msg,false,true);
    this._vready = false;
}

fw.mess();