var _j={};

_j._construct=function()
{
    function UIObject(definition)
    {
        this.listeners=[];
        this.children=[];
        this.parent=null;
        this.def=definition;
        // Problemas de cluttering de namespace.
        this.curState=null;
        this.curTimeLine=null;
        var curNode;
        for(k in definition.nodes)    
        {        
            curNode=document.getElementById(definition.nodes[k]);
            this[k]=curNode;
            curNode.ui=this;
        }
        var defState=null;
        
        for(k in definition.states)
        {
            if(defState==null)defState=k;
            if(definition.states[k]._default)
            {
                this.setState(k,false);
                return;
            }
        }
        
        if(defState)this.setState(k,false);        
        
    };
    

    UIObject.prototype.setState=function(stateName,animate)
    {
        
        var k;
        if(this.def.states[stateName])
        {
            if(this.state && this.state != stateName && this.def.states[this.state].classes)
            {
                var curNode;
                var cS=this.def.states[this.state].classes;
                var oldCa;
                var j;
                for(k in cS)
                {
                    oldCa=cS[k].split(" ");
                    for(j=0;j<oldCa.length;j++)
                    {
                        ADS.removeClassName(this[k],oldCa[j]);
                    }
                    
                }
            }
            var oldState=this.state;
            this.state=stateName;
            this.curState=this.def.states[stateName];
            this.fire("changeState",{state:stateName,src:this,prevState:oldState});
            if(this.curState.events)
            {
                if(this.curState.events.onEnterState)this.curState.events.onEnterState(stateName);
            }
            
            if(this.curState.classes)
            {                
                var curNode;
                for(k in this.def.nodes)
                {
                    if(this[k].oldClasses)
                        this[k].className=this[k].oldClasses;
                    if(this.curState.classes[k])
                    {
                        this[k].oldClasses=this[k].className;
                        this[k].className+=' '+this.curState.classes[k];
                    }                    
                }
            }
            
            if(this.curState.nodeEvents)
            {
                
                var curUI=this;
                for(k in this.curState.nodeEvents)
                {
                    curNode=k;
                    var j;
                    var curEvents=this.curState.nodeEvents[k];
                    
                    for(j in curEvents)
                        this[k]["on"+j]=function(){curEvents[j].apply(curUI,arguments)};
                }
            }
            
            if(this.curState.frames && animate)
            {
                this.curTimeLine=new _j.TimeLine({nodes:this,frames:this.curState.frames});
                this.curTimeLine.start();
            }

        }
    };
    UIObject.prototype.addChild=function(uiobj)
    {
        uiobj.parent=this;
        this.children.push(uiobj);
    };
    UIObject.prototype.bubble=function(evt,params)
    {
        
        if(this.parent)
        {
            this.parent.receiveEvent(evt,params);
        }
    };
    UIObject.prototype.receiveEvent=function(evt,params)
    {
        if(this.curState && this.curState.events && this.curState.events[evt])
        {

            this.curState.events[evt].apply(this,arguments);
            return;
        }
        if(this.def.events && this.def.events[evt])
            this.def.events[evt].apply(this,arguments);
    };
    UIObject.prototype.cascade=function(evt,params)
    {
        var k;
        for(k=0;k<this.children.length;k++)
        {
            
            this.children[k].receiveEvent(evt,params);
        }
    }

    

    UIObject.prototype.fire=function(evtName,params)
    {
        if(this.listeners[evtName])
        {
            var curListener;
            for(var k=0;k<this.listeners[evtName].length;k++)
            {
                curListener=this.listeners[evtName][k];
                curListener.callback(this,curListener.params);
                
            }

        }
    }
       
    function TimeLine(definition)
    {
        this.currentIndex=0;
        this.maxIndex=0;
        this.def=definition;
        this.minFrame=this.def.frames[0].time;
        this.maxIndex=this.def.frames.length-1;
        this.maxFrame=this.def.frames[this.maxIndex].time;

        this.start=function()
        {
            this.anim={running:1};
            AnimationManager.add(this,this.anim);
        };

        this.tick=function(frame,anim)
        {        
            
            while(frame > this.def.frames[this.currentIndex].time && this.currentIndex<=this.maxIndex)
            {
                
                if(this.def.frames[this.currentIndex].anims)
                {
                    for(var k=0;k<this.def.frames[this.currentIndex].anims.length;k++)
                    {
                        var curAnim=this.def.frames[this.currentIndex].anims[k].anim;
                        var node=this.def["nodes"][this.def.frames[this.currentIndex].anims[k].node];
                        setupAnimation(node);
                        var tm=getStockAnimation(curAnim.type,curAnim.start,curAnim.end,curAnim.duration);
                        var a={property:curAnim.property,frames:tm};
                        if(curAnim.units){a.units=curAnim.units};
                        node.addAnimation(a);
                    }
                }
                if(this.def.frames[this.currentIndex].callback)
                {
                    this.def.frames[this.currentIndex].callback();
                }
                if(this.currentIndex==this.maxIndex)
                {
                    
                    anim.finished=true;
                    return;
                }

                this.currentIndex++;   
            }
        }
    
    }
    
    this.TimeLine=TimeLine;

    this.UIObject=UIObject;
}

_j.animations={
                    grayIn:{"type":"floatEase2","start":100,"end":50,"duration":.75,"property":"opacity"},
                    grayOut:{"type":"floatEase2","start":50,"end":100,"duration":.75,"property":"opacity"},
                    longFadeIn:{"type":"floatEase2","start":0,"end":100,"duration":.75,"property":"opacity"},
                    longFadeOut:{"type":"floatEase2","start":100,"end":0,"duration":.75,"property":"opacity"},
                    shortFadeIn:{"type":"floatEase2","start":0,"end":100,"duration":.25,"property":"opacity"},
                    widthIn:{"type":"floatEase2","start":0,"end":350,"duration":0.25,"property":"width","units":"px"},
                    heightIn:{"type":"floatEase2","start":20,"end":290,"duration":0.25,"property":"height","units":"px"},
                    slightMove:{"type":"floatEase2","start":0,"end":40,duration:.5,property:"marginLeft","units":"px"}
              };       
_j.Containers={
    create_structure:function(str,targets)
    {
        if(str.tag.indexOf('#')==0)
        {
            var newTargets={};
            var el=_j.Containers.create_structure(_j.Containers[str.tag.substr(1)],newTargets);
            for(var k in str.map)targets[k]=newTargets[map[k]];
        }
        else
            var el=document.createElement(str.tag);

        if(str.returnAs)
        {
            targets[str.returnAs]=el;
            if(!el.attrs && !el.attrs.className)
                el.className=str.returnAs;
        }

        var k;
        if(str.attrs)
        {
            for(k in str.attrs)
                el[k]=str.attrs[k];
        }
        if(str.children)
        {
            for(k=0;k<str.children.length;k++)
            {
                el.appendChild(_j.Containers.create_structure(str.children[k],targets));
            }
        }
        return el;
    },

    create:function(name)
    {
        var obj={}
        var e=create_structure(name,obj);
        obj._root=e;
        return obj;
    }
};


Array.prototype.map=function(f){for(var k=0;k<this.length;k++) f(this[k]);};

_j._construct();

