/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: fxseshun.h,v 1.1.24.1 2004/07/09 01:51:43 hubbe Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 or later (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

#ifndef _FXSESHUN_H
#define _FXSESHUN_H

class PXEffectsManager;

class PXEffectSession : public CHXBaseCountingObject,
                        public CUnknownIMP
{
    DECLARE_UNKNOWN_NOCREATE(PXEffectSession)
public:
    PXEffectSession();
    virtual ~PXEffectSession();

    virtual HX_RESULT Init(PXEffectsManager*  pEffectsManager,
                           PXEffect*          pEffect,
                           PXImageManager*    pImageManager,
                           IHXErrorMessages* pErrorMessages) = 0;
    virtual HX_RESULT Execute(UINT32 ulTime) = 0;

    BOOL              IsFinished()                        const { return m_bFinished;          }
    void              SetFinished(BOOL bFinished)               { m_bFinished = bFinished;     }
    BOOL              IsDisplayDamaged()                  const { return m_bDisplayDamaged;    }
    void              GetDamageRect(HXxRect& rDamageRect) const { rDamageRect = m_cDamageRect; }
    void              ResetDamage();
    HX_RESULT         GetEffect(PXEffect** ppEffect);
    BOOL              NeedsPostDurationUpdate() const;
    HX_RESULT         ReleaseTargetImage();
    UINT32            GetPostDurationExpirationTime()     const    { return m_ulPostDurationExpirationTime;   }
    void              SetPostDurationExpirationTime(UINT32 ulTime) { m_ulPostDurationExpirationTime = ulTime; }
    BOOL              MaxFramesPerSecondCheck(UINT32 ulTime);
    BOOL              GetDelayedInit() const     { return m_bDelayedInit;  }
    void              SetDelayedInit(BOOL bFlag) { m_bDelayedInit = bFlag; }
    void              SetEffect(PXEffect* pEffect);
    BOOL              IsFirstExe() const         { return m_bFirstExe;     }
protected:
    PXEffectsManager*  m_pEffectsManager;
    PXEffect*          m_pEffect;
    PXImageManager*    m_pImageManager;
    IHXErrorMessages* m_pErrorMessages;
    PXImage*           m_pDstImage;
    HXxRect            m_cDamageRect;
    BOOL               m_bDisplayDamaged;
    BOOL               m_bInitialized;
    BOOL               m_bFinished;
    UINT32             m_ulPostDurationExpirationTime;
    BOOL               m_bFirstExe;
    UINT32             m_ulLastExeTime;
    BOOL               m_bDelayedInit;

    void               Reset();
    void               Deallocate();
};

inline void PXEffectSession::SetEffect(PXEffect* pEffect)
{
    if (pEffect)
    {
        HX_RELEASE(m_pEffect);
        m_pEffect = pEffect;
        m_pEffect->AddRef();
    }
}

class PXFillEffectSession : public PXEffectSession
{
    DECLARE_COM_CREATE_FUNCS(PXFillEffectSession)
public:
    PXFillEffectSession() {};

    ~PXFillEffectSession() {};

    HX_RESULT Init(PXEffectsManager*  pEffectsManager,
                   PXEffect*          pEffect,
                   PXImageManager*    pImageManager,
                   IHXErrorMessages* pErrorMessages);
    HX_RESULT Execute(UINT32 ulTime);
protected:
};

class PXFadeOutEffectSession : public PXEffectSession
{
    DECLARE_COM_CREATE_FUNCS(PXFadeOutEffectSession)
public:
    PXFadeOutEffectSession()
    {
        m_bRecursive = FALSE;
        m_pDstCopy   = NULL;
    };

    ~PXFadeOutEffectSession()
    {
        HX_RELEASE(m_pDstCopy);
    }

    HX_RESULT Init(PXEffectsManager*  pEffectsManager,
                   PXEffect*          pEffect,
                   PXImageManager*    pImageManager,
                   IHXErrorMessages* pErrorMessages);
    HX_RESULT Execute(UINT32 ulTime);
protected:
    PXImage* m_pDstCopy;
    BOOL     m_bRecursive;
};

class PXFadeInEffectSession : public PXEffectSession
{
    DECLARE_COM_CREATE_FUNCS(PXFadeInEffectSession)
public:
    PXFadeInEffectSession()
    {
        m_pStartImage   = NULL;
        m_pEndImage     = NULL;
        m_bRecursive    = FALSE;
    };

    ~PXFadeInEffectSession()
    {
        HX_RELEASE(m_pStartImage);
        HX_RELEASE(m_pEndImage);
    };

    HX_RESULT Init(PXEffectsManager*  pEffectsManager,
                   PXEffect*          pEffect,
                   PXImageManager*    pImageManager,
                   IHXErrorMessages* pErrorMessages);
    HX_RESULT Execute(UINT32 ulTime);
protected:
    PXImage* m_pStartImage;
    PXImage* m_pEndImage;
    BOOL     m_bRecursive;
};

class PXWipeEffectSession : public PXEffectSession
{
    DECLARE_COM_CREATE_FUNCS(PXWipeEffectSession)
public:
    PXWipeEffectSession()
    {
        m_pStartImage   = NULL;
        m_pEndImage     = NULL;
        m_bRecursive    = FALSE;
        m_bFirstTime    = TRUE;
    };

    ~PXWipeEffectSession()
    {
        HX_RELEASE(m_pStartImage);
        HX_RELEASE(m_pEndImage);
    };

    HX_RESULT Init(PXEffectsManager*  pEffectsManager,
                   PXEffect*          pEffect,
                   PXImageManager*    pImageManager,
                   IHXErrorMessages* pErrorMessages);
    HX_RESULT Execute(UINT32 ulTime);
protected:
    PXImage* m_pStartImage;
    PXImage* m_pEndImage;
    BOOL     m_bRecursive;
    BOOL     m_bFirstTime;
};

class PXViewchangeEffectSession : public PXEffectSession
{
    DECLARE_COM_CREATE_FUNCS(PXViewchangeEffectSession)
public:
    PXViewchangeEffectSession()
    {
        m_bSrcChanges         = FALSE;
        m_bDstChanges         = FALSE;
        m_bDstMoves           = FALSE;
        m_bRestoreDst         = FALSE;
        m_cRestoreRect.left   = 0;
        m_cRestoreRect.top    = 0;
        m_cRestoreRect.right  = 0;
        m_cRestoreRect.bottom = 0;
        m_pSrcImage           = NULL;
        m_pPrevDst            = NULL;
    };

    ~PXViewchangeEffectSession()
    {
        HX_RELEASE(m_pSrcImage);
        HX_RELEASE(m_pPrevDst);
    };

    HX_RESULT Init(PXEffectsManager*  pEffectsManager,
                   PXEffect*          pEffect,
                   PXImageManager*    pImageManager,
                   IHXErrorMessages* pErrorMessages);
    HX_RESULT Execute(UINT32 ulTime);
protected:
    BOOL      m_bSrcChanges;
    BOOL      m_bDstChanges;
    BOOL      m_bDstMoves;
    BOOL      m_bRestoreDst;
    HXxRect   m_cRestoreRect;
    PXImage*  m_pSrcImage;
    PXImage*  m_pPrevDst;

    HX_RESULT SizeAspectCopy(PXImage* pSrcImage, PXImage* pDstImage,
	                     BOOL bAspectFlag, UINT32 ulBackgroundColor);
};

class PXSimpleViewchangeEffectSession : public PXEffectSession
{
    DECLARE_COM_CREATE_FUNCS(PXSimpleViewchangeEffectSession)
public:
    PXSimpleViewchangeEffectSession()
    {
        m_bRestoreDst         = FALSE;
        m_cRestoreRect.left   = 0;
        m_cRestoreRect.top    = 0;
        m_cRestoreRect.right  = 0;
        m_cRestoreRect.bottom = 0;
        m_pPrevDst            = NULL;
    };

    ~PXSimpleViewchangeEffectSession()
    {
        HX_RELEASE(m_pPrevDst);
    };

    HX_RESULT Init(PXEffectsManager*  pEffectsManager,
                   PXEffect*          pEffect,
                   PXImageManager*    pImageManager,
                   IHXErrorMessages* pErrorMessages);
    HX_RESULT Execute(UINT32 ulTime);
protected:
    BOOL      m_bRestoreDst;
    HXxRect   m_cRestoreRect;
    PXImage*  m_pPrevDst;
};

class PXExternalEffectSession : public PXEffectSession
{
    DECLARE_COM_CREATE_FUNCS(PXExternalEffectSession)
public:
    PXExternalEffectSession()
    {
        m_pEffectsPackage = NULL;
        m_pStartImage     = NULL;
        m_pEndImage       = NULL;
    };

    ~PXExternalEffectSession()
    {
        HX_RELEASE(m_pEffectsPackage);
        HX_RELEASE(m_pStartImage);
        HX_RELEASE(m_pEndImage);
    };

    HX_RESULT Init(PXEffectsManager*  pEffectsManager,
                   PXEffect*          pEffect,
                   PXImageManager*    pImageManager,
                   IHXErrorMessages* pErrorMessages);
    HX_RESULT Execute(UINT32 ulTime);
protected:
    IIMFEffect* m_pEffectsPackage;
    INT32       m_lHandle;
    PXImage*    m_pStartImage;
    PXImage*    m_pEndImage;
};

class PXAnimationSession : public PXEffectSession
{
    DECLARE_COM_CREATE_FUNCS(PXAnimationSession)
public:
    PXAnimationSession()
    {
        m_ulNumFrames      = 0;
        m_ulCycleTime      = 0;
        m_pulNextFrameTime = NULL;
        m_ulCurrentFrame   = 0xFFFFFFFF;
    };

    ~PXAnimationSession()
    {
        HX_VECTOR_DELETE(m_pulNextFrameTime);
    };

    HX_RESULT Init(PXEffectsManager*  pEffectsManager,
                   PXEffect*          pEffect,
                   PXImageManager*    pImageManager,
                   IHXErrorMessages* pErrorMessages);
    HX_RESULT Execute(UINT32 ulTime);
protected:
    UINT32    m_ulNumFrames;
    UINT32    m_ulCycleTime;
    UINT32*   m_pulNextFrameTime;
    UINT32    m_ulCurrentFrame;

    HX_RESULT ComputeFrameToDisplay(UINT32 ulTime, UINT32 ulStart, UINT32* pulFrameNum);
    HX_RESULT GetClippedImages(PXImage* pSrc, const HXxRect& rFrameRect,
                               PXImage* pDst, PXEffect* pEffect,
                               PXImage* pSrcFrame, PXImage* pDstFrame, BOOL* pbDoCopy);
};

#define LINEAR_PARAM(x1, x2, t, d, d2)  ((x1) + (((x2) - (x1)) * (t) + (d2)) / (d))

#endif
