/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: effect.cpp,v 1.2.24.1 2004/07/09 01:52:03 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 ***** */

#include "hxtypes.h"
#include "hxcom.h"
#include "hxcomm.h"
#include "hxstring.h"
#include "baseobj.h"
#include "effect.h"
#include "rpfilobj.h"

#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE		
static char HX_THIS_FILE[] = __FILE__;
#endif


char CIMFEffect::m_pszStart[]                  = "start";
char CIMFEffect::m_pszDuration[]               = "duration";
char CIMFEffect::m_pszTarget[]                 = "target";
char CIMFEffect::m_pszAspect[]                 = "aspect";
char CIMFEffect::m_pszWipeDirection[]          = "direction";
char CIMFEffect::m_pszWipeType[]               = "type";
char CIMFEffect::m_pszURL[]                    = "url";
char CIMFEffect::m_pszMaxFps[]				   = "maxfps";
char CIMFEffect::m_pszPackage[]                = "package";
char CIMFEffect::m_pszName[]                   = "name";
char CIMFEffect::m_pszData[]                   = "data";
char CIMFEffect::m_pszFile[]                   = "file";
char CIMFWipeEffect::m_pszWipeDirectionUp[]    = "up";
char CIMFWipeEffect::m_pszWipeDirectionDown[]  = "down";
char CIMFWipeEffect::m_pszWipeDirectionLeft[]  = "left";
char CIMFWipeEffect::m_pszWipeDirectionRight[] = "right";
char CIMFWipeEffect::m_pszWipeTypeNormal[]     = "normal";
char CIMFWipeEffect::m_pszWipeTypePush[]       = "push";

/////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////
CIMFEffect::CIMFEffect() : 
	m_ulStart(0)
    ,	m_cDstRect()
    ,	m_cURL()
    ,	m_ulMaxFps(0)
    ,	m_bFirstUse(FALSE)
    ,	m_bLastUse(FALSE)
    ,	m_pFileObject(NULL)
    ,	m_cErrorMessage()
{
};

CIMFEffect::CIMFEffect(CIMFFileObject *pFileObject) : 
	m_cDstRect()
    ,	m_cURL()
    ,	m_cErrorMessage()
{
    m_ulStart     = 0;
    m_ulMaxFps    = 0;
    m_bFirstUse   = FALSE;
    m_bLastUse    = FALSE;
    m_pFileObject = pFileObject;
};

CIMFEffect::CIMFEffect(const CIMFEffect &rEffect) : 
	m_ulStart(rEffect.m_ulStart)
    ,	m_cDstRect(rEffect.m_cDstRect)
    ,	m_cURL(rEffect.m_cURL)
    ,	m_ulMaxFps(rEffect.m_ulMaxFps)
    ,	m_bFirstUse(rEffect.m_bFirstUse)
    ,	m_bLastUse(rEffect.m_bLastUse)
    ,	m_pFileObject(rEffect.m_pFileObject)
    ,	m_cErrorMessage(rEffect.m_cErrorMessage)
{
}

CIMFEffect::~CIMFEffect() 
{
};


ULONG32 CIMFFadeinEffect::GetBinaryLength()
{
    return 54 + 4 + m_cURL.length();
}

ULONG32 CIMFFadeinEffect::RenderBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;

    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, (ULONG32) kTypeFadeIn);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
	ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulTarget);
    ulCurPos += m_cSrcRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_bAspectFlag);
    
    return ulCurPos;
}

ULONG32 CIMFFadeinEffect::InitFromBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;
    ULONG32 ulTmp;

    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, ulTmp); // This is the type
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulStart);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
	ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulTarget);
    ulCurPos += m_cSrcRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_bAspectFlag);
    
    return ulCurPos;
}

void CIMFFadeinEffect::RenderText(GString &rText)
{
    rText += CIMFFileObject::m_pszTagStart;
    rText += CIMFFileObject::m_pszFadeinTag;
    rText += " ";
    CIMFFileObject::RenderAttribute(m_pszStart,    m_ulStart,     rText);
	CIMFFileObject::RenderAttribute(m_pszDuration, m_ulDuration,  rText);
    CIMFFileObject::RenderAttribute(m_pszTarget,   m_ulTarget,    rText);
    
	m_cSrcRect.RenderText(rText);
    m_cDstRect.RenderText(rText);
    if (m_bAspectFlag != m_bAspectDefault)
    {
        CIMFFileObject::RenderAttribute(m_pszAspect, m_bAspectFlag, rText);
    }
    if (m_cURL.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszURL, m_cURL, rText);
    }
    rText += CIMFFileObject::m_pszTagEnd;
}

BOOL CIMFFadeinEffect::InitFromText(GString &rText)
{
    // Get the start time
    HX_RESULT retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                             m_pszStart,
                                                             m_pFileObject->GetTimeFormat(),
                                                             m_ulStart);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing start attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
    // Get the duration
    retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                   m_pszDuration,
                                                   m_pFileObject->GetTimeFormat(),
                                                   m_ulDuration);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing duration attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszStart,    m_ulStart))    return FALSE;
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszDuration, m_ulDuration)) return FALSE;
    if (!CIMFFileObject::SetAttributeValue(rText, m_pszTarget,   m_ulTarget))   return FALSE;

    // These are optional attributes
    m_cSrcRect.InitFromText(rText);
    m_cDstRect.InitFromText(rText);
    CIMFFileObject::SetAttributeValue(rText, m_pszURL, m_cURL);
	CIMFFileObject::SetAttributeValue(rText, m_pszMaxFps, m_ulMaxFps);
    if (!CIMFFileObject::SetAttributeValueBOOL(rText, m_pszAspect, m_bAspectFlag))
    {
        m_bAspectFlag = m_bAspectDefault;
    }

    return TRUE;
}

void CIMFFadeinEffect::RenderToolData(IMFEFFECT& imfEffect)
{

    imfEffect.m_ulBinSize        = GetBinaryLength();
    imfEffect.m_ulMaxFps         = GetMaxFps();
    imfEffect.m_ulStart          = GetStart();
    imfEffect.m_ulDuration       = GetDuration();
    imfEffect.m_bAspect          = GetAspectFlag();
    imfEffect.m_bDefaultAspect   = GetAspectDefault();
    imfEffect.m_ulTarget         = GetTargetImageHandle();
    imfEffect.m_ulType           = GetType();
    
    imfEffect.m_nSrc_x           = m_cSrcRect.GetX();
    imfEffect.m_nSrc_y           = m_cSrcRect.GetY();
    imfEffect.m_nSrc_W           = m_cSrcRect.GetWidth();
    imfEffect.m_nSrc_H           = m_cSrcRect.GetHeight();
    imfEffect.m_nDest_x          = m_cDstRect.GetX();
    imfEffect.m_nDest_y          = m_cDstRect.GetY();
    imfEffect.m_nDest_W          = m_cDstRect.GetWidth();
    imfEffect.m_nDest_H          = m_cDstRect.GetHeight();
    if (m_cURL.length() > 0)
        SafeStrCpy(imfEffect.m_cURL, GetURL().c_str(), 256);

}

BOOL CIMFFadeinEffect::InitFromToolData(IMFEFFECT imfEffect)
{
    // Set Attributes
    SetStart(imfEffect.m_ulStart);
    SetDefaultMaxFps(imfEffect.m_ulMaxFps);
    SetDuration(imfEffect.m_ulDuration);   
    SetAspectFlag(imfEffect.m_bAspect);
    SetAspectDefault(imfEffect.m_bDefaultAspect);
    SetTargetImageHandle(imfEffect.m_ulTarget);
    SetURL(imfEffect.m_cURL);
    m_cSrcRect.SetX(imfEffect.m_nSrc_x);
    m_cSrcRect.SetY(imfEffect.m_nSrc_y);
    m_cSrcRect.SetWidth(imfEffect.m_nSrc_W);
    m_cSrcRect.SetHeight(imfEffect.m_nSrc_H);
    m_cDstRect.SetX(imfEffect.m_nDest_x);
    m_cDstRect.SetY(imfEffect.m_nDest_y);
    m_cDstRect.SetWidth(imfEffect.m_nDest_W);
    m_cDstRect.SetHeight(imfEffect.m_nDest_H);
    return TRUE;    
}
/////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////
ULONG32 CIMFCrossfadeEffect::GetBinaryLength()
{
    return 54 + 4 + m_cURL.length();
}

ULONG32 CIMFCrossfadeEffect::RenderBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;

    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, (ULONG32) kTypeCrossFade);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulTarget);
    ulCurPos += m_cSrcRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_bAspectFlag);

    return ulCurPos;
}

ULONG32 CIMFCrossfadeEffect::InitFromBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;
    ULONG32 ulTmp;

    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, ulTmp); // This is the type
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulTarget);
    ulCurPos += m_cSrcRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_bAspectFlag);

    return ulCurPos;
}

void CIMFCrossfadeEffect::RenderText(GString &rText)
{
    rText += CIMFFileObject::m_pszTagStart;
    rText += CIMFFileObject::m_pszCrossfadeTag;
    rText += " ";
    CIMFFileObject::RenderAttribute(m_pszStart,    m_ulStart,     rText);
    CIMFFileObject::RenderAttribute(m_pszDuration, m_ulDuration,  rText);
    CIMFFileObject::RenderAttribute(m_pszTarget,   m_ulTarget,    rText);
    m_cSrcRect.RenderText(rText);
    m_cDstRect.RenderText(rText);
    if (m_bAspectFlag != m_bAspectDefault)
    {
        CIMFFileObject::RenderAttribute(m_pszAspect, m_bAspectFlag, rText);
    }
    if (m_cURL.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszURL, m_cURL, rText);
    }
    rText += CIMFFileObject::m_pszTagEnd;
}

BOOL CIMFCrossfadeEffect::InitFromText(GString &rText)
{
    // These are required attributes
    // Get the start time
    HX_RESULT retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                             m_pszStart,
                                                             m_pFileObject->GetTimeFormat(),
                                                             m_ulStart);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing start attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
    // Get the duration
    retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                   m_pszDuration,
                                                   m_pFileObject->GetTimeFormat(),
                                                   m_ulDuration);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing duration attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszStart,    m_ulStart))    return FALSE;
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszDuration, m_ulDuration)) return FALSE;
    if (!CIMFFileObject::SetAttributeValue(rText, m_pszTarget,   m_ulTarget))   return FALSE;

    // These are optional attributes
    m_cSrcRect.InitFromText(rText);
    m_cDstRect.InitFromText(rText);
    CIMFFileObject::SetAttributeValue(rText, m_pszURL, m_cURL);
	CIMFFileObject::SetAttributeValue(rText, m_pszMaxFps, m_ulMaxFps);
    if (!CIMFFileObject::SetAttributeValueBOOL(rText, m_pszAspect, m_bAspectFlag))
    {
        m_bAspectFlag = m_bAspectDefault;
    }

    return TRUE;
}

void CIMFCrossfadeEffect::RenderToolData(IMFEFFECT& imfEffect)
{
    imfEffect.m_ulBinSize        = GetBinaryLength();
    imfEffect.m_ulMaxFps         = GetMaxFps();
    imfEffect.m_ulStart          = GetStart();
    imfEffect.m_ulDuration       = GetDuration();
    imfEffect.m_bAspect          = GetAspectFlag();
    imfEffect.m_bDefaultAspect   = GetAspectDefault();
    imfEffect.m_ulTarget         = GetTargetImageHandle();
    imfEffect.m_ulType           = GetType();

    imfEffect.m_nSrc_x           = m_cSrcRect.GetX();
    imfEffect.m_nSrc_y           = m_cSrcRect.GetY();
    imfEffect.m_nSrc_W           = m_cSrcRect.GetWidth();
    imfEffect.m_nSrc_H           = m_cSrcRect.GetHeight();
    imfEffect.m_nDest_x          = m_cDstRect.GetX();
    imfEffect.m_nDest_y          = m_cDstRect.GetY();
    imfEffect.m_nDest_W          = m_cDstRect.GetWidth();
    imfEffect.m_nDest_H          = m_cDstRect.GetHeight();
    if (m_cURL.length() > 0)
        SafeStrCpy(imfEffect.m_cURL, GetURL().c_str(), 256);

    
}

BOOL CIMFCrossfadeEffect::InitFromToolData(IMFEFFECT imfEffect)
{
    SetStart(imfEffect.m_ulStart);
    SetDefaultMaxFps(imfEffect.m_ulMaxFps);
    SetDuration(imfEffect.m_ulDuration);   
    SetAspectFlag(imfEffect.m_bAspect);
    SetAspectDefault(imfEffect.m_bDefaultAspect);
    SetTargetImageHandle(imfEffect.m_ulTarget);
    SetURL(imfEffect.m_cURL);
    m_cSrcRect.SetX(imfEffect.m_nSrc_x);
    m_cSrcRect.SetY(imfEffect.m_nSrc_y);
    m_cSrcRect.SetWidth(imfEffect.m_nSrc_W);
    m_cSrcRect.SetHeight(imfEffect.m_nSrc_H);
    m_cDstRect.SetX(imfEffect.m_nDest_x);
    m_cDstRect.SetY(imfEffect.m_nDest_y);
    m_cDstRect.SetWidth(imfEffect.m_nDest_W);
    m_cDstRect.SetHeight(imfEffect.m_nDest_H);
    return TRUE;    
}

/////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////
ULONG32 CIMFFillEffect::GetBinaryLength()
{
    return 30 + 4 + m_cURL.length();
}

ULONG32 CIMFFillEffect::RenderBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;

    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, (ULONG32) kTypeFill);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += m_cColor.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.RenderBinary(pBuffer + ulCurPos);

    return ulCurPos;
}

ULONG32 CIMFFillEffect::InitFromBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;
    ULONG32 ulTmp;

    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, ulTmp); // This is the type
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += m_cColor.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.InitFromBinary(pBuffer + ulCurPos);

    return ulCurPos;
}

void CIMFFillEffect::RenderText(GString &rText)
{
    rText += CIMFFileObject::m_pszTagStart;
    rText += CIMFFileObject::m_pszFillTag;
    rText += " ";
    CIMFFileObject::RenderAttribute(m_pszStart, m_ulStart, rText);
    m_cColor.RenderText(rText);
    m_cDstRect.RenderText(rText);
    if (m_cURL.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszURL, m_cURL, rText);
    }
    rText += CIMFFileObject::m_pszTagEnd;
}

BOOL CIMFFillEffect::InitFromText(GString &rText)
{
    // Get the start time
    HX_RESULT retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                             m_pszStart,
                                                             m_pFileObject->GetTimeFormat(),
                                                             m_ulStart);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing start attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
    // Get the color
    if (!m_cColor.InitFromText(rText)) return FALSE;

    // These are optional attributes
    m_cDstRect.InitFromText(rText);
    CIMFFileObject::SetAttributeValue(rText, m_pszURL, m_cURL);
	CIMFFileObject::SetAttributeValue(rText, m_pszMaxFps, m_ulMaxFps);

    return TRUE;
}

void CIMFFillEffect::RenderToolData(IMFEFFECT& imfEffect)
{
    imfEffect.m_ulBinSize        = GetBinaryLength();
    imfEffect.m_ulMaxFps         = GetMaxFps();
    imfEffect.m_ulStart          = GetStart();
    imfEffect.m_ucRed            = m_cColor.GetRed();
    imfEffect.m_ucBlue           = m_cColor.GetBlue();
    imfEffect.m_ucGreen          = m_cColor.GetGreen();
    imfEffect.m_ulType           = GetType();

    imfEffect.m_nDest_x          = m_cDstRect.GetX();
    imfEffect.m_nDest_y          = m_cDstRect.GetY();
    imfEffect.m_nDest_W          = m_cDstRect.GetWidth();
    imfEffect.m_nDest_H          = m_cDstRect.GetHeight();
    if (m_cURL.length() > 0)
        SafeStrCpy(imfEffect.m_cURL, GetURL().c_str(), 256);
    
}

BOOL  CIMFFillEffect::InitFromToolData(IMFEFFECT imfEffect)
{
    SetDefaultMaxFps(imfEffect.m_ulMaxFps);
    SetStart(imfEffect.m_ulStart);
    SetURL(imfEffect.m_cURL);

    CIMFColor newColor(imfEffect.m_ucRed,imfEffect.m_ucBlue,imfEffect.m_ucGreen);
    m_cColor= newColor;

    m_cDstRect.SetX(imfEffect.m_nDest_x);
    m_cDstRect.SetY(imfEffect.m_nDest_y);
    m_cDstRect.SetWidth(imfEffect.m_nDest_W);
    m_cDstRect.SetHeight(imfEffect.m_nDest_H);

    return TRUE;    
}
/////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////
ULONG32 CIMFFadeoutEffect::GetBinaryLength()
{
    return 34 + 4 + m_cURL.length();
}

ULONG32 CIMFFadeoutEffect::RenderBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;

    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, (ULONG32) kTypeFadeOut);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += m_cColor.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.RenderBinary(pBuffer + ulCurPos);

    return ulCurPos;
}

ULONG32 CIMFFadeoutEffect::InitFromBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;
    ULONG32 ulTmp;

    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, ulTmp); // This is the type
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += m_cColor.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.InitFromBinary(pBuffer + ulCurPos);

    return ulCurPos;
}

void CIMFFadeoutEffect::RenderText(GString &rText)
{
    rText += CIMFFileObject::m_pszTagStart;
    rText += CIMFFileObject::m_pszFadeoutTag;
    rText += " ";
    CIMFFileObject::RenderAttribute(m_pszStart,    m_ulStart,     rText);
    CIMFFileObject::RenderAttribute(m_pszDuration, m_ulDuration,  rText);
    m_cColor.RenderText(rText);
    m_cDstRect.RenderText(rText);
    if (m_cURL.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszURL, m_cURL, rText);
    }
    rText += CIMFFileObject::m_pszTagEnd;
}

BOOL CIMFFadeoutEffect::InitFromText(GString &rText)
{
    // These are required attributes
    // Get the start time
    HX_RESULT retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                             m_pszStart,
                                                             m_pFileObject->GetTimeFormat(),
                                                             m_ulStart);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing start attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
    // Get the duration
    retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                   m_pszDuration,
                                                   m_pFileObject->GetTimeFormat(),
                                                   m_ulDuration);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing duration attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszStart,    m_ulStart))    return FALSE;
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszDuration, m_ulDuration)) return FALSE;
    if (!m_cColor.InitFromText(rText)) return FALSE;

    // These are optional attributes
    m_cDstRect.InitFromText(rText);
    CIMFFileObject::SetAttributeValue(rText, m_pszURL, m_cURL);
	CIMFFileObject::SetAttributeValue(rText, m_pszMaxFps, m_ulMaxFps);

    return TRUE;
}
void CIMFFadeoutEffect::RenderToolData(IMFEFFECT& imfEffect)
{
    imfEffect.m_ulBinSize        = GetBinaryLength();
    imfEffect.m_ulMaxFps         = GetMaxFps();
    imfEffect.m_ulStart          = GetStart();
    imfEffect.m_ulDuration       = GetDuration();
    imfEffect.m_ucRed            = m_cColor.GetRed();
    imfEffect.m_ucBlue           = m_cColor.GetBlue();
    imfEffect.m_ucGreen          = m_cColor.GetGreen();
    imfEffect.m_ulType           = GetType();
    imfEffect.m_nDest_x          = m_cDstRect.GetX();
    imfEffect.m_nDest_y          = m_cDstRect.GetY();
    imfEffect.m_nDest_W          = m_cDstRect.GetWidth();
    imfEffect.m_nDest_H          = m_cDstRect.GetHeight();
    if (m_cURL.length() > 0)
        SafeStrCpy(imfEffect.m_cURL, GetURL().c_str(), 256);
    
}

BOOL CIMFFadeoutEffect::InitFromToolData(IMFEFFECT imfEffect)
{
    SetStart(imfEffect.m_ulStart);
    SetDefaultMaxFps(imfEffect.m_ulMaxFps);
    SetDuration(imfEffect.m_ulDuration);
    SetURL(imfEffect.m_cURL);   
    
    CIMFColor newColor(imfEffect.m_ucRed,imfEffect.m_ucBlue,imfEffect.m_ucGreen);
    m_cColor= newColor;

    m_cDstRect.SetX(imfEffect.m_nDest_x);
    m_cDstRect.SetY(imfEffect.m_nDest_y);
    m_cDstRect.SetWidth(imfEffect.m_nDest_W);
    m_cDstRect.SetHeight(imfEffect.m_nDest_H);

    return TRUE;    
}
/////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////
ULONG32 CIMFWipeEffect::GetBinaryLength()
{
    return 62 + 4 + m_cURL.length();
}

ULONG32 CIMFWipeEffect::RenderBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;

    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, (ULONG32) kTypeWipe);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulType);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulDirection);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulTarget);
    ulCurPos += m_cSrcRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_bAspectFlag);

    return ulCurPos;
}

ULONG32 CIMFWipeEffect::InitFromBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;
    ULONG32 ulTmp;

    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, ulTmp); // This is the type
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulType);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulDirection);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulTarget);
    ulCurPos += m_cSrcRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_bAspectFlag);

    return ulCurPos;
}

void CIMFWipeEffect::RenderText(GString &rText)
{
    rText += CIMFFileObject::m_pszTagStart;
    rText += CIMFFileObject::m_pszWipeTag;
    rText += " ";
    CIMFFileObject::RenderAttribute(m_pszStart,    m_ulStart,     rText);
    CIMFFileObject::RenderAttribute(m_pszDuration, m_ulDuration,  rText);
    CIMFFileObject::RenderAttribute(m_pszTarget,   m_ulTarget,    rText);
    // Render direction
    rText += m_pszWipeDirection;
    rText += "=";
    switch (m_ulDirection)
    {
        case kDirectionUp:
            rText += m_pszWipeDirectionUp;
            break;
        case kDirectionDown:
            rText += m_pszWipeDirectionDown;
            break;
        case kDirectionLeft:
            rText += m_pszWipeDirectionLeft;
            break;
        case kDirectionRight:
            rText += m_pszWipeDirectionRight;
            break;
    }
    rText += " ";
    // Render type
    rText += m_pszWipeType;
    rText += "=";
    switch (m_ulType)
    {
        case kTypeNormal:
            rText += m_pszWipeTypeNormal;
            break;
        case kTypePush:
            rText += m_pszWipeTypePush;
            break;
    }
    rText += " ";
    m_cSrcRect.RenderText(rText);
    m_cDstRect.RenderText(rText);
    if (m_bAspectFlag != m_bAspectDefault)
    {
        CIMFFileObject::RenderAttribute(m_pszAspect, m_bAspectFlag, rText);
    }
    if (m_cURL.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszURL, m_cURL, rText);
    }
    rText += CIMFFileObject::m_pszTagEnd;
}

BOOL CIMFWipeEffect::InitFromText(GString &rText)
{
    // These are required attributes
    // Get the start time
    HX_RESULT retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                             m_pszStart,
                                                             m_pFileObject->GetTimeFormat(),
                                                             m_ulStart);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing start attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
    // Get the duration
    retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                   m_pszDuration,
                                                   m_pFileObject->GetTimeFormat(),
                                                   m_ulDuration);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing duration attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszStart,    m_ulStart))    return FALSE;
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszDuration, m_ulDuration)) return FALSE;
    if (!CIMFFileObject::SetAttributeValue(rText, m_pszTarget,   m_ulTarget))   return FALSE;

    // The following are optional attributes
    GString cTmpStr;
    CIMFFileObject::SetAttributeValue(rText, m_pszMaxFps, m_ulMaxFps);
    // Initialize the direction attribute
    if (CIMFFileObject::GetAttributeSubstring(rText, m_pszWipeDirection, cTmpStr))
    {
        if      (cTmpStr == m_pszWipeDirectionUp)    m_ulDirection = kDirectionUp;
        else if (cTmpStr == m_pszWipeDirectionDown)  m_ulDirection = kDirectionDown;
        else if (cTmpStr == m_pszWipeDirectionLeft)  m_ulDirection = kDirectionLeft;
        else if (cTmpStr == m_pszWipeDirectionRight) m_ulDirection = kDirectionRight;
    }
    // Initialize the type attribute
    if (CIMFFileObject::GetAttributeSubstring(rText, m_pszWipeType, cTmpStr))
    {
        if      (cTmpStr == m_pszWipeTypeNormal) m_ulType = kTypeNormal;
        else if (cTmpStr == m_pszWipeTypePush)   m_ulType = kTypePush;
    }
    m_cSrcRect.InitFromText(rText);
    m_cDstRect.InitFromText(rText);
    if (!CIMFFileObject::SetAttributeValueBOOL(rText, m_pszAspect, m_bAspectFlag))
    {
        m_bAspectFlag = m_bAspectDefault;
    }
    CIMFFileObject::SetAttributeValue(rText, m_pszURL, m_cURL);

    return TRUE;
}

void CIMFWipeEffect::RenderToolData(IMFEFFECT& imfEffect)
{
    imfEffect.m_ulBinSize        = GetBinaryLength();
    imfEffect.m_ulMaxFps         = GetMaxFps();
    imfEffect.m_ulStart          = GetStart();
    imfEffect.m_ulDuration       = GetDuration();
    imfEffect.m_ulDirection      = GetDirection();
    imfEffect.m_bAspect          = GetAspectFlag();
    imfEffect.m_bDefaultAspect   = GetAspectDefault();
    imfEffect.m_ulTarget         = GetTargetImageHandle();
    imfEffect.m_ulType           = GetType();

    imfEffect.m_nSrc_x           = m_cSrcRect.GetX();
    imfEffect.m_nSrc_y           = m_cSrcRect.GetY();
    imfEffect.m_nSrc_W           = m_cSrcRect.GetWidth();
    imfEffect.m_nSrc_H           = m_cSrcRect.GetHeight();
    imfEffect.m_nDest_x          = m_cDstRect.GetX();
    imfEffect.m_nDest_y          = m_cDstRect.GetY();
    imfEffect.m_nDest_W          = m_cDstRect.GetWidth();
    imfEffect.m_nDest_H          = m_cDstRect.GetHeight();
    if (m_cURL.length() > 0)
        SafeStrCpy(imfEffect.m_cURL, GetURL().c_str(), 256);
    
}

BOOL  CIMFWipeEffect::InitFromToolData(IMFEFFECT imfEffect)
{
    SetStart(imfEffect.m_ulStart);
    SetDefaultMaxFps(imfEffect.m_ulMaxFps);
    SetDuration(imfEffect.m_ulDuration);   
    SetAspectFlag(imfEffect.m_bAspect);
    SetAspectDefault(imfEffect.m_bDefaultAspect);
    SetTargetImageHandle(imfEffect.m_ulTarget);   
    SetURL(imfEffect.m_cURL);

    m_cSrcRect.SetX(imfEffect.m_nSrc_x);
    m_cSrcRect.SetY(imfEffect.m_nSrc_y);
    m_cSrcRect.SetWidth(imfEffect.m_nSrc_W);
    m_cSrcRect.SetHeight(imfEffect.m_nSrc_H);
    m_cDstRect.SetX(imfEffect.m_nDest_x);
    m_cDstRect.SetY(imfEffect.m_nDest_y);
    m_cDstRect.SetWidth(imfEffect.m_nDest_W);
    m_cDstRect.SetHeight(imfEffect.m_nDest_H);
    return TRUE;    
}
/////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////
ULONG32 CIMFViewchangeEffect::GetBinaryLength()
{
    return 46 + 4 + m_cURL.length();
}

ULONG32 CIMFViewchangeEffect::RenderBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;

    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, (ULONG32) kTypeViewChange);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += m_cSrcRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.RenderBinary(pBuffer + ulCurPos);

    return ulCurPos;
}

ULONG32 CIMFViewchangeEffect::InitFromBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;
    ULONG32 ulTmp;

    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, ulTmp); // This is the type
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += m_cSrcRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.InitFromBinary(pBuffer + ulCurPos);

    return ulCurPos;
}

void CIMFViewchangeEffect::RenderText(GString &rText)
{
    rText += CIMFFileObject::m_pszTagStart;
    rText += CIMFFileObject::m_pszViewchangeTag;
    rText += " ";
    CIMFFileObject::RenderAttribute(m_pszStart,    m_ulStart,     rText);
    CIMFFileObject::RenderAttribute(m_pszDuration, m_ulDuration,  rText);
    m_cSrcRect.RenderText(rText);
    m_cDstRect.RenderText(rText);
    if (m_cURL.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszURL, m_cURL, rText);
    }
    rText += CIMFFileObject::m_pszTagEnd;
}

BOOL CIMFViewchangeEffect::InitFromText(GString &rText)
{
    // These are required attributes
    // Get the start time
    HX_RESULT retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                             m_pszStart,
                                                             m_pFileObject->GetTimeFormat(),
                                                             m_ulStart);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing start attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
    // Get the duration
    retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                   m_pszDuration,
                                                   m_pFileObject->GetTimeFormat(),
                                                   m_ulDuration);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing duration attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszStart,    m_ulStart))    return FALSE;
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszDuration, m_ulDuration)) return FALSE;

    // These are optional attributes
    m_cSrcRect.InitFromText(rText);
    m_cDstRect.InitFromText(rText);
    CIMFFileObject::SetAttributeValue(rText, m_pszURL, m_cURL);
	CIMFFileObject::SetAttributeValue(rText, m_pszMaxFps, m_ulMaxFps);

    return TRUE;
}

void CIMFViewchangeEffect::RenderToolData(IMFEFFECT& imfEffect)
{
    imfEffect.m_ulBinSize        = GetBinaryLength();
    imfEffect.m_ulMaxFps         = GetMaxFps();
    imfEffect.m_ulStart          = GetStart();
    imfEffect.m_ulDuration       = GetDuration();
    imfEffect.m_bAspect          = GetAspectFlag();
    imfEffect.m_bDefaultAspect   = GetAspectDefault();
    imfEffect.m_ulTarget         = GetTargetImageHandle();
    imfEffect.m_ulType           = GetType();

    imfEffect.m_nSrc_x           = m_cSrcRect.GetX();
    imfEffect.m_nSrc_y           = m_cSrcRect.GetY();
    imfEffect.m_nSrc_W           = m_cSrcRect.GetWidth();
    imfEffect.m_nSrc_H           = m_cSrcRect.GetHeight();
    imfEffect.m_nDest_x          = m_cDstRect.GetX();
    imfEffect.m_nDest_y          = m_cDstRect.GetY();
    imfEffect.m_nDest_W          = m_cDstRect.GetWidth();
    imfEffect.m_nDest_H          = m_cDstRect.GetHeight();
    if (m_cURL.length() > 0)
        SafeStrCpy(imfEffect.m_cURL, GetURL().c_str(), 256);
    
}

BOOL CIMFViewchangeEffect::InitFromToolData(IMFEFFECT imfEffect)
{
    SetStart(imfEffect.m_ulStart);
    SetDefaultMaxFps(imfEffect.m_ulMaxFps);
    SetDuration(imfEffect.m_ulDuration);   
    SetAspectFlag(imfEffect.m_bAspect);
    SetAspectDefault(imfEffect.m_bDefaultAspect);
    SetTargetImageHandle(imfEffect.m_ulTarget);
    SetURL(imfEffect.m_cURL);
    m_cSrcRect.SetX(imfEffect.m_nSrc_x);
    m_cSrcRect.SetY(imfEffect.m_nSrc_y);
    m_cSrcRect.SetWidth(imfEffect.m_nSrc_W);
    m_cSrcRect.SetHeight(imfEffect.m_nSrc_H);
    m_cDstRect.SetX(imfEffect.m_nDest_x);
    m_cDstRect.SetY(imfEffect.m_nDest_y);
    m_cDstRect.SetWidth(imfEffect.m_nDest_W);
    m_cDstRect.SetHeight(imfEffect.m_nDest_H);
    return TRUE;    
    
}
/////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////
ULONG32 CIMFExternalEffect::GetBinaryLength()
{
    return 62 + 4 +
		        m_cURL.length()     +
                m_cPackage.length() +
                m_cName.length()    +
                m_cData.length()    +
                m_cFile.length();
}

ULONG32 CIMFExternalEffect::RenderBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;

    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, (ULONG32) kTypeExternal);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulTarget);
    ulCurPos += m_cSrcRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_bAspectFlag);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cPackage);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cName);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cData);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cFile);

    return ulCurPos;
}

ULONG32 CIMFExternalEffect::InitFromBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;
    ULONG32 ulTmp;

    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, ulTmp); // This is the type
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulTarget);
    ulCurPos += m_cSrcRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_bAspectFlag);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cPackage);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cName);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cData);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cFile);

    return ulCurPos;
}

void CIMFExternalEffect::RenderText(GString &rText)
{
    rText += CIMFFileObject::m_pszTagStart;
    rText += CIMFFileObject::m_pszCrossfadeTag;
    rText += " ";
    CIMFFileObject::RenderAttribute(m_pszStart,    m_ulStart,     rText);
    CIMFFileObject::RenderAttribute(m_pszDuration, m_ulDuration,  rText);
    CIMFFileObject::RenderAttribute(m_pszTarget,   m_ulTarget,    rText);
    m_cSrcRect.RenderText(rText);
    m_cDstRect.RenderText(rText);
    if (m_bAspectFlag != m_bAspectDefault)
    {
        CIMFFileObject::RenderAttribute(m_pszAspect, m_bAspectFlag, rText);
    }
    if (m_cURL.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszURL, m_cURL, rText);
    }
    if (m_cPackage.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszPackage, m_cPackage, rText);
    }
    if (m_cName.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszName, m_cName, rText);
    }
    if (m_cData.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszData, m_cData, rText);
    }
    if (m_cFile.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszFile, m_cFile, rText);
    }
    rText += CIMFFileObject::m_pszTagEnd;
}

BOOL CIMFExternalEffect::InitFromText(GString &rText)
{
    // These are required attributes
    // Get the start time
    HX_RESULT retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                             m_pszStart,
                                                             m_pFileObject->GetTimeFormat(),
                                                             m_ulStart);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing start attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
    // Get the duration
    retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                   m_pszDuration,
                                                   m_pFileObject->GetTimeFormat(),
                                                   m_ulDuration);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing duration attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszStart,    m_ulStart))    return FALSE;
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszDuration, m_ulDuration)) return FALSE;
    if (!CIMFFileObject::SetAttributeValue(rText, m_pszTarget,   m_ulTarget))   return FALSE;
    if (!CIMFFileObject::SetAttributeValue(rText, m_pszPackage,  m_cPackage))   return FALSE;
    if (!CIMFFileObject::SetAttributeValue(rText, m_pszName,     m_cName))      return FALSE;

    // These are optional attributes
    m_cSrcRect.InitFromText(rText);
    m_cDstRect.InitFromText(rText);
    CIMFFileObject::SetAttributeValue(rText, m_pszURL, m_cURL);
	CIMFFileObject::SetAttributeValue(rText, m_pszMaxFps, m_ulMaxFps);

    if (!CIMFFileObject::SetAttributeValueBOOL(rText, m_pszAspect, m_bAspectFlag))
    {
        m_bAspectFlag = m_bAspectDefault;
    }
    CIMFFileObject::SetAttributeValue(rText, m_pszData, m_cData);
    CIMFFileObject::SetAttributeValue(rText, m_pszFile, m_cFile);

    return TRUE;
}

void CIMFExternalEffect::RenderToolData(IMFEFFECT& imfEffect)
{
    imfEffect.m_ulBinSize        = GetBinaryLength();
    imfEffect.m_ulMaxFps         = GetMaxFps();
    imfEffect.m_ulStart          = GetStart();
    imfEffect.m_ulDuration       = GetDuration();
    imfEffect.m_bAspect          = GetAspectFlag();
    imfEffect.m_bDefaultAspect   = GetAspectDefault();
    imfEffect.m_ulTarget         = GetTargetImageHandle();
    imfEffect.m_ulType           = GetType();

    if (m_cPackage.length() > 0)
        SafeStrCpy(imfEffect.m_cPackage, m_cPackage.c_str(), 256);
    
    if (m_cName.length() > 0)
        SafeStrCpy(imfEffect.m_cName, m_cName.c_str(), 256);
    
    if (m_cData.length() > 0)
        SafeStrCpy(imfEffect.m_cData, m_cData.c_str(), 256);

    if (m_cFile.length() > 0)
        SafeStrCpy(imfEffect.m_cFile, m_cFile.c_str(), 256);
    
    if (m_cURL.length() > 0)
        SafeStrCpy(imfEffect.m_cURL, GetURL().c_str(), 256);

    imfEffect.m_nSrc_x           = m_cSrcRect.GetX();
    imfEffect.m_nSrc_y           = m_cSrcRect.GetY();
    imfEffect.m_nSrc_W           = m_cSrcRect.GetWidth();
    imfEffect.m_nSrc_H           = m_cSrcRect.GetHeight();
    imfEffect.m_nDest_x          = m_cDstRect.GetX();
    imfEffect.m_nDest_y          = m_cDstRect.GetY();
    imfEffect.m_nDest_W          = m_cDstRect.GetWidth();
    imfEffect.m_nDest_H          = m_cDstRect.GetHeight();

}

BOOL CIMFExternalEffect::InitFromToolData(IMFEFFECT imfEffect)
{
    SetStart(imfEffect.m_ulStart);
    SetDefaultMaxFps(imfEffect.m_ulMaxFps);
    SetDuration(imfEffect.m_ulDuration);   
    SetAspectFlag(imfEffect.m_bAspect);
    SetAspectDefault(imfEffect.m_bDefaultAspect);
    SetTargetImageHandle(imfEffect.m_ulTarget);
    SetPackage(imfEffect.m_cPackage);
    SetName(imfEffect.m_cName);
    SetData(imfEffect.m_cData);
    SetFile(imfEffect.m_cFile);
    SetURL(imfEffect.m_cURL);

    m_cSrcRect.SetX(imfEffect.m_nSrc_x);
    m_cSrcRect.SetY(imfEffect.m_nSrc_y);
    m_cSrcRect.SetWidth(imfEffect.m_nSrc_W);
    m_cSrcRect.SetHeight(imfEffect.m_nSrc_H);
    m_cDstRect.SetX(imfEffect.m_nDest_x);
    m_cDstRect.SetY(imfEffect.m_nDest_y);
    m_cDstRect.SetWidth(imfEffect.m_nDest_W);
    m_cDstRect.SetHeight(imfEffect.m_nDest_H);

    return TRUE;    
    
}
/////////////////////////////////////////////////////////////////////////////////////////////////

ULONG32 CIMFAnimateEffect::GetBinaryLength()
{
    return 54 + 4 + m_cURL.length();
}

ULONG32 CIMFAnimateEffect::RenderBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;

    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, (ULONG32) kTypeAnimate);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulStart);
	ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
	ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulTarget);
    ulCurPos += m_cSrcRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.RenderBinary(pBuffer + ulCurPos);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_bAspectFlag);
    
    return ulCurPos;
}

ULONG32 CIMFAnimateEffect::InitFromBinary(unsigned char *pBuffer)
{
    ULONG32 ulCurPos = 0;
    ULONG32 ulTmp;

    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, ulTmp); // This is the type
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulStart);
    ulCurPos += RenderBinaryType(pBuffer + ulCurPos, m_ulMaxFps);
	ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_cURL);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulDuration);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_ulTarget);
    ulCurPos += m_cSrcRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += m_cDstRect.InitFromBinary(pBuffer + ulCurPos);
    ulCurPos += InitFromBinaryType(pBuffer + ulCurPos, m_bAspectFlag);
    
    return ulCurPos;
}

void CIMFAnimateEffect::RenderText(GString &rText)
{
    rText += CIMFFileObject::m_pszTagStart;
    rText += CIMFFileObject::m_pszAnimateTag;
    rText += " ";
    CIMFFileObject::RenderAttribute(m_pszStart,    m_ulStart,     rText);
	CIMFFileObject::RenderAttribute(m_pszDuration, m_ulDuration,  rText);
    CIMFFileObject::RenderAttribute(m_pszTarget,   m_ulTarget,    rText);
    
	m_cSrcRect.RenderText(rText);
    m_cDstRect.RenderText(rText);
    if (m_bAspectFlag != m_bAspectDefault)
    {
        CIMFFileObject::RenderAttribute(m_pszAspect, m_bAspectFlag, rText);
    }
    if (m_cURL.length() > 0)
    {
        CIMFFileObject::RenderAttribute(m_pszURL, m_cURL, rText);
    }
    rText += CIMFFileObject::m_pszTagEnd;
}

BOOL CIMFAnimateEffect::InitFromText(GString &rText)
{
    // Get the start time
    HX_RESULT retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                             m_pszStart,
                                                             m_pFileObject->GetTimeFormat(),
                                                             m_ulStart);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing start attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
    // Get the duration
    retVal = CIMFFileObject::SetAttributeTimeValue(rText,
                                                   m_pszDuration,
                                                   m_pFileObject->GetTimeFormat(),
                                                   m_ulDuration);
    if (retVal != HXR_OK)
    {
        if (retVal == HXR_PROP_NOT_FOUND)
        {
            m_cErrorMessage = "Missing duration attribute in ";
        }
        else
        {
            m_cErrorMessage = "Invalid time formatting in ";

        }
        m_cErrorMessage += rText;

        return FALSE;
    }
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszStart,    m_ulStart))    return FALSE;
//    if (!CIMFFileObject::SetAttributeValue(rText, m_pszDuration, m_ulDuration)) return FALSE;
    if (!CIMFFileObject::SetAttributeValue(rText, m_pszTarget,   m_ulTarget))   return FALSE;

    // These are optional attributes
    m_cSrcRect.InitFromText(rText);
    m_cDstRect.InitFromText(rText);
    CIMFFileObject::SetAttributeValue(rText, m_pszURL, m_cURL);
	CIMFFileObject::SetAttributeValue(rText, m_pszMaxFps, m_ulMaxFps);
    if (!CIMFFileObject::SetAttributeValueBOOL(rText, m_pszAspect, m_bAspectFlag))
    {
        m_bAspectFlag = m_bAspectDefault;
    }

    return TRUE;
}

void CIMFAnimateEffect::RenderToolData(IMFEFFECT& imfEffect)
{

    imfEffect.m_ulBinSize        = GetBinaryLength();
    imfEffect.m_ulMaxFps         = GetMaxFps();
    imfEffect.m_ulStart          = GetStart();
    imfEffect.m_ulDuration       = GetDuration();
    imfEffect.m_bAspect          = GetAspectFlag();
    imfEffect.m_bDefaultAspect   = GetAspectDefault();
    imfEffect.m_ulTarget         = GetTargetImageHandle();
    imfEffect.m_ulType           = GetType();
    
    imfEffect.m_nSrc_x           = m_cSrcRect.GetX();
    imfEffect.m_nSrc_y           = m_cSrcRect.GetY();
    imfEffect.m_nSrc_W           = m_cSrcRect.GetWidth();
    imfEffect.m_nSrc_H           = m_cSrcRect.GetHeight();
    imfEffect.m_nDest_x          = m_cDstRect.GetX();
    imfEffect.m_nDest_y          = m_cDstRect.GetY();
    imfEffect.m_nDest_W          = m_cDstRect.GetWidth();
    imfEffect.m_nDest_H          = m_cDstRect.GetHeight();
    if (m_cURL.length() > 0)
        SafeStrCpy(imfEffect.m_cURL, GetURL().c_str(), 256);

}

BOOL CIMFAnimateEffect::InitFromToolData(IMFEFFECT imfEffect)
{
    // Set Attributes
    SetStart(imfEffect.m_ulStart);
    SetDefaultMaxFps(imfEffect.m_ulMaxFps);
    SetDuration(imfEffect.m_ulDuration);   
    SetAspectFlag(imfEffect.m_bAspect);
    SetAspectDefault(imfEffect.m_bDefaultAspect);
    SetTargetImageHandle(imfEffect.m_ulTarget);
    SetURL(imfEffect.m_cURL);
    m_cSrcRect.SetX(imfEffect.m_nSrc_x);
    m_cSrcRect.SetY(imfEffect.m_nSrc_y);
    m_cSrcRect.SetWidth(imfEffect.m_nSrc_W);
    m_cSrcRect.SetHeight(imfEffect.m_nSrc_H);
    m_cDstRect.SetX(imfEffect.m_nDest_x);
    m_cDstRect.SetY(imfEffect.m_nDest_y);
    m_cDstRect.SetWidth(imfEffect.m_nDest_W);
    m_cDstRect.SetHeight(imfEffect.m_nDest_H);
    return TRUE;    
}

/////////////////////////////////////////////////////////////////////////////////////////////////
CIMFEffect* CIMFEffectFactory::CreateInstance(IMFEFFECT& imfEffect)
{

    CIMFEffect* pEffect= NULL;
    switch(imfEffect.m_ulType)
    {
        case kTypeFill:
            pEffect = new CIMFFillEffect();
        break;
        case kTypeFadeIn:
            pEffect = new CIMFFadeinEffect();
        break;
        case kTypeFadeOut:
            pEffect = new CIMFFadeoutEffect();
        break;
        case kTypeCrossFade:
            pEffect = new CIMFCrossfadeEffect();
        break;
        case kTypeWipe:
            pEffect = new CIMFWipeEffect();
        break;
        case kTypeViewChange:
            pEffect = new  CIMFViewchangeEffect();
        break;
        case kTypeExternal:
            pEffect = new  CIMFExternalEffect();
        break;
        case kTypeAnimate:
            pEffect = new  CIMFAnimateEffect();
        break;
    }

    if(pEffect)
        pEffect->InitFromToolData(imfEffect);
    return pEffect;
}
/////////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////////
