﻿ /*
    Source adapted from: http://www.webappers.com/progressBar/
*/

Type.registerNamespace('MattBerseth.WebControls.AJAX.Progress.ProgressBehavior');

MattBerseth.WebControls.AJAX.Progress.ProgressBehavior = function(element) {

    //  Properties    
    this._mode = null;
    this._speed = null;
    //  keep track of the current percentage.
    //  when the continuous animation is running,
    //  this value will be -1    
    this._value = null;
    this._animate = null;
    this._tooltipText = null;
    this._statusText = null;
    this._showStatusText = null;
    
    //  the DOM element whose background image
    //  contains the indicator image
    this._indicator = null;
    
    //  Members used by the continuous animation
    //  resizing secquence
    this._sequenceAnimation = null;
    //  manually change the percentage
    this._percentageAnimation = null;
    //  handle the animation started event
    this._percentAnimationStartedHandler = null;    
    //  handle the animation ended event
    this._percentAnimationEndedHandler = null;
    //  handle the percent animation property changed event
    this._percentAnimationPropertyChangedHandler = null;
    
    //  Members used by the percentage animation
    //  not running
    this._isPercentQueueRunning = null;
    //  create the empty request queue
    this._percentQueue = null;  
    //  the DOM element that contains the percent status message
    this._info = null;
    
    MattBerseth.WebControls.AJAX.Progress.ProgressBehavior.initializeBase(this, [element]);
}

MattBerseth.WebControls.AJAX.Progress.ProgressBehavior.prototype = {    
    initialize : function() {
        MattBerseth.WebControls.AJAX.Progress.ProgressBehavior.callBaseMethod(this, 'initialize');
        
        //  get the DOM element that contains the indicator
        this._indicator = $get(this.get_id() + '_indicator');
        this._info = $get(this.get_id() + '_info');
        
        if(this.get_Mode() == MattBerseth.WebControls.AJAX.Progress.Mode.Manual){
        
            if(this.get_Animate()) {
                this._percentQueue = new Array();
                this._isPercentQueueRunning = false;
                
                //  create the animation that is used to change the percentage values
                this._percentageAnimation = new $AA.LengthAnimation(this._indicator, null, 35, 'style', 'width', null, null, '%');
                //  attach
                this._percentAnimationEndedHandler = Function.createDelegate(this, this._onPercentAnimationEnd);
                this._percentageAnimation.add_ended(this._percentAnimationEndedHandler);
                //  attach
                this._percentAnimationStartedHandler = Function.createDelegate(this, this._onPercentAnimationStart);
                this._percentageAnimation.add_started(this._percentAnimationStartedHandler);            
                //  attach
                this._percentAnimationPropertyChangedHandler = Function.createDelegate(this, this._onPercentAnimationPropertyChanged);
                this._percentageAnimation.add_propertyChanged(this._percentAnimationPropertyChangedHandler);              
            }
            
            //  hide the status text if the user
            //  doesn't want it displayed
            if(!this._showStatusText){
                this._info.style.display = 'none';
            }
            
            //  set the percentage
            this.set_percentage(this.get_Value());            
        }
        
        if(this.get_Mode() == MattBerseth.WebControls.AJAX.Progress.Mode.Continuous){
            //  create the resize animation
            var resizeAnimation = new $AA.LengthAnimation(this._indicator, 1, 50, 'style', 'width', 0, 100, '%');
            var noOpAnimation = new $AA.ScriptAction(null, .1, 25, '');
            //  setup the sequence
            this._sequenceAnimation = new $AA.SequenceAnimation(null, null, null, [resizeAnimation, noOpAnimation], -1);
            
            this._value = -1;
            this._info.style.display = 'none';
        }
    },
    
    dispose : function() {
        MattBerseth.WebControls.AJAX.Progress.ProgressBehavior.callBaseMethod(this, 'dispose');
    },
    
    show : function() {
        this.get_element().style.display = '';
    },
    
    hide : function() {
        this.get_element().style.display = 'none';
    },
    
    play : function() {
        if(this.get_Mode() == MattBerseth.WebControls.AJAX.Progress.Mode.Continuous) {
            //  kick off the animation        
            this._sequenceAnimation.play();
        }        
    },
    
    stop : function() {
        if(this.get_Mode() == MattBerseth.WebControls.AJAX.Progress.Mode.Continuous) {
            //  kick off the animation        
            this._sequenceAnimation.stop();  
        }           
    },
    
    set_percentage : function(percentage) {
        if(this.get_Mode() == MattBerseth.WebControls.AJAX.Progress.Mode.Manual) {
    	    
    	    if(this.get_Animate()){
                //  add the request to the queue
	            this._percentQueue.push(percentage);
        		
	            //  if we are not already processing,
	            //  start processing the queue
	            if (!this._isPercentQueueRunning) {
		            this._processPercentQueue();
	            }  
	        }
	        else {
	            //  no animation, just set the percentage
	            this._updatePercentage(percentage);
	        }
	    }	        
    },
    
    _processPercentQueue : function(){
        //  if there are items in the queue start
        //  processing them
		if (this._percentQueue.length > 0) {
		    //  update the status to running
			this._isPercentQueueRunning = true;
			
            var fromPercent = this._indicator.style.width == '' ? 0 : $common.parseUnit(this._indicator.style.width).size;
	        //var fromPercent = this.get_Value();
	        var toPercent = this._percentQueue[0];			
			
			// define the new percentage
			if ((toPercent.toString().substring(0,1) == "+") || (toPercent.toString().substring(0,1) == "-")) {
				toPercent = fromPercent + parseInt(toPercent);
			}
            
	        //  make sure we don't go above or below
	        //  the 0 - 100 range
	        if (toPercent < 0) {
	            toPercent = 0;
            }
	        if (toPercent > 100) {
		        toPercent = 100;
	        }
	
	        //  keep the actual value in sync        
    		this._percentQueue[0] = toPercent;
            
	        //  determine how long the animation should run
	        var speed = this.get_Speed() > 0 ? this.get_Speed() : parseFloat('0.' + Math.abs(fromPercent - toPercent));
        
            //  update the animation values
            this._percentageAnimation.set_duration(speed);
            this._percentageAnimation.set_startValue(fromPercent);
            this._percentageAnimation.set_endValue(toPercent);
            
            //  kick off the animation
            this._percentageAnimation.play();			
		} 
    },
    
    _onPercentAnimationStart : function() {
        //  add the updating class
        Sys.UI.DomElement.addCssClass(this.get_element(), 'updating');
    },
    
    _onPercentAnimationEnd : function() {
        //  remove the updating class
        Sys.UI.DomElement.removeCssClass(this.get_element(), 'updating');
    
        this._updatePercentage(this._percentQueue[0]);
	    // remove the entry from the queue
	    this._percentQueue.splice(0, 1);
	    //  we are not running any more
	    this._isPercentQueueRunning = false;
	    //  process any other items in the queue
	    this._processPercentQueue();
    },
    
    _onPercentAnimationPropertyChanged : function(sender, args) {
        if(args.get_propertyName() == 'percentComplete'){
            //  get the width of the element, thats the percentage
            var width = sender.get_target().style.width;
            if(width != ''){
                this._updatePercentage($common.parseUnit(width).size);
            }
        }
    },
    
    _updatePercentage : function(value) {
        this._value = parseInt(value);
        this._indicator.style.width = value + '%';
        
        //  apply the tooltip
        this._info.innerHTML = this._statusText ? String.format(this._statusText, value) : value + '%';
        this.get_element().title = this._tooltipText ? String.format(this._tooltipText, value) : value + '%';
    },
    
    get_Mode : function() {
        return this._mode;
    },
    set_Mode : function(value) {
        //  ToDo: can't set this property after the control has been initialized
        if (this._mode != value) {
            this._mode = value;
            this.raisePropertyChanged('Mode');
        }
    },
    
    get_Value : function() {
        return this._value;
    },
    set_Value : function(value) {
        //  ToDo: can't set this property after the control has been initialized
        if (this._value != value) {
            this._value = value;
            this.raisePropertyChanged('Value');
        }
    },
    
    get_Animate : function() {
        return this._animate;
    },
    set_Animate : function(value) {
        //  ToDo: can't set this property after the control has been initialized
        if (this._animate != value) {
            this._animate = value;
            this.raisePropertyChanged('Animate');
        }
    },
    
    get_Speed : function() {
        return this._speed;
    },
    set_Speed : function(value) {
        if (this._speed != value) {
            this._speed = value;
            this.raisePropertyChanged('Speed');
        }
    },    
    
    get_ToolTip : function() {
        return this._tooltipText;
    },
    
    set_ToolTip : function(value) {
        if (this._tooltipText != value) {
            this._tooltipText = value;
            this.raisePropertyChanged('Tooltip');
        }
    },
    
    get_StatusText : function() {
        return this._statusText;
    },
    
    set_StatusText : function(value) {
        if (this._statusText != value) {
            this._statusText = value;
            this.raisePropertyChanged('StatusText');
        }
    },
    
    get_ShowStatusText : function() {
        return this._showStatusText;
    },
    
    set_ShowStatusText : function(value) {
        if (this._showStatusText != value) {
            this._showStatusText = value;
            this.raisePropertyChanged('ShowStatusText');
        }
    }                           
}
MattBerseth.WebControls.AJAX.Progress.ProgressBehavior.registerClass('MattBerseth.WebControls.AJAX.Progress.ProgressBehavior', Sys.UI.Control);

MattBerseth.WebControls.AJAX.Progress.Mode = function() {
    throw Error.invalidOperation();
}
MattBerseth.WebControls.AJAX.Progress.Mode.prototype = {
    Manual: 0,
    Continuous: 1
}
MattBerseth.WebControls.AJAX.Progress.Mode.registerEnum('MattBerseth.WebControls.AJAX.Progress.Mode');
if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();