﻿/*********************************************
 *
 *  Funzioni per l'animazione degli oggetti DOM
 *  Autore: Roberto Roncato
 *  Copyright: Softimax 2006
 * 
 *  Versione 1: 11/07/2006
 *  Versione 1.1: 05/2008       (Deluxe Portal)
 *  Versione 1.2: 19/05/2008    (Opacity)
 *  Versione 1.3: 11/08/2009    Modificata la nomenclatura generale
 *  Versione 1.4: 01/08/2011	Aggiunta la possibilità di impostare una CssClass all'oggetto al termine dell'animazione
 *
 *********************************************
 
Usage:

    MO_SetAnimationParams(newLeftSpeed, newTopSpeed, newWidthSpeed, newHeightSpeed, newOpacitySpeed, 
                          newMovingInterval, newSizingInterval, newFadingInterval)
        Note:
        Speed parameters are used for interpolation routine: default=0.2 
         With higher values, more speedest is movement. Range:  (0->1) excluded
         Interval parameters are used for frequency of execution: default=50 msec
        Lower value increments fluidity but many systems are uncapable of
         respect timing below 40msec

    MO_MoveObjTo(objName, endLeft, endTop, endWidth, endHeight, endOpacity)
    

Library for external use:
    
    MO_MOVING_OBJECT_DEFINED        
        Note: if this value = 1 then this Javascript is loaded

    MO_ChangeOpacity(styleOfObject, opacity) 
    MO_SetOpacity(object, opacity)     
        Note: opacity value range: 0->100
        
    MO_GetMouseCoordsForTarget(evnt)
        Note: 
        evnt is the event object IE&FireFox compatible. You can use like this:
         <div id="parent" onmousemove="foo( MO_GetMouseCoordsForTarget(event) , 'other param');">
            <div id="child"></div>
         </div>
        The function return an object with 3 properties (x, y, objectId) 
         X and Y are mouse coords relative to the object, not to the page.
         objectId is the id of the object than fire the event. Sometimes could be a child object of
         our object ("child" in example), so eval this if is important and modify x or y if needed
    
 */





var MO_MOVING_OBJECT_DEFINED = 1;

/* Sistema di array per permettere più animazioni 
 * contemporaneamente
 */
var MO_AnimatedObjects = new Array();
var MO_AnimatedObjectsOpacity = new Array();
var MO_AnimatedObjectsPosX = new Array();
var MO_AnimatedObjectsPosY = new Array();
var MO_AnimatedObjectsSizeX = new Array();
var MO_AnimatedObjectsSizeY = new Array();
var MO_FadingTimeout = new Array();
var MO_MovingTimeout = new Array();
var MO_SizingTimeout = new Array();
var MO_IsFading = new Array();
var MO_IsMoving = new Array();
var MO_IsSizing = new Array();
var MO_CSSClass = new Array();
function MO_FindObjIndex(objName)
{
    var i = 0;
    var size = MO_AnimatedObjects.length;
    for (i=0; i<size; i++)
    {
        if ( MO_AnimatedObjects[i]== objName)
        {
            MO_AnimatedObjectsOpacity[i] = -1;
            MO_AnimatedObjectsPosX[i] = -1;
            MO_AnimatedObjectsPosY[i] = -1;
            MO_AnimatedObjectsSizeX[i] = -1;
            MO_AnimatedObjectsSizeY[i] = -1;
            return i;
        }
    }
    
    // Oggetto non creato: ne aggiungo uno nuovo
    MO_FadingTimeout.push(0);
    MO_MovingTimeout.push(0);
    MO_SizingTimeout.push(0);
    MO_IsFading.push(false);
    MO_IsMoving.push(false);
    MO_IsSizing.push(false);
    MO_AnimatedObjectsOpacity.push(-1);
    MO_AnimatedObjectsPosX.push(-1);
    MO_AnimatedObjectsPosY.push(-1);
    MO_AnimatedObjectsSizeX.push(-1);
    MO_AnimatedObjectsSizeY.push(-1);
    MO_AnimatedObjects.push(objName);
    return MO_AnimatedObjects.length-1;
}

/*  Routine che si occupa di attivare l'animazione (interrompendo
 *  quella in corso se necessario)
 *
 *  Parametri:
 *   objName        Nome dell'oggetto da spostare
 *   endLeft...     Coordinate volute alla fine dell'animazione
 *
 *  Da notare che se left=top=-1 l'animazione sarà effettuata solo
 *  per il dimensionamento. Se width=height=-1 l'animazione sarà
 *  effettuata solo per il posizionamento 
 */
function MO_MoveObjTo(objName, endLeft, endTop, endWidth, endHeight, endOpacity)
{
	MO_MoveObjTo(objName, endLeft, endTop, endWidth, endHeight, endOpacity, "");
}
function MO_MoveObjTo(objName, endLeft, endTop, endWidth, endHeight, endOpacity, endCssClass)
{
    var idx = MO_FindObjIndex(objName);
    if (isNaN(endOpacity)) endOpacity = -1;
    if (endOpacity==null) endOpacity = -1;
    if (isNaN(endLeft)) endLeft =-1;
    if (endLeft==null) endLeft =-1;
    if (isNaN(endTop)) endTop =-1;
    if (endTop==null) endTop =-1;
    if (isNaN(endWidth)) endWidth =-1;
    if (endWidth==null) endWidth =-1;
    if (isNaN(endHeight)) endHeight =-1;
    if (endHeight==null) endHeight =-1;
        
	MO_CSSClass[idx] = endCssClass;
	
    if ((endLeft!=-1) || (endTop!=-1))
    {
        if ( MO_IsMoving[idx] )
        {
            MO_IsMoving[idx] = false;
            window.clearTimeout(MO_MovingTimeout[idx]);
        }            
        if ((endLeft!=-1) && (endTop!=-1))
            MO_MoveObjWithAnimation(objName, idx, endLeft, endTop);
        else if (endLeft!=-1)
            MO_MoveObjWithAnimation(objName, idx, endLeft, -1);
        else
            MO_MoveObjWithAnimation(objName, idx, -1, endTop);
    }

    if ((endWidth!=-1) || (endHeight!=-1))
    {
        if ( MO_IsSizing[idx] )
        {
            MO_IsSizing[idx] = false;
            window.clearTimeout(MO_SizingTimeout[idx]);
        }
        if ((endWidth!=-1) && (endHeight!=-1))
            MO_SizeObjWithAnimation(objName, idx, endWidth, endHeight);
        else if (endWidth!=-1)
            MO_SizeObjWithAnimation(objName, idx, endWidth, -1);
        else
            MO_SizeObjWithAnimation(objName, idx, -1, endHeight);
    }
    
    if (endOpacity!=-1)
    {
        if ( MO_IsFading[idx] )
        {
            MO_IsFading[idx] = false;
            window.clearTimeout(MO_FadingTimeout[idx]);
        }            
        MO_FadeObjWithAnimation(objName, idx, endOpacity);
    }
	
	MO_SetCssClassAfterAnimation(objName, idx);
}        


/* Recupero lo stile degli elementi da animare
 */
var MO_ie = (document.all)?true:false;
var MO_ns4 = (document.layers)?true:false;
function MO_GetObjForMoving(objName)
{   
    var objMove;
    
    if (MO_ie) 
        objMove = document.all[objName];
    else if (MO_ns4) 
        objMove = document.layers[objName]; 
    else 
        objMove = document.getElementById(objName);
        
    return objMove;
}


/* Trovo il valore intermedio con il valore approssimato
 *  dell'equazione del moto accelerato 
 */
function MO_Interpolation(actualValue, endValue, speed)
{
    if ( isNaN(actualValue) ) actualValue = 0;
    
    var newValue = ((actualValue*(1-speed)) + (endValue*speed));
    
    // Correzione
    //if ( (newValue==actualValue) && (newValue!=endValue) )
    //{
        if (newValue<(endValue-1))
            newValue++;
        else if (newValue>(endValue+1))
            newValue--;                
        else
            newValue = endValue;     
    //}
    return newValue;        
}


/* Impostazione dei parametri dell'animazione
 */
var MO_OpacitySpeed = 0.2;
var MO_LeftSpeed = 0.2;
var MO_TopSpeed = 0.2;
var MO_WidthSpeed = 0.2;
var MO_HeightSpeed = 0.2;
var MO_FadingInterval = 50;
var MO_MovingInterval = 50;
var MO_SizingInterval = 50;
function MO_SetAnimationParams(newLeftSpeed, newTopSpeed, newWidthSpeed, newHeightSpeed, newOpacitySpeed, newMovingInterval, newSizingInterval, newFadingInterval)
{
    MO_OpacitySpeed = newOpacitySpeed;
    MO_LeftSpeed = newLeftSpeed;
    MO_TopSpeed = newTopSpeed;
    MO_WidthSpeed = newWidthSpeed;
    MO_HeightSpeed = newHeightSpeed;
    MO_FadingInterval = newFadingInterval;
    MO_MovingInterval = newMovingInterval;
    MO_SizingInterval = newSizingInterval;
}


/* Routine di animazione che richiamano se stesse fino a quando
 * l'oggetto non è alla posizione/dimensione voluta.
 */
function MO_FadeObjWithAnimation(objName, idx, endOpacity)
{
    if (objName=="") 
        return;
    
    var objMove = MO_GetObjForMoving(objName);
    var objStyle = objMove.style;
    var blnRepeat = false;
    var oldVal;
    var newVal;
    
    if (endOpacity!=-1)
    {
        oldVal = 100 * parseFloat(objStyle.opacity)
        if ( MO_AnimatedObjectsOpacity[idx]==-1 ) MO_AnimatedObjectsOpacity[idx] = oldVal;
        MO_AnimatedObjectsOpacity[idx] = MO_Interpolation( MO_AnimatedObjectsOpacity[idx], endOpacity, MO_OpacitySpeed);
        newVal = parseFloat(MO_AnimatedObjectsOpacity[idx]);
        if ( oldVal!=newVal ) blnRepeat = true;
        MO_ChangeOpacity(objStyle, newVal);
    }
    
    if (blnRepeat)
    {
        MO_IsFading[idx] = true;
        MO_FadingTimeout[idx] = window.setTimeout("MO_FadeObjWithAnimation('" + objName + "'," + idx + "," + endOpacity + ")", MO_FadingInterval);
    }
    else
    {
        MO_IsFading[idx] = false;
        MO_FadingTimeout[idx] = 0;
		MO_SetCssClassAfterAnimation(objName, idx);
    }   
}
function MO_MoveObjWithAnimation(objName, idx, endLeft, endTop)
{
    if (objName=="") 
        return;
    
    var objMove = MO_GetObjForMoving(objName);
    var objStyle = objMove.style;
    var blnRepeat = false;
    var oldVal;
    var newVal;
    
    if (endLeft!=-1)
    {
        oldVal = parseInt(objStyle.left)
        if ( MO_AnimatedObjectsPosX[idx]==-1 ) MO_AnimatedObjectsPosX[idx] = oldVal;
        MO_AnimatedObjectsPosX[idx] = MO_Interpolation( MO_AnimatedObjectsPosX[idx], endLeft, MO_LeftSpeed);
        newVal = parseInt(MO_AnimatedObjectsPosX[idx]);
        if ( oldVal!=newVal ) blnRepeat = true;
        objStyle.left = newVal + "px";
    }
    
    if (endTop != -1)
    {
        oldVal = parseInt(objStyle.top)
        if ( MO_AnimatedObjectsPosY[idx]==-1 ) MO_AnimatedObjectsPosY[idx] = oldVal;
        MO_AnimatedObjectsPosY[idx] = MO_Interpolation( MO_AnimatedObjectsPosY[idx], endTop, MO_TopSpeed);
        newVal = parseInt(MO_AnimatedObjectsPosY[idx]);
        if ( oldVal!=newVal ) blnRepeat = true;
        objStyle.top = newVal + "px";
    }
    
    if (blnRepeat)
    {
        MO_IsMoving[idx] = true;
        MO_MovingTimeout[idx] = window.setTimeout("MO_MoveObjWithAnimation('" + objName + "'," + idx + "," + endLeft + "," + endTop + ")", MO_MovingInterval);
    }
    else
    {
        MO_IsMoving[idx] = false;
        MO_MovingTimeout[idx] = 0;
		MO_SetCssClassAfterAnimation(objName, idx);
    }   
}
function MO_SizeObjWithAnimation(objName, idx, endWidth, endHeight)
{
    if (objName=="") 
        return;
    
    var objMove = MO_GetObjForMoving(objName);
    var objStyle = objMove.style;

    var blnRepeat = false;
    var oldVal;
    var newVal;
    
    if (endWidth!=-1)
    {
        oldVal = parseInt(objStyle.width)
        if ( MO_AnimatedObjectsSizeX[idx]==-1 ) MO_AnimatedObjectsSizeX[idx] = oldVal;
        MO_AnimatedObjectsSizeX[idx] = MO_Interpolation( oldVal, endWidth, MO_WidthSpeed);
        newVal = parseInt(MO_AnimatedObjectsSizeX[idx]);
        if ( oldVal!=newVal ) blnRepeat = true;
        objStyle.width= newVal + "px";
    }

    if (endHeight !=-1)
    {
        oldVal = parseInt(objStyle.height)
        if ( MO_AnimatedObjectsSizeY[idx]==-1 ) MO_AnimatedObjectsSizeY[idx] = oldVal;
        MO_AnimatedObjectsSizeY[idx] = MO_Interpolation( oldVal, endHeight, MO_HeightSpeed);
        newVal = parseInt(MO_AnimatedObjectsSizeY[idx]);
        if ( oldVal!=newVal ) blnRepeat = true;
        objStyle.height= newVal + "px";
    }
    
    //objStyle.clip = "rect(0px " + (parseInt(objStyle.width)+2) + "px " + (parseInt(objStyle.height)+2) + "px 0px)";
    
    if (blnRepeat)
    {
        MO_IsSizing[idx] = true;
        MO_SizingTimeout[idx] = window.setTimeout("MO_SizeObjWithAnimation('" + objName + "'," + idx + "," + endWidth + "," + endHeight + ")", MO_SizingInterval);
    }
    else
    {
        MO_IsSizing[idx] = false;
        MO_SizingTimeout[idx] = 0;
		MO_SetCssClassAfterAnimation(objName, idx);
    }   
}
function MO_SetCssClassAfterAnimation(objName, idx)
{
	if ((!MO_IsFading[idx]) && (!MO_IsMoving[idx]) && (!MO_IsSizing[idx]))
	{
		if (MO_CSSClass[idx] != "")
		{
			var objMove = MO_GetObjForMoving(objName);
			objMove.className = MO_CSSClass[idx];
		}
	}
}

//change the opacity for different browsers 
function MO_ChangeOpacity(objStyle, opacity) 
{ 
    objStyle.opacity = (opacity / 100); 
    objStyle.MozOpacity = (opacity / 100); 
    objStyle.KhtmlOpacity = (opacity / 100); 
    objStyle.filter = "alpha(opacity=" + opacity + ")"; 
}
function MO_SetOpacity(objName, opacity) 
{
    var objMove = MO_GetObjForMoving(objName);
    var objStyle = objMove.style;
    MO_ChangeOpacity(objStyle, opacity);
}
function MO_GetMouseCoordsForTarget(evnt)
{
    var coords = { x: 0, y: 0, objectId: ""};

    if(window.event) // then we have a non-DOM (probably IE)  browser
    {
            evnt = window.event;
            coords.x = evnt.offsetX;
            coords.y = evnt.offsetY;
            coords.objectId = evnt.srcElement.id;
    }
    else       // we assume DOM modeled  javascript
    {
            var Element = evnt.target;
            var CalculatedTotalOffsetLeft = 0;
            var CalculatedTotalOffsetTop = 0 ;
            
            while (Element.offsetParent)
            {
                    CalculatedTotalOffsetLeft += Element.offsetLeft ;     
                    CalculatedTotalOffsetTop += Element.offsetTop ;
                    Element = Element.offsetParent ;
            }

            coords.objectId = evnt.target.id;
            coords.x = evnt.pageX - CalculatedTotalOffsetLeft ;
            coords.y = evnt.pageY - CalculatedTotalOffsetTop ;
    }

    return coords;
}
