var fades;
var shifts;
var sizes;
function Fade( e, trgOpac, rate, interval, done ) 
{
    this.cont = function()
    {
        this.adjOpac();
        if( this.curOpac == this.trgOpac )
            term( fades, this, done );
        else if( this.fadeIn == false )
        {
            this.curOpac -= this.rate;
            if( this.curOpac < this.trgOpac ) this.curOpac = this.trgOpac;
        }
        else
        {
            this.curOpac += this.rate;
            if( this.curOpac > this.trgOpac ) this.curOpac = this.trgOpac;
        }
    }
    this.adjW3C = function()
    {
        this.e.style.opacity = ( this.curOpac - 0.00001 ) / 100;
    }
    this.adjWIE = function()
    {
        this.e.filters.alpha.opacity = this.curOpac;
    }
   
    this.e = con( e );
    this.trgOpac = trgOpac;
    this.rate = rate;
    if( window.opera )
    {
        if( this.e.style.opacity == "" )
            this.e.style.opacity = "0.99";
        this.adjOpac = this.adjW3C;
        this.curOpac = parseInt( this.e.style.opacity * 100 );
    }
    else if( document.all )
    {
        try{ this.e.filters.alpha.opacity; }
        catch( exc ){ this.e.style.filter = "alpha(opacity=99)"; }
        this.adjOpac = this.adjWIE;
        this.curOpac = parseInt( this.e.filters.alpha.opacity );
    }
    else if( window.sidebar )
    {
        if( this.e.style.opacity == "" )
            this.e.style.opacity = "0.99";
        this.adjOpac = this.adjW3C;
        this.curOpac = parseInt( this.e.style.opacity * 100 );
    }
    else{
        if( this.e.style.opacity == "" )
            this.e.style.opacity = "0.99";
        this.adjOpac = this.adjW3C;
        this.curOpac = parseInt( this.e.style.opacity * 100 );
    }
    this.fadeIn = this.trgOpac > this.curOpac;
    if( fades == null )
        fades = new Array();
    init( fades, this );
    var ref = this;
    this.id = setInterval( function(){ ref.cont(); }, interval );   
}
function Shift( e, trgLeft, trgTop, rate, interval, done ) 
{
    this.cont = function()
    {
        if( this.curLeft == this.trgLeft && this.curTop == this.trgTop )
            term( shifts, this, done );
        else
        {
            this.curLeft += this.leftRate;
            this.curTop += this.topRate;
        }
        if( ( this.leftRate > 0 && this.curLeft > this.trgLeft ) || (  this.leftRate < 0 && this.curLeft < this.trgLeft ) ) this.curLeft = this.trgLeft;
        if( ( this.topRate > 0 && this.curTop > this.trgTop ) || (  this.topRate < 0 && this.curTop < this.trgTop ) ) this.curTop = this.trgTop;
        this.e.style.left = this.curLeft + "px";
        this.e.style.top = this.curTop + "px";
    }

    this.e = con( e );
    this.trgLeft = trgLeft;
    this.trgTop = trgTop;
    this.rate = rate;
    if( this.e.style.left.indexOf( "px" ) == -1 )
        this.e.style.left = "0px";
    if( this.e.style.top.indexOf( "px" ) == -1 )
        this.e.style.top = "0px";
    this.curLeft = parseInt( this.e.style.left.replace( "px", "" ) );
    this.curTop = parseInt( this.e.style.top.replace( "px", "" ) );
    var run = this.trgLeft - this.curLeft;
    var rise = this.trgTop - this.curTop;
    var theta = Math.atan( rise / run );
    var ref = this;
    this.leftRate = Math.cos( theta ) * this.rate;
    this.topRate = Math.sin( theta ) * this.rate;
    if( run < 0 )
    {
        this.leftRate = -this.leftRate;
        this.topRate = -this.topRate;
    }
    if( shifts == null )
        shifts = new Array();
    init( shifts, this );
    var ref = this;
    this.id = setInterval( function(){ ref.cont(); }, interval );    
}
function Size( e, trgWidth, trgHeight, rate, interval, done ) 
{
    this.cont = function()
    {
        if( this.curWidth == this.trgWidth && this.curHeight == this.trgHeight ) term( sizes, this, done );
        else
        {
            this.curWidth += this.widthRate;
            this.curHeight += this.heightRate;
        }
        if( ( this.widthRate > 0 && this.curWidth > this.trgWidth ) || (  this.widthRate < 0 && this.curWidth < this.trgWidth ) ) this.curWidth = this.trgWidth;
        if( ( this.heightRate > 0 && this.curHeight > this.trgHeight ) || (  this.heightRate < 0 && this.curHeight < this.trgHeight ) ) this.curHeight = this.trgHeight;
        this.e.style.width = this.curWidth + "px";
        this.e.style.height = this.curHeight + "px";
    }

    this.e = con( e );
    this.trgWidth = trgWidth;
    this.trgHeight = trgHeight;
    this.rate = rate;
    if( this.e.style.width.indexOf( "px" ) == -1 )
        this.e.style.width = "0px";
    if( this.e.style.height.indexOf( "px" ) == -1 )
        this.e.style.height = "0px";
    this.curWidth = parseInt( this.e.style.width.replace( "px", "" ) );
    this.curHeight = parseInt( this.e.style.height.replace( "px", "" ) );
    var run = this.trgWidth - this.curWidth;
    var rise = this.trgHeight - this.curHeight;
    var theta = Math.atan( rise / run );
    var ref = this;
    this.widthRate = Math.cos( theta ) * this.rate;
    this.heightRate = Math.sin( theta ) * this.rate;
    if( run < 0 )
    {
        this.widthRate = -this.widthRate;
        this.heightRate = -this.heightRate;
    }
    if( sizes == null )
        sizes = new Array();
    init( sizes, this );
    var ref = this;
    this.id = setInterval( function(){ ref.cont(); }, interval );    
}
function con( e )
{
    if( typeof e == 'string' )
        e = document.getElementById( e );
    return e;
}
function term( arr, obj, done )
{
    clearInterval( obj.id );
    var len = arr.length;
    for( var i = 0; i < len; i ++ )
        if( arr[ i ].e == obj.e )
        {
            arr.splice( i, 1 );
            break;
        }
    done();
}
function init( arr, obj )
{
    var len = arr.length;
    for( var i = 0; i < len; i ++ )
        if( arr[ i ].e == obj.e )
        {
            term( arr, arr[ i ], function(){} );
            break;
        }
    arr.push( obj );
}