﻿Type.registerNamespace('BIT.WebControls');


BIT.WebControls.AnimationType = function ()
{
    if (arguments.length !== 0) throw Error.parameterCount();
    throw Error.notImplemented();
}

BIT.WebControls.AnimationType.prototype = 
{
    linear: 0,
    exp: 1,
    ln: 2
}

BIT.WebControls.AnimationType.registerEnum("BIT.WebControls.AnimationType");


BIT.WebControls.AnimationState = function ()
{
    if (arguments.length !== 0) throw Error.parameterCount();
    throw Error.notImplemented();
}

BIT.WebControls.AnimationState.prototype = 
{
    stopped: 0,
    started: 1,
    paused: 2
}

BIT.WebControls.AnimationState.registerEnum("BIT.WebControls.AnimationState");


BIT.WebControls.AnimationStateEventArgs = function BIT$CRM$WebControls$AnimationStateEventArgs(state) {
    var e = Function._validateParams(arguments, [
        {name: "state", mayBeNull: false, optional: false}
    ]);
    if (e) throw e;
        
    Sys.EventArgs.initializeBase(this);

    this._state = state;
}

BIT.WebControls.AnimationStateEventArgs.prototype = 
{
    get_state: function () 
    {
        if (arguments.length !== 0) throw Error.parameterCount();
        
        return this._state;
    },
    
    set_state: function (value) 
    {
        var e = Function._validateParams(arguments, [{name: "value", type: Number, integer: true}]);
        if (e) throw e;

        this._state = value;
    }
}

BIT.WebControls.AnimationStateEventArgs.registerClass('BIT.WebControls.AnimationStateEventArgs', Sys.EventArgs);


BIT.WebControls.AnimationStepEventArgs = function BIT$CRM$WebControls$AnimationStepEventArgs(step) {
    var e = Function._validateParams(arguments, [
        {name: "step", mayBeNull: false, optional: false}
    ]);
    if (e) throw e;
        
    Sys.EventArgs.initializeBase(this);

    this._step = step;
}

BIT.WebControls.AnimationStepEventArgs.prototype = 
{
    get_step: function () 
    {
        if (arguments.length !== 0) throw Error.parameterCount();
        
        return this._step;
    },
    
    set_step: function (value) 
    {
        var e = Function._validateParams(arguments, [{name: "value", type: Number}]);
        if (e) throw e;

        this._step = value;
    }
}


BIT.WebControls.AnimationStepEventArgs.registerClass('BIT.WebControls.AnimationStepEventArgs', Sys.EventArgs);

BIT.WebControls.Animator = function()
{
    BIT.WebControls.Animator.initializeBase(this);

    this.addProperty('type', BIT.WebControls.AnimationType.exp);
    this.addProperty('state', BIT.WebControls.AnimationState.stopped);
    
    
    this.addProperty('step', 0);
    this.addProperty('reverse', false);
    
    this.addProperty('delay', 35);
    this.addProperty('interval', 5);
    this.addProperty('steps', 4);
    
    this.addEvent('stateChanged');
    this.addEvent('stepChanged');
    
    this._timerId = null;
}

BIT.WebControls.Animator.prototype = 
{
    set_state: function(value)
    {
        if (this.state != value)
            this.state = value;
            
        this.raiseEvent('stateChanged', new BIT.WebControls.AnimationStateEventArgs(this.state));
    },
    
    set_step: function(value)
    {
        if (this.step != value)
            this.step = value;

        this.raiseEvent('stepChanged', new BIT.WebControls.AnimationStepEventArgs(this.step));
    },
    
    initialize: function()
    {
        BIT.WebControls.Animator.callBaseMethod(this, 'initialize');    
        
        this._stepDelegate = Function.createDelegate(this, this._step);
    },
    
    dispose : function()
    {   
        BIT.WebControls.Animator.callBaseMethod(this, 'dispose');    
        
        this.stop();
        
        var t = this._timer;
        
        this._timer = null;

        if (t)
			t.dispose();
    },
    
    _step : function()
    {
		var ticks = new Date().getTime();
		
		var delta = (this._time === null) ? 0 : (ticks - this._time);
		
        var step = this.step + ((this.reverse) ? -1 : 1) * ((delta > 0) ? delta / this.delay : 1 ) ;
        
        if (step < 0)
			step = 0;
		else if (step > this.steps - 1)
			step = this.steps - 1;

        this.set_step(step);
        
        if (this.reverse)
        {
            if (step == 0)
            {
                this.stop();
                return;
			}
        }
        else
        {
            if (step == this.steps - 1)
            {
                this.stop();
                return;
			}
        }
        
        
        this._time = ticks;
        this._timerId = window.setTimeout( this._stepDelegate, this.interval );
    },
    
	_lnCalc : function ( step, steps )
    {
        return 1 - Math.exp((Math.max(1, steps) - step) * 5 / (Math.max(1, steps))) / Math.exp(5) ;
    },    
    
    _expCalc : function ( step, steps )
    {
        return Math.exp(step * 5 / (Math.max(1, steps))) / Math.exp(5) ;
    },
    
    _linearCalc : function ( step, steps )
    {
        return step / (Math.max(1, steps));
    },

    calc : function( start , end , step, steps, reverse)
    {
        var res = 0;
        
        reverse = !!reverse;
        steps = (steps || this.steps);
        step = reverse ? (step || 0) + steps - this.step + 1 : this.step - (step || 0);
        
        
        switch(this.type)
        {
            case BIT.WebControls.AnimationType.ln:
                res = this._lnCalc( step, steps );
                break;            
            case BIT.WebControls.AnimationType.exp:
                res = this._expCalc( step, steps );
                break;        
            case BIT.WebControls.AnimationType.linear:
                res = this._linearCalc( step, steps );
                break;
            default:
                throw Error.notImplemented();
        }
        
        return start + (end - start) * res;
    },
    
    start: function()
    {
        if (this.state == BIT.WebControls.AnimationState.started)
            return;
        
        var paused = (this.state == BIT.WebControls.AnimationState.paused)
            
        this.set_state(BIT.WebControls.AnimationState.started);
        
        if (!paused)
            this.step = (this.reverse) ? Math.max(this.steps - 1 , 0) : 0;
            
		this._time = null;
		
		if (this._timerId)
        {
			window.clearTimeout(this._timerId);
			this._timerId = null;
		}


		this._step();
    },
    
    stop: function()
    {
        if (this.state == BIT.WebControls.AnimationState.stopped)
            return;
            
		this.set_state(BIT.WebControls.AnimationState.stopped);
			
		if (this._timerId)
        {
			window.clearTimeout(this._timerId);
			this._timerId = null;
		}
    },
    
    pause: function()
    {
        if (this.state == BIT.WebControls.AnimationState.paused)
            return;
            
        
        this.set_state(BIT.WebControls.AnimationState.paused);
                
        if (this._timerId)
        {
			window.clearTimeout(this._timerId);
			this._timerId = null;
		}
    }
    
}

BIT.WebControls.Animator.registerClass('BIT.WebControls.Animator', Sys.Component);


if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();