//------------------------------------------------------------------------------
//  WAX 1.5 - general-purpose web application library
//  Copyright (C) 2000-2006 SnapWorks
//  Website : http://www.snap-works.com/
//  Email   : info@snap-works.com
//------------------------------------------------------------------------------

function Animator()
{
    this.m_behaviors = [];
    this.m_index = 0;
    this.m_done = true;

    this.refreshInterval = 10;
    this.repeat = false;    
    this.onDone = null;
}

Animator.prototype.addBehavior = function(behavior)
{
	
	this.m_behaviors.push(behavior);
    this.m_done = false;
    behavior.m_animator = this;
}

Animator.prototype.run = function()
{
   	
	
    if (this.m_done) {
        return;
    }
    
    this.m_done = (this.m_index >= this.m_behaviors.length);
    
    if (! this.m_done) {
        this.m_behaviors[this.m_index++].run();
        
    } else {
        if (this.onDone) {
            this.onDone();
        }
        
        this.m_done = false;
        
        if (this.repeat) {
            var __this = this;
            this.m_index = 0;
            setTimeout(function() { __this.run(); }, '50');
        }
    }
}

Animator.prototype.stop = function()
{
    for (var i=0; i<this.m_behaviors.length; i++) {
        this.m_behaviors[i].stop();
    }
}

Animator.prototype.clear = function()
{
    this.stop();

    this.m_behaviors.length = 0;
    this.m_index = 0;
    this.m_done = true;
}

////////////////////////////////////////////////////////////////////////////////

function Behavior(element, duration)
{
    this.m_animator = null;
    this.m_element = element;
    this.m_duration = duration;
    this.m_timer = null;
}

Behavior.prototype.run = function()
{
    var startTime = new Date().getTime();
    var behavior = this;
    
    function onTimer()
    {
        var currentTime = new Date().getTime();
     
        behavior.timer = null;
        
        if (0 == behavior.m_duration) {
            behavior.update(1.0);
            behavior.m_animator.run();
        } else if (currentTime - startTime < behavior.m_duration) { 
            behavior.m_timer = setTimeout(onTimer, behavior.m_animator.refreshInterval);
            behavior.update((currentTime - startTime) / behavior.m_duration);
        } else {
            behavior.update(1.0);
            behavior.m_animator.run();
        }
    }
    
    onTimer();
}

Behavior.prototype.stop = function()
{
    if (null != this.m_timer) {
        clearTimeout(this.m_timer);
    }
    
    this.m_timer = null;
}

Behavior.prototype.update = function(progress)
{
}

////////////////////////////////////////////////////////////////////////////////

function GroupBehavior(behaviors)
{
    Behavior.call(this, null, behaviors[0].m_duration);
    this.m_behaviors = behaviors;
}

ExtendClass(GroupBehavior, Behavior);

GroupBehavior.prototype.update = function(progress)
{
    for (var i=0; i<this.m_behaviors.length; i++) {
        this.m_behaviors[i].update(progress);
    }
}

////////////////////////////////////////////////////////////////////////////////

function MoveBehavior(element, duration, ox, oy, nx, ny)
{
    Behavior.call(this, element, duration);
    
    this.ox = ox;
    this.oy = oy;
    this.nx = nx;
    this.ny = ny;
}

ExtendClass(MoveBehavior, Behavior);

MoveBehavior.prototype.update = function(progress)
{
    this.m_element.style.left = (this.ox + (this.nx-this.ox) * progress) + 'px';
    this.m_element.style.top  = (this.oy + (this.ny-this.oy) * progress) + 'px';
}

////////////////////////////////////////////////////////////////////////////////

function ColorBehavior(element, duration, or, og, ob, nr, ng, nb)
{
    Behavior.call(this, element, duration);
    
    this.or = or;
    this.og = og;
    this.ob = ob;
    
    this.nr = nr;
    this.ng = ng;
    this.nb = nb;
}

ExtendClass(ColorBehavior, Behavior);

ColorBehavior.prototype.update = function(progress)
{
    var r = Math.round(this.or + (this.nr-this.or) * progress);
    var g = Math.round(this.og + (this.ng-this.og) * progress);
    var b = Math.round(this.ob + (this.nb-this.ob) * progress);
    this.m_element.style.backgroundColor = 'rgb('+r+', '+g+', '+b+')';
}

////////////////////////////////////////////////////////////////////////////////

function AlphaBehavior(element, duration, oa, na)
{
    Behavior.call(this, element, duration);
    
    this.oa = oa;
    this.na = na;
}

ExtendClass(AlphaBehavior, Behavior);

AlphaBehavior.prototype.update = function(progress)
{
    applyAlpha(this.m_element, (this.oa + (this.na-this.oa) * progress));
}

////////////////////////////////////////////////////////////////////////////////

