﻿//---------------------------------------- ANIMATIONS --------------------------------------------------//
//Controls to benefit are - tooltip, window, dock, colorpicker
//Animations combine two animations [open/close] using the same set of data.
//Properties that are needed to provide information show and hide animations
//startBounds, endBounds, ITkey.Web.UI.ToolTipPosition position!-> will probably need to be made common for all controls.

//Window can be moved from original location, their opener can be moved, so calculating exact values to use can requier more actions to get the correct values
//Close animations assume the animated element's size and position
Type.registerNamespace('ITkey.Web.UI.Animations');

ITkey.Web.UI.Animations.ShowHideAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    ///<exclude/>    
    this.controller = controller;
        
    this._duration = (duration !=  null) ? duration : .3;
    this._fps = (fps !=  null) ? fps : 50;
    this._frames = duration * fps;		    
    this._position = null != position ? position : 32;//ITkey.Web.UI.ToolTipPosition.BottomCenter;
        
    this._animatedElement = animatedElement;//The element to be animated    
    this._sourceElement = sourceElement;    //The source element that initiates the animation can be used to obtain start/end bounds
    
    //Start bounds are optional and not set on some animations.If a sourceElement exists, it has higher priority than the startBounds
    this._startBounds = null;
    //End bounds are mandatory for animations that perform resizing, and must be set in onStart handler
    this._endBounds = null;
    
    //Created by classes that inherit the base class
    this._showAnimation = null;
    this._hideAnimation = null;
}


ITkey.Web.UI.Animations.ShowHideAnimation.prototype = 
{   
    //## region protected methods##
    
    //Returns the horizontal position of animated element relative to the sourceElement
    _getHorizontalPosition : function()
    {
      return parseInt((this._position + "").charAt(1));      
    },
    
    //Returns the vertical position of animated element relative to the sourceElement
    _getVerticalPosition : function()
    {
      return parseInt((this._position + "").charAt(0));      
    },
    
    //Use it to set proper values to the animation. 
    //if startBounds are set, use them as initial size/position values. Else - if _sourceElement is set - use its bounds for initial values
    _onBeforeShow : function()
    {    
        /* Override in subclass */
    },
            
    _onBeforeHide : function()
    {    
        /* Override in subclass */
    },
        
    _onAfterShow : function()
    {   
        /* Override in subclass */ 
    },
    
    _onAfterHide : function()
    {   
        /* Override in subclass */ 
    },
                                      
    //## region Public API ##//
    onShowStart : function()
    {
        /* Override when initializing */
    },
            
    onHideStart : function()
    {
        /* Override when initializing */
    },
    
    onShowEnd : function()
    {
       /* Override when initializing */
    },
    onHideEnd : function()
    {
       /* Override when initializing */
    },
    
    play : function(isHideSequence)
    {
       var animation = (true == isHideSequence) ? this._hideAnimation : this._showAnimation;
        
        if (animation)
        {
            //Stop running animation [if any]
            //this.stop();
            
            if (!animation.__isITkeyModified)
            {                
                animation.__isITkeyModified = true;                
                //Attach to onStart and prevent onStart from being replaced multiple times on each animation play
                var oldStart = animation.onStart;
                animation.add_started(Function.createDelegate(this, function()
                {                            
                    //Call current onStart to allow for setting configuration values
                    if (isHideSequence) this.onHideStart();
                    else this.onShowStart();
              
                    //Use the values set in the onStart event handler to finish the initialization process
                    if (true == isHideSequence)
                    {
                        this._onBeforeHide();
                    }
                    else
                    {                                  
                        this._onBeforeShow();          
                    }
                    
                    //Important: Call original onStart to perform initialiation, or else it would not work
                    //! The invocation must be here - as the last action!
                    //if (oldStart) oldStart.call(this);
                }));
                
                //Attach to onEnd and prevent onEnd from being replaced multiple times on each animation play
                var oldEnd = animation.onEnd;
                animation.add_ended(Function.createDelegate(this,function()
                {                        
                    //if (oldEnd) oldEnd.call(this);
                    
                    if (this.onEnd) this.onEnd(isHideSequence);
                    
                    //Cleanup
                    if (true == isHideSequence)
                    {
                        this._onAfterHide();
                    }
                    else
                    {                                  
                        this._onAfterShow();          
                    }
                    
                    //Run finalizing code
                    if (isHideSequence) this.onHideEnd();
                    else this.onShowEnd();           
               }));
            }
            
            //NEW: Reset the duration
            animation.set_duration(this._duration);
          
            //Play animation            
            animation.play();    
        }
                
        this._runningAnimation = animation;       
    },
    
    set_startBounds : function(bounds)
    {
        this._startBounds = bounds;
    },

    set_endBounds : function(bounds)
    {
        this._endBounds = bounds;
    },
        
    dispose : function()
    {
        this.stop();
        if (this._showAnimation) this._showAnimation.dispose();
        if (this._hideAnimation) this._hideAnimation.dispose();
    },
    
    stop : function()
    {
        if (this._runningAnimation)
        {
            this._runningAnimation.stop();
            this._runningAnimation = null;
        }
    },
    
    //NEW: Pause functionality
    pause : function()
    {
        if (this._runningAnimation)
        {
            this._runningAnimation.pause();
            
        }
    },
    
    resume : function()
    {
        if (this._runningAnimation)
        {
            this._runningAnimation.play();
            
        }
    },
    
    //NEW: API methods    
    set_position : function(value)
    {
        this._position = value;
    },
    
    set_duration : function(value)
    {
        this._duration = value;        
        if (this._showAnimation) this._showAnimation.set_duration(this._duration);
        if (this._hideAnimation) this._hideAnimation.set_duration(this._duration);
    
    },
    
    get_startBounds : function()
    {
        return this._startBounds;
    },
    
    get_endBounds : function()
    {
        return this._endBounds;
    }
        
}
ITkey.Web.UI.Animations.ShowHideAnimation.registerClass('ITkey.Web.UI.Animations.ShowHideAnimation', null);


/****************************************************************************************************************
 *                                                  Resize animation 
 ****************************************************************************************************************/
ITkey.Web.UI.Animations.ResizeAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    ITkey.Web.UI.Animations.ResizeAnimation.initializeBase(this, [controller, duration, fps, animatedElement, position, sourceElement]);    
    
    var duration = this._duration;
    var fps = this._fps;
    var target =  this._animatedElement; 
    
    //Fake values for easier initialiation    
    //var width = 100, height = 100, startY = 0, endY = 100, startX = 0, endX = 100;
    var width, height, startY, endY, startX, endX;
    
	//_showAnimation			
    var resizeAnimation = new ITkey.Web.Animation.ResizeAnimation(target, duration, fps, width, height, 'px');    
    var leftAnimation = new ITkey.Web.Animation.LengthAnimation(target, duration, fps, "style", "left", startX, endX, "px");
    var topAnimation = new ITkey.Web.Animation.LengthAnimation(target, duration, fps, "style", "top", startY, endY, "px");							        
    var fadeAnimation = new ITkey.Web.Animation.FadeInAnimation(target, duration, fps, .3, 1, false);	    						

    this._showAnimation = new ITkey.Web.Animation.ParallelAnimation(target, duration, fps, 		    
                          [resizeAnimation, leftAnimation, topAnimation, fadeAnimation]
                        );                                   
    
    //_hideAnimation
    this._hideAnimation = new ITkey.Web.Animation.FadeInAnimation(this._animatedElement, this._duration, this._fps, 1, 0, false);	               	    
};

ITkey.Web.UI.Animations.ResizeAnimation.prototype = 
{    
    //Break into pieces, some of which will be overridden in ineriting animations
    _configureAnimatedElement : function()
    {
        var target = this._animatedElement;        
        target.style.overflow = "hidden";
        target.style.display = "";
        target.style.visibility = "visible";     
        target.style.width = "1px";
        target.style.height = "1px";        
    },
              
    _configureAnimation : function(animValues)
    {        
        //Configure the animations before you run the parent animation
		var anims = this._showAnimation.get_animations();
		var resizeAnim = anims[0];
		resizeAnim.set_width(animValues.width);
		resizeAnim.set_height(animValues.height);

        var leftAnim = anims[1];     
        leftAnim.set_startValue(animValues.startX);
        leftAnim.set_endValue(animValues.endX);
   
        var topAnim = anims[2];
        topAnim.set_startValue(animValues.startY);
        topAnim.set_endValue(animValues.endY);
    },
        
        
    _getStartBounds : function()
    {
        var startBounds = null;
        if (this._startBounds) startBounds = this._startBounds;
		else if (this._sourceElement) startBounds = $ITkey.getBounds(this._sourceElement);
		else startBounds = new Sys.UI.Bounds(1,1,1,1); 	
		return startBounds;
    },
    
    _getEndBounds : function()
    {
        return this._endBounds;
    },
    
    //Can be overridden in subclasses
	_modifyAnimationValues : function(animValues)
    {      			
		//Additional smooth out - if the source element is smaller than tooltip, use the source element as starting size
		var target = this._animatedElement;
		var startBounds = this._getStartBounds();
			                   		
		if(startBounds.width < animValues.width) 
		{
		    animValues.startX = startBounds.x;
		    target.style.width = startBounds.width;
		}
		
		if(startBounds.height < animValues.height) 
		{
		    //Only if position is in center! Other than that -> if position top - start from top, position bottom start from bottom
		    animValues.startY = startBounds.y;				    
            target.style.height = startBounds.height;
		}
	},
		
    _setHorizontalValues : function(animValues)
    {
        var horSide = this._getHorizontalPosition();
        var popupBounds = this._getEndBounds();
        switch(horSide)
        {
            //Center
            case 2:                            
                animValues.startX = popupBounds.x + Math.floor(popupBounds.width/2);  
                animValues.endX = popupBounds.x;
                break;
            //Right
            case 3:              
                animValues.startX = popupBounds.x;
                animValues.endX = popupBounds.x;
                break;                
            //Left            
            case 1:
                animValues.startX = popupBounds.x + popupBounds.width;  
                animValues.endX = popupBounds.x;          
        }
    },
    
    _setVerticalValues : function(animValues)
    {
        var verSide = this._getVerticalPosition();                
        var popupBounds = this._getEndBounds();
         //Compute the vertical coordinate
        switch(verSide)
        {
            //Middle
            case 2:                                               
               animValues.startY = popupBounds.y + Math.floor(popupBounds.height/2);
               animValues.endY = popupBounds.y;
               break;
            //Top    
            case 1:               
               animValues.startY = popupBounds.y + popupBounds.height;
               animValues.endY = popupBounds.y;                
                break;
            //Bottom
            case 3:
               animValues.startY = popupBounds.y;
               animValues.endY = popupBounds.y;             
        }
    },
    
    _setSizeValues : function(animValues)
    {
        var popupBounds = this._endBounds;
        animValues["width"] = popupBounds.width;
		animValues["height"] = popupBounds.height;
    },
    
    //Inherit from parent class
    _onBeforeShow : function()
    {    
		//Create animation object
		var animValues = {};				
		this._setHorizontalValues(animValues);
		this._setVerticalValues(animValues);
		this._setSizeValues(animValues);
	
	    //Configure the element to be animated
		this._configureAnimatedElement();
						                
		//Overridden method - allow for value and target element modification
		this._modifyAnimationValues(animValues);
        //alert("Start x=" + animValues.startX + " , y = " + animValues.startY);
		//Configure the child animation objects using the supplied values
		this._configureAnimation(animValues);
    },
    
    _onAfterShow : function()
    {           
       this._animatedElement.style.overflow = "";        
       //Remove trasnparency filter(s) to make callout visible! Bug in IE         
       this._animatedElement.style.filter = "";               
    }            
}

ITkey.Web.UI.Animations.ResizeAnimation.registerClass('ITkey.Web.UI.Animations.ResizeAnimation', ITkey.Web.UI.Animations.ShowHideAnimation);


/****************************************************************************************************************
 *                                                  Slide animation 
 ****************************************************************************************************************/
 ITkey.Web.UI.Animations.SlideAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    ITkey.Web.UI.Animations.SlideAnimation.initializeBase(this, [controller, duration, fps, animatedElement, position, sourceElement]);            
};

ITkey.Web.UI.Animations.SlideAnimation.prototype = 
{         
    _modifyAnimationValues : function(animValues)
    {      					
	},
	
	 _configureAnimatedElement : function()
    {
        var target = this._animatedElement;        
        target.style.overflow = "hidden";
        target.style.display = "";
        target.style.visibility = "visible";     
        
        var verSide = this._getVerticalPosition();        
        if (verSide == 2)
        {
           target.style.width = "1px";
        }
        else target.style.height = "1px"; 
    },
		
   _setHorizontalValues : function(animValues)
    {
        var horSide = this._getHorizontalPosition();
        var popupBounds = this._getEndBounds();
        switch(horSide)
        {
            //Center
            case 2:                            
                animValues.startX = popupBounds.x;// + Math.floor(popupBounds.width/2);  
                animValues.endX = popupBounds.x;
                break;
            //Right
            case 3:              
                animValues.startX = popupBounds.x;
                animValues.endX = popupBounds.x;
                break;                
            //Left            
            case 1:
                var startX = popupBounds.x;
                
                if (2 == this._getVerticalPosition())  //Only if vertical pos is middle!
                        startX += popupBounds.width;
                
                animValues.startX = startX;
                                    
                animValues.endX = popupBounds.x;          
        }
    },
    
    _setVerticalValues : function(animValues)
    {
        var verSide = this._getVerticalPosition();                
        var popupBounds = this._getEndBounds();
         //Compute the vertical coordinate
        switch(verSide)
        {
            //Middle
            case 2:                                               
               animValues.startY = popupBounds.y;// + Math.floor(popupBounds.height/2);
               animValues.endY = popupBounds.y;
               break;
            //Top    
            case 1:               
               animValues.startY = popupBounds.y + popupBounds.height;
               animValues.endY = popupBounds.y;                
                break;
            //Bottom
            case 3:
               animValues.startY = popupBounds.y;
               animValues.endY = popupBounds.y;             
        }
    }
}

ITkey.Web.UI.Animations.SlideAnimation.registerClass('ITkey.Web.UI.Animations.SlideAnimation', ITkey.Web.UI.Animations.ResizeAnimation);
 
/****************************************************************************************************************
*                                                  FlyIn animation 
****************************************************************************************************************/
ITkey.Web.UI.Animations.FlyInAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    ITkey.Web.UI.Animations.FlyInAnimation.initializeBase(this, [controller, duration, fps, animatedElement, position, sourceElement]);    
};

ITkey.Web.UI.Animations.FlyInAnimation.prototype = 
{         
	_modifyAnimationValues : function(animValues)
    {      					
	},
		
    _setHorizontalValues : function(animValues)
    {    
        var horSide = this._getHorizontalPosition();
        var popupBounds = this._getEndBounds();
        
        var browserBounds = $ITkey.getClientBounds();
        
        switch(horSide)
        {
            //Center
            case 2:                            
                animValues.startX = popupBounds.x;
                animValues.endX = popupBounds.x;
                break;
            //Right
            case 3:              
                animValues.startX = browserBounds.width;
                animValues.endX =  popupBounds.x;
                break;                
            //Left            
            case 1:
                animValues.startX = browserBounds.x;  
                animValues.endX = popupBounds.x;          
        }
                
    },
    
    _setVerticalValues : function(animValues)
    {
        var verSide = this._getVerticalPosition();                
        var popupBounds = this._getEndBounds();
        var browserBounds = $ITkey.getClientBounds();
        
         //Compute the vertical coordinate
        switch(verSide)
        {
            //Middle
            case 2:                                               
               animValues.startY = popupBounds.y;
               animValues.endY = popupBounds.y;
               break;
            //Top    
            case 1:               
               animValues.startY = browserBounds.y - popupBounds.height;
               animValues.endY = popupBounds.y;                
                break;
            //Bottom
            case 3:
               animValues.startY = browserBounds.height;
               animValues.endY = popupBounds.y;             
        }                
    }
}

ITkey.Web.UI.Animations.FlyInAnimation.registerClass('ITkey.Web.UI.Animations.FlyInAnimation', ITkey.Web.UI.Animations.ResizeAnimation);
 
  
/****************************************************************************************************************
*                                                  Fade animation 
****************************************************************************************************************/
ITkey.Web.UI.Animations.FadeAnimation = function(controller, duration, fps, animatedElement) 
{                 
    ITkey.Web.UI.Animations.FadeAnimation.initializeBase(this, [controller, duration, fps, animatedElement]);    
    
    this._showAnimation = new ITkey.Web.Animation.FadeInAnimation(this._animatedElement, this._duration, this._fps, .5, 1, false);	      
    this._hideAnimation = new ITkey.Web.Animation.FadeInAnimation(this._animatedElement, this._duration, this._fps, .9, 0, false);	               
};

ITkey.Web.UI.Animations.FadeAnimation.prototype = 
{      
    _onAfterShow : function()
    {                            
        //Remove trasnparency filter(s) to make callout visible! Bug in IE         
        this._animatedElement.style.filter = "";       
    }       
}

ITkey.Web.UI.Animations.FadeAnimation.registerClass('ITkey.Web.UI.Animations.FadeAnimation', ITkey.Web.UI.Animations.ShowHideAnimation);

/****************************************************************************************************************
 *                                                  SimpleResize animation 
 ****************************************************************************************************************/
 ITkey.Web.UI.Animations.SimpleResizeAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    ITkey.Web.UI.Animations.SimpleResizeAnimation.initializeBase(this, [controller, duration, fps, animatedElement, position, sourceElement]);            
};

ITkey.Web.UI.Animations.SimpleResizeAnimation.prototype = 
{         
    _modifyAnimationValues : function(animValues)
    {      					
	},
	
	_configureAnimation : function(animValues)
    {        
        ITkey.Web.UI.Animations.SimpleResizeAnimation.callBaseMethod(this, '_configureAnimation', [animValues]);

		var anims = this._showAnimation.get_animations();
		var resizeAnim = anims[0];
		
		var startBounds = this._getStartBounds();
		// Modify the onStart of the resize animation as it sets as start(end)Width(Height) the offsetWidth(Height).
		// This is not correct in case the animated element has borders.
		resizeAnim.onStart = function()
		{
		     $TWA.ResizeAnimation.callBaseMethod(this, 'onStart');
        
            // Set the start and end values of the animations by getting
            // the element's current width and height
            var element = this.get_target();
            this._horizontalAnimation.set_startValue(startBounds.width);
            this._verticalAnimation.set_startValue(startBounds.height);
            this._horizontalAnimation.set_endValue((this._width !== null && this._width !== undefined) ?
                this._width : element.offsetWidth);
            this._verticalAnimation.set_endValue((this._height !== null && this._height !== undefined) ?
                this._height : element.offsetHeight);
		};
    },
	
	_configureAnimatedElement : function()
    {
        var target = this._animatedElement;        
        target.style.overflow = "hidden";
        target.style.display = "";
        target.style.visibility = "visible";  
    },
		
   _setHorizontalValues : function(animValues)
    {
        var horSide = this._getHorizontalPosition();
        var startBounds = this._getStartBounds();
        var endBound = this._getEndBounds();
                          
        animValues.startX = startBounds.x;
        animValues.endX = endBound.x;
    },
    
    _setVerticalValues : function(animValues)
    {
        var verSide = this._getVerticalPosition();                
        var startBounds = this._getStartBounds();
        var endBound = this._getEndBounds();
                                            
       animValues.startY = startBounds.y;
       animValues.endY = endBound.y;
    }
}

ITkey.Web.UI.Animations.SimpleResizeAnimation.registerClass('ITkey.Web.UI.Animations.SimpleResizeAnimation', ITkey.Web.UI.Animations.ResizeAnimation);
 
 

 
ITkey.Web.UI.Animations.ScrollAnimation = function(controller, duration, fps, animatedElement, position, sourceElement) 
{                 
    ITkey.Web.UI.Animations.ScrollAnimation.initializeBase(this, [controller, duration, fps, animatedElement, position, sourceElement]);            
    
    //HACK: Remove the fade animation - after the FUTURES we will rework the ITkeyAnimations!
    var anims = this._showAnimation.get_animations();    
    if (anims[3])
    {        
        this._showAnimation.remove(anims[3]);
    }
    
};

ITkey.Web.UI.Animations.ScrollAnimation.prototype = 
{         
    //Override to empty
    _modifyAnimationValues : function(animValues)
    {      					
	},
	
	//Override to empty
	 _configureAnimatedElement : function()
    {
         //Called too late, so do not set anything to the element here         
    },
		
   _setHorizontalValues : function(animValues)
    {                  
        var startBounds = this._getStartBounds();                
        var popupBounds = this._getEndBounds();

        var horSide = this._getHorizontalPosition();                               
        switch(horSide)
        {
            //Center - currently not used, but with two dimensions it will!
            case 2:                            
                animValues.startX = startBounds.x;
                animValues.endX = startBounds.x;
                break;
            
            //Right
            case 3:              
                animValues.startX = startBounds.x;
                animValues.endX = startBounds.x + popupBounds.x;
                break;                
            //Left            
            case 1:                                                 
                animValues.startX = startBounds.x;                                    
                animValues.endX = startBounds.x - popupBounds.x;          
        }
        //alert(horSide +  " Start x=" + animValues.startX + " " +   animValues.endX);      
    },
    
    _setVerticalValues : function(animValues)
    {
        var verSide = this._getVerticalPosition();                
        
        var startBounds = this._getStartBounds();   
        var popupBounds = this._getEndBounds();
         //Compute the vertical coordinate
        switch(verSide)
        {
            //Middle
            case 2:                                               
               animValues.startY = popupBounds.y;
               animValues.endY = popupBounds.y;
               break;
            //Top    
            case 1:               
               animValues.startY = startBounds.y;
               animValues.endY = startBounds.y - popupBounds.y;
               break;
            //Bottom
            case 3:
               animValues.startY = startBounds.y;
               animValues.endY = startBounds.y + popupBounds.y;             
        }
        
        //alert(verSide + " Vertical values =" + animValues.startY + " " +   animValues.endY);              
    }
};

ITkey.Web.UI.Animations.ScrollAnimation.registerClass('ITkey.Web.UI.Animations.ScrollAnimation', ITkey.Web.UI.Animations.ResizeAnimation);	

if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();