function __create_structure(str,targets)
    {
        
        var el=document.createElement(str.tag);
        if(str.returnAs)
        {
            targets[str.returnAs]=el;
        }
        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(this.__create_structure(str.children[k],targets));
            }
        }
        return el;
    }


function disableSelection(target){ 
 
if (typeof target.onselectstart!="undefined") //IE route 
 
    target.onselectstart=function(){return false} 
 
else if (typeof target.style.MozUserSelect!="undefined") //Firefox route 
 
    target.style.MozUserSelect="none" 
 
else //All other route (ie: Opera) 
 
    target.onmousedown=function(){return false} 
    target.style.cursor = "default" 
 
} 



function animationTick()
{
    var nAnims=AnimationManager.animations.length;
    var k=0;
    var allNull=true;
    var curAnim;
    for(k=0;k<AnimationManager.animations.length;k++) 
    {
        curAnim=AnimationManager.animations[k];
        
        if(curAnim.node!=null) {
            
            if(curAnim.anim.running==1) {
                curAnim.node.tick((new Date().getTime()-curAnim.node._timeReference)/1000,curAnim.anim);
            }
            else
            {
                curAnim.node._runAnimation(curAnim.anim);
            }

                if(curAnim.anim.finished)
                {                    
                    curAnim.node=null;
                    if(curAnim.anim.onEndCallback)
                         curAnim.anim.onEndCallback();
                }
                else
                    allNull=false;
            
        }
    }
    if(allNull) {
        
        AnimationManager.animations=[];              
        AnimationManager.runningTimer=false;
        return;
    }
    setTimeout(animationTick,25);
}

var AnimationManager={
    runningTimer:false,
    animations:[],
    add:function(node,anim)
    {
        if(anim.running==1) { // Es una timeline
            var AnimationTimer=new Date();
            node._timeReference=AnimationTimer.getTime();
        }
        this.animations.push({node:node,anim:anim});
        if(this.runningTimer==false) {
            this.runningTimer=true;
            
            animationTick();
        }
    }
    

}


function setupAnimation(node)
{

    if(node.animation)
        return;
    node.nAnimations=0;
    node.animation={};
    node.hasAnimations=function(){
        return this.nAnimations>0;
    }
    node.setStyle=function(style,value,units){
       
        switch(style)
        {

            case 'opacity':
            {

                this.style.opacity=value/100;
                    this.style.MozOpacity=value/100;
                    if(this.filters)
                    {   
                        this.style.filter='alpha(opacity = '+value+')';
                    }
            }break;
        case 'width':
        case 'height':
            {
                if(value<0 || value==NaN)
                    value=0;
                this.style[style]=''+Math.floor(value)+(units?units:'');


            }break;
        case 'left':
        case 'top':
        
        {            
            this.style[style]=''+Math.floor(value)+(units?units:'');

        }break;

            default:
            {                
                this.style[style]=''+value+(units?units:'');
                
            }
        }
    
    };
    node.runAnimation=function(animObj)
    {
        AnimationManager.add(this,animObj);
    };

    node._runAnimation=function(animObj){
        var c=new Date();
        var elapsed=c.getTime()-animObj.startTime;
        while(animObj.currentIndex < (animObj.nSpecFrames-1) &&
              animObj.frames[animObj.currentIndex+1].f<elapsed) {
            animObj.currentIndex++;
        }
        
                            if(animObj.currentIndex == animObj.nSpecFrames-1)
                            {
                                animObj.finished=true;
                                //document.getElementById("debug").innerHTML+=("<br>"+animObj.frames[animObj.currentIndex-1].v);
                                animObj.node.setStyle(animObj.property,animObj.frames[animObj.currentIndex].v,animObj.units);                                
                                return;
                            }

                            /*if(animObj.callbacks[animObj.curFrame])
                            {
                                animObj.callbacks[animObj.curFrame]();
                            } */

                            var i=animObj.currentIndex;                            

                            var x=elapsed;
                            
                            var t=animObj.t;
                            var y=animObj.y;
                            var z=animObj.z;

                            var h=(t[i+1]-t[i]);
                            var A=(1/(h*6))*(z[i+1]-z[i]);
                            var B=z[i]/2;
                            var C=-(h/6)*z[i+1]-(h*z[i]/3)+(y[i+1]-y[i])/h;
                            var S=y[i]+(x-t[i])*(C+(x-t[i])*(B+(x-t[i])*A));                            
                            animObj.node.setStyle(animObj.property,animObj.startingValue+S,animObj.units);                        
                            
                            };

    node.addAnimation=function(animationDef)
    {
        this.nAnimations++;
        if(!animationDef.startingValue)
            animationDef.startingValue=0;
        
        var animObj={
                currentIndex:0,
                curFrame:0,
                node:this,
                frames:animationDef.frames,
                property:animationDef["property"],
                startingValue:animationDef.startingValue,
                units:animationDef.units,
                callbacks:animationDef.callbacks,
                t:[],
                y:[]
               };
        if(!animObj.callbacks)
            animObj.callbacks={};
            var k;
        if(animationDef.onEndCallback)
            animObj.onEndCallback=animationDef.onEndCallback;
               animObj.nSpecFrames=animObj.frames.length;
               for(k=0;k<animObj.nSpecFrames;k++)
               {
                    animObj.t.push(animObj.frames[k].f);
                    animObj.y.push(animObj.frames[k].v);
                            
               }  
               animObj.z=this.numericLinear_calculateCoef(animObj.t,animObj.y);
               var c=new Date();
               animObj.startTime=c.getTime();
               this.runAnimation(animObj);
    };


    node.numericLinear_calculateCoef=function(t,y)
                    {
                        var n=t.length;
                        var b=new Array();
                        var u=new Array();
                        var v=new Array();
                        var z=new Array();
                        var h=new Array();
                        var i;
                        var i;
                        for(i=0;i<n;i++)
                            {
                            h[i]=t[i+1]-t[i];
                            b[i]=6*(y[i+1]-y[i])/h[i];
                        }

                        u[1]=2*(h[0]+h[1]);
                        v[1]=b[1]-b[0];


                        for(i=2;i<n-1;i++)
                            {
                            u[i]=2*(h[i]+h[i-1])-(h[i-1]*h[i-1])/u[i-1];
                            v[i]=b[i]-b[i-1]-h[i-1]*v[i-1]/u[i-1];
                        }

                        z[n-1]=0;
                        for(i=n-2;i>0;i--)
                            {

                            z[i]=(v[i]-h[i]*z[i+1])/u[i];
                        }
                        z[0]=0;
                        return z;
                    }
};

function getStockAnimation(name,valueStart,valueEnd,speedMultiplier)
{
    
    if(!speedMultiplier) {
        speedMultiplier=1;
    }
    valueStart=parseInt(valueStart);
    valueEnd=parseInt(valueEnd);
    
    switch(name) {
            case "easing":{
                var diff=valueEnd-valueStart;
                var nFrames=speedMultiplier*1000;
                var result=[{f:0,v:valueStart}];
                result.push({f:Math.floor(nFrames*12/20),v:Math.floor(valueStart+diff*10/18)});
                result.push({f:Math.floor(nFrames*16/20),v:Math.floor(valueStart+diff*17/18)});
                //result.push({f:Math.floor(nFrames*17/20),v:Math.floor(valueStart+diff*15/18)});
                //result.push({f:Math.floor(nFrames*19/20),v:Math.floor(valueStart+diff*17/18)});
                result.push({f:Math.floor(nFrames),v:valueEnd});                
                
                return result;
        }break;
            case "easeout":{
                var diff=valueEnd-valueStart;
                var nFrames=speedMultiplier*1000;
                var result=[{f:0,v:valueStart}];
                result.push({f:Math.floor(nFrames*3/20),v:valueStart+20});
                result.push({f:Math.floor(nFrames*5/20),v:valueStart+5});
                result.push({f:Math.floor(nFrames*12/20),v:Math.floor(valueStart+diff*10/18)});
                result.push({f:Math.floor(nFrames*14/20),v:Math.floor(valueStart+diff*15/18)});
                result.push({f:Math.floor(nFrames),v:valueEnd});
                return result;
        }break;
            case "floatEase":{
                var diff=valueEnd-valueStart;
                var nFrames=speedMultiplier*1000;
                var result=[{f:0,v:valueStart}];
                result.push({f:Math.floor(nFrames*6/20),v:valueStart+diff*5/18});
                result.push({f:Math.floor(nFrames*8/20),v:valueStart+diff*13/18});
                result.push({f:Math.floor(nFrames*15/20),v:valueStart+diff*15/18});
                result.push({f:Math.floor(nFrames*18/20),v:valueStart+diff*17/18});
                result.push({f:Math.floor(nFrames),v:valueEnd});
                
                return result;
            }break;

            case "floatEase2":{
                var diff=valueEnd-valueStart;
                var nFrames=speedMultiplier*1000;
                var result=[{f:0,v:valueStart}];
                result.push({f:Math.floor(nFrames*6/20),v:valueStart+diff*2/18});
                result.push({f:Math.floor(nFrames*8/20),v:valueStart+diff*6/18});
                result.push({f:Math.floor(nFrames*15/20),v:valueStart+diff*15/18});
                result.push({f:Math.floor(nFrames*18/20),v:valueStart+diff*17/18});
                result.push({f:Math.floor(nFrames),v:valueEnd});
                
                return result;
            }break;
                

        }
        

}

function getElementsByClass(searchClass,node,tag) {
        var classElements = new Array();
        var i;
        var j;

        if ( node == null )
                node = document;
        if ( tag == null )
                tag = '*';
        var els = node.getElementsByTagName(tag);
        var elsLen = els.length;
        var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
        for (i = 0, j = 0; i < elsLen; i++) {
                if ( pattern.test(els[i].className) ) {
                        classElements[j] = els[i];
                        j++;
                }
        }
        return classElements;
}
function node_has_class(node,className)
{
    var currentClasses=node.className.split(" ");
    var k;
    for(k=0;k<currentClasses.length;k++)
        {
        if(currentClasses[k]==className)
            return true;
        }
        return false;
}
function node_delete_class(node,className)
{
    
    var currentClasses=node.className.split(" ");
    var k;
    var newClass="";
    for(k=0;k<currentClasses.length;k++)
        {
        if(k>0)newClass+=' ';
        if(currentClasses[k]!=className)
            newClass+=currentClasses[k];
        }
        node.className=newClass;
}
function node_add_class(node,className)
{
    node.className+=' '+className;
}

var _GET = {};
for(var i,a,m,n,o,v,p=location.href.split(/[?&]/),l=p.length,k=1;k<l;k++)  
    if(m=p[k].match(/(.*?)(\..*?|\[.*?\])?=([^#]*)/))
        {    
            n=decodeURI(m[1]).toLowerCase(),o=_GET;    
            if(m[2])
                for(a=decodeURI(m[2]).replace(/\[\s*\]/g,"[-1]").split(/[\.\[\]]/),i=0;i<a.length;i++)       
                    v=a[i],o=o[n]?o[n]: o[n]=(parseInt(v)==v)?[]:{}, n=v.replace(/^["\'](.*)["\']$/,"$1");    
                     n!='-1'?o[n]=decodeURI(m[3]): o[o.length]=decodeURI(m[3]);
        }


var globalCallbacks=new Array();

function addCallback(when,f)
{
    if(!globalCallbacks[when])
        globalCallbacks[when]=new Array();
    globalCallbacks[when].push(f);

}
function initialize()
{
    var k;
    if(globalCallbacks.LOAD)
    {
        for(k=0;k<globalCallbacks["LOAD"].length;k++)
        {
            globalCallbacks["LOAD"][k]();
        }
    }
}


