
if(!fw.timer)
fw.timer = function(){
    var out = {};
    for(var i in fw.timer) out[i] = (typeof fw.timer[i]);
    out['version'] = "v0.20";
    return out;
}

fw.timer._handlers = {};
fw.timer._type = 'TIMER';

fw.timer._execute = function(id){
    if(fw.data.isType(id, fw.timer._type)){
        var el = fw.timer._handlers[id];
        
        if(el){
            el.cc++;
            fw.eval._evalNative(el.fn, el.fp);
            if(el.hndl){
                clearTimeout(el.hndl);
                el.hndl = null;
            }
            if((el.cc < el.cl) || (el.cl === true)){
                el.hndl = setTimeout('fw.timer._execute("'+id+'")', el.tm);
            }
        }
    }
}

fw.timer.create = function(fname){
		//alert(fname);	
	
    if(!fw.data.isStr(fname)) return fw.data.error(2);
    
    var id = fw.info.counter(this._type);
    var fparam = fw.data.argm(arguments,1);
    this._handlers[id] = {fn:fname, fp:fparam, tm:50, lv:255, cl:1, cc:0, hndl:null};
    return id;
}

fw.timer.close = function(id, level, curr){
    return fw.timer._close(id, level, curr, true);
}

fw.timer.stop = function(id, level, curr){
    return fw.timer._close(id, level, curr, false);
}

fw.timer._close = function(id, level, curr, cls){
    if(!fw.data.isSet(id)){
        if(!fw.data.isSet(level)) return false;
        for(var i in this._handlers){
            if((curr && this._handlers[i].lv == level) || (!curr && this._handlers[i].lv >= level)){
                clearTimeout(this._handlers[i].hndl);
                if(cls) this._handlers[i] = null;
                else this._handlers[i].hndl = null;
            }
        }
        return true;
    }else{
        if(!fw.data.isType(id, this._type)) return fw.data.error(2);
        if(!this._handlers[id]) return fw.data.error(3);
        
        clearTimeout(this._handlers[id].hndl);
        if(cls){
        	this._handlers[id] = null;
        	this._handlers = fw.data.vacuum(this._handlers);
        }
        else this._handlers[id].hndl = null;
        
        return true;
    }
    return false;
}

fw.timer.start = function(id, to, cycle, level){
    if(!fw.data.isType(id, this._type)) return fw.data.error(2);
    if(!this._handlers[id]) return fw.data.error(3);
    
    with(this._handlers[id]){
        cc = 0;
        if(fw.data.isNum(to)) tm = to;
        if(fw.data.isNum(cycle) || fw.data.isBool(cycle)) cl = cycle;
        if(fw.data.isNum(level)) lv = level;
        if(!this._handlers[id].hndl) hndl = setTimeout('fw.timer._execute("'+id+'")', tm);
    }
    return true;
}

fw.timer.update = function(id){
    if(!fw.data.isType(id, this._type)) return fw.data.error(2);
    if(!this._handlers[id]) return fw.data.error(3);
    
    this._handlers[id].fp = fw.data.argm(arguments,1);
    return true;
}

fw.timer.info = function(id){
    if(!fw.data.isType(id, this._type)) return fw.data.error(2);
    
    var res = {work:null, cycle:null, maximum:null, timeout:null, level:null};
    if(this._handlers[id])
    with(this._handlers[id]){
        res.work = (hndl? true : false);
        res.cycle = cc;
        res.maximum = cl;
        res.timeout = tm;
        res.level = lv;
    }
    return res;
}

fw.timer();