var fade = { // Namespace
    step    : 0.05,
    delay   : 30, // ms
    timer   : null,
    setOpacity : function(elem, nOpacity) {
        if (typeof elem == 'string') elem = document.getElementById(elem);
        var props = ['MozOpacity', 'KhtmlOpacity', 'opacity'];
        for (var i in props) {
            if (typeof elem.style[props[i]] == 'string') {
                elem.style[props[i]] = nOpacity;
                return;
            }
        }
        // IE 6+
        try 
        {
            nOpacity = 100 * parseFloat(nOpacity);
            if ((oAlpha = elem.filters['DXImageTransform.Microsoft.alpha'] || elem.filters.alpha)) 
            {
				oAlpha.opacity = nOpacity;
			}
            else 
            {
				elem.style.filter += "progid:DXImageTransform.Microsoft.Alpha(opacity="+nOpacity+");";
			}
        } 
        catch (e) 
        {
            // IE <= 5.5 OR Opera < 9 OR another browser. Do nothing
        }
    },
    _out : function(id, from, to, callback) {
        from -= this.step;
        from = from <= to ? to : from;
        if (this.doit(id, from, to, callback)) 
            this.timer = setTimeout("fade._out('"+id+"', "+from+", "+to+", '"+(callback ? callback : '')+"')", this.delay);
    },
    _in : function(id, from, to, callback) {
        from += this.step;
        from = from >= to ? to : from;
        if (this.doit(id, from, to, callback)) 
            this.timer = setTimeout("fade._in('"+id+"', "+from+", "+to+", '"+(callback ? callback : '')+"')", this.delay);
    },
    doit : function(id, from, to, callback) {
        this.setOpacity(id, from);
        clearTimeout(this.timer);
        if (from == to) {
            if (callback) eval(callback+'()');
        } else return true;
    }
}
