/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: smlelem.h,v 1.4.16.1 2004/07/09 01:57:56 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 _SMLELEM_H_
#define _SMLELEM_H_

#define WAY_IN_THE_FUTURE  1981342000 /*1981342000 is 22d+22h+22m+22s */
#if !defined(MAX_LONG32)
#define MAX_LONG32  0x7FFFFFFF
#endif

// /This is used for passing invalid coord value for firing a link when an
// accesskey event occurs (and no mouse coords are involved): 
#define ANCHOR_POS_DONTCARE ((UINT16)-1)

// /This is used to simplify event processing since accesskey events have no
// element that raises them, they have no element ID.  The following is used
// for all accesskey events that have no ID, and it starts with a number to
// make sure it's an illegal XML id and thus won't be used in a SMIL file:
#define ACCESSKEY_EVENT_FAKE_ID_STRING  "21yrsOld__accesskey_fake_id"


// Forward declarations
typedef _INTERFACE IHXValues IHXValues;
typedef _INTERFACE IHXBuffer IHXBuffer;
class CSmilElement;
class CSmilAddGroup;
class CSmilRootLayout;
class CSmilRegion;
class CSmilRegPoint;
#if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
class CSmilViewport;
#endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
class CSmilSource;
class CSmilMeta;
class CSmilMetadata;
class CSmilEndLayout;
class CSmilRendererPreFetch;
class CSmilSourceUpdate;
#if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)
class CSmilTransition;
#endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */
class CSmilAnimateElement;
class CSmilCustomTest;
class SMILNode;
class CSmilParser;
class SmilTimeValue;
class CHXString;
class CSmilTimelineElement;
class CHXSimpleList;
class CAttr;
class CHXStack;
class CSmilElement;

class CSmilElementHandler
{
public:
    virtual HX_RESULT handleAddGroup(CSmilAddGroup* pAddGroup) = 0;
    virtual HX_RESULT handleRootLayout(CSmilRootLayout* pRootLayout) = 0;
    virtual HX_RESULT handleRegion(CSmilRegion* pRegion) = 0;
    virtual HX_RESULT handleRegPoint(CSmilRegPoint* pRegPoint) = 0;
#if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)
    virtual HX_RESULT handleViewport(CSmilViewport* pView) = 0;
#endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */
    virtual HX_RESULT handleSource(CSmilSource* pSource) = 0;
    virtual HX_RESULT handleMeta(CSmilMeta* pMeta) = 0;
    virtual HX_RESULT handleMetadata(CSmilMetadata* pMetadata) = 0;
    virtual HX_RESULT handleEndLayout(CSmilEndLayout* pEndLayout) = 0;
    virtual HX_RESULT handleRendererPreFetch(CSmilRendererPreFetch* pRend) = 0;
    virtual HX_RESULT handleSourceUpdate(CSmilSourceUpdate* pUpdate) = 0;
#if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)
    virtual HX_RESULT handleTransition(CSmilTransition* pTrans) = 0;
#endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */
    virtual HX_RESULT handleTrackRemoval(const char* pID, INT32 nGroup) = 0;
    virtual HX_RESULT handleTrackPausing(SMILNode* pNode,
			LONG32 lTimeOfPause,
			SMILPriorityClassPauseDisplay pauseDisplay,
			const char* pIdOfPauser) = 0;
    virtual HX_RESULT handleTrackResuming(const char* pID, INT32 nGroup) = 0;
#if defined(HELIX_FEATURE_SMIL2_ANIMATION)
    virtual HX_RESULT handleAnimate(CSmilAnimateElement* pAnimate) = 0;
#endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */
    virtual HX_RESULT handleRemoveTimeUpdate(CSmilElement* pElement, UINT32 ulRemoveTime) = 0;
    virtual HX_RESULT handleExternalMediaMarkerFile(CSmilElement* pElement,
                                                    const char*   pszID,
                                                    const char*   pszExternalFileName,
                                                    const char*   pszRelativeSource) = 0;
    virtual HX_RESULT resolveGroupDurToOuterTimeContainerDur(UINT32 ulGroupIndex,
				     UINT32 ulGroupTimeContainerDuration) = 0;
    virtual HX_RESULT GetCurGroupDuration(REF(UINT32) ulCurGrpDur) = 0;
};

class CSmilElement
{
public:
    CSmilElement(SMILNode* pNode);
    virtual ~CSmilElement();

    virtual void      addDuration(UINT32 ulDuration);
    virtual void      addElement(CSmilElement* pElement,
                                 UINT32&       ulStartTime,
                                 UINT32&       ulDuration);
    virtual HX_RESULT handleElement() { return HXR_OK; }
    virtual HX_RESULT setBeginTime(CSmilParser* pParser);
    virtual HX_RESULT setEndTime(CSmilParser* pParser);
    virtual void      prepForRestart(BOOL bParentIsRestarting, LONG32 lWhen);
    virtual void      prepForPauseInExcl(LONG32 lCurTime);
    virtual void      prepForResumeInExcl();
    virtual void      prepForStopInExcl(LONG32 lCurTime);
    virtual void      prepForDeferralInExcl(UINT32 lCurTime);
    virtual BOOL      isPausedInExcl() { return m_bIsPausedInExcl; }
    virtual BOOL      isDeferredInExcl() { return m_bIsDeferredInExcl; }
    virtual BOOL      isStoppedInExcl() { return m_bIsStoppedInExcl; }
    virtual HX_RESULT getBeginTimeValue(REF(SmilTimeValue*) pValue);
    virtual HX_RESULT getEndTimeValue(REF(SmilTimeValue*) pValue);

    // /These were added in order to easily calculate when an already-
    // inserted-into-the-timeline element *actually* begins and ends so
    // that doing such things as freezing and holding can be done:
    virtual HX_RESULT getCurrentScheduledStartTime(
	    REF(ULONG32) ulActualStartTime);
    virtual HX_RESULT getCurrentScheduledStopTime(
	    REF(ULONG32) ulActualStopTime);

    // /Note: pValue, as well as the two lists, is|are filled with either
    // begin or end time|times, depending on the listType value:
    virtual HX_RESULT getNextResolvedTimeValue(REF(SmilTimeValue*) pValue,
                                               INT32 lCurTimeInGroupTime,
                                               INT32 lCurTimeInSyncBaseTime,
                                               SmilTimingListType  listType,
                                               CHXSimpleList*
					       pListOfAllResolvedTimes);
    virtual HX_RESULT resolveEventTimeValues(INT32              lCurTime,
                                             const char*        pEventName,
                                             const char*        pEventElementId,
                                             SmilTimingListType listType,
                                             REF(BOOL)          bATimeWasResolved);
    virtual HX_RESULT resolveSyncArcTimeValues(INT32              lResolvedToTime,
                                               const char*        pSyncBaseElementId,
                                               SmilTimingListType listType,
                                               REF(BOOL)          bATimeWasResolved,
					       BOOL bMoveNewlyResolvedsToPendingTimesList,
					       CSmilParser* pParser);
    virtual HX_RESULT getParentRestartDefault();
    virtual void      updateRemoveTime(UINT32 ulRemoveTime);
    virtual void      handleXMMF(const char* pszID, const char* pszXMMFile, const char* pszSrc);
    virtual BOOL      hasEventBasedBeginTime();
    virtual BOOL      hasEventBasedEndTime();
    virtual CSmilElement* getSyncAncestorElement();

    // /Use of the new method fixes PR 79699 and PR 8XXYZ (PR 63622 part 3,
    // revisited) by making sure that the duration passed to
    // resetTimelineElementDuration() is in local time coords, not syncbase
    // time coord (i.e., m_ulDuration may or may not include the delay beyond
    // the syncbase.  This method returns the duration from the element's
    // begin to its end, w/o any delay:
    ULONG32 getPureDuration();

    // /This method goes through the m_pEndTimeList to see if there's an
    // event-arc end time or other unresolved end time; this is important
    // for use in the algorithm for determining whether or not something
    // should restart (see SMIL 2.0 Spec Timing Module's getNextInterval()
    // pseudocode):
    BOOL hasUnresolvedEndTime();

    // /This method helps fix PR 50660 (par version) and PR 62408: to make
    // sure restarted track doesn't get treated as a repeat track in
    // handleSource(), it calls this and uses the return val to decide; the
    // m_bIsRestarting is reset to FALSE in case this element does have
    // a repeat so the repeats will also restart:
    BOOL IsRestartingAndNotRepeating() { BOOL bIs=m_bIsRestarting;
                                         m_bIsRestarting=FALSE; return bIs;}

    HX_RESULT	GetElementProperties(REF(IHXValues*) pProperties);

    void checkElementFillBehavior();
    
    // /NOTE: all values below are for the currently-active (or, if this
    // element is not active on the timeline currently, the next-to-be
    // active) "interval" (see SMIL 2.0 Timing module for details on
    // how a "current interval" is defined and computed).  Multiple begin
    // and end times are stored in the m_pBeginTimeList and m_pEndTimeList,
    // respectively.  When a new one from that list becomes the active one,
    // the following vars may change (which happens *during* playback):
    SMILNode*             m_pNode;
    UINT32                m_ulClipBegin;           // start of clip
    UINT32                m_ulAuthoredClipBegin;   // explicitly-authored clipBegin value
    UINT32                m_ulClipEnd;             // clip end time
    INT32                 m_lBeginOffset;          // clip delay
    ULONG32		  m_ulBeginOffsetFromSyncBase;
    UINT32                m_ulDelay;               // presentation delay
    // /NOTE: this may include delay beyond syncbase.  getPureDuration()
    // returns the duration from the element's begin to its end, w/o delay:
    UINT32                m_ulDuration;            // clip duration
    UINT32                m_ulOriginalDuration;    // value dur attribute if dur is specified.
    UINT32                m_ulDurationInAddTrack;
    UINT32                m_ulMaxDuration;
    UINT32                m_ulMaxActiveDur;        // as set by the "min" attribute. deflt=indef
    UINT32                m_ulMinActiveDur;        // as set by the "min" attribute. default=0.
    UINT32                m_ulAuthoredDur;         // as set by the "dur" attribute.
    INT32                 m_lEndOffset;
    UINT32                m_ulAnticipatedPauseDur;
    UINT32                m_ulEndSync;
    ULONG32		  m_ulStopTimeInExcl;
    ULONG32               m_ulLongSyncArcBeginInGroupTime;
    double                m_fRepeatValue;
    UINT32                m_ulTimestamp;           // timestamp to send packet
    SmilElementRestart    m_restartBehavior;
    SmilElementRestart    m_restartDefaultBehavior;
    ULONG32               m_ulSyncTolerance;
    ULONG32               m_ulSyncToleranceDefault;
    SMILSyncBehaviorType  m_syncBehavior;
    SMILSyncBehaviorType  m_syncBehaviorDefault;
    CHXString             m_sensitivityToMouseEvents;
    CHXString             m_title;
    CHXString             m_author;
    CHXString             m_copyright;
    CHXString             m_abstract;
    CHXString             m_alt;
    CHXString             m_longdesc;
    ULONG32               m_ulReadIndex;
    SMILEventSourceTag    m_nBeginEventSourceTag;
    CHXString             m_BeginEventSourceID;
    INT32                 m_lBeginEventClockValue;
    SMILEventSourceTag    m_nEndEventSourceTag;
    CHXString             m_EndEventSourceID;
    INT32                 m_lEndEventClockValue;
    SMILEventSourceTag    m_nEndsyncEventSourceTag;
    CHXString             m_EndsyncEventSourceID;
    CSmilTimelineElement* m_pTimelineElement;
    CSmilElementHandler*  m_pHandler;
    CHXSimpleList*        m_pHyperlinks;
    CHXSimpleList*        m_pBeginTimeList;
    CHXSimpleList*        m_pEndTimeList;
    CHXString             m_beginTransition;
    CHXString             m_endTransition;
    FillType              m_eFill;
    FillDefaultType       m_eFillDefault;
    FillType              m_eActualFill;
    EraseType             m_eErase;
    UINT32                m_ulRemoveTime;
    CHXString             m_customTestKey;
    char*                 m_pszClipBeginMarkerName;
    char*                 m_pszClipBeginExternalMarkerFileName;
    char*                 m_pszClipEndMarkerName;
    char*                 m_pszClipEndExternalMarkerFileName;
    AccessErrorBehavior   m_eAccessErrorBehavior;
    UINT32                m_ulTimeDeferralOccurred;
    // ONLY HX_BITFIELD MEMBERS SHOULD GO BELOW THIS LINE!
    // ALL OTHER MEMBER TYPES SHOULD GO ABOVE THIS LINE!
    HX_BITFIELD           m_bBeginOffsetSet : 1;
    HX_BITFIELD           m_bNegBeginOffsetAlreadyUsed : 1;
    HX_BITFIELD           m_bCurBeginIsOffsetFromSyncBase : 1;
    HX_BITFIELD           m_bCurEndClippedByParent : 1; // end clipped by parent end
    HX_BITFIELD           m_bUseMediaDurForMinDur : 1; // flag for min="media"
    HX_BITFIELD           m_bUseMediaDurForMaxDur : 1; // flag for max="media"
    HX_BITFIELD           m_bHasExplicitEnd : 1;
    HX_BITFIELD           m_bHasExplicitDur : 1;
    HX_BITFIELD           m_bDurationIncludesDelayBeyondSyncbase : 1;
    HX_BITFIELD           m_bAddDurationAlreadyDone : 1;
    HX_BITFIELD           m_bEndOffsetSet : 1;
    HX_BITFIELD           m_bInsertedIntoTimeline : 1; // TRUE when inserted
    HX_BITFIELD           m_bHasBeenScheduled : 1;     // TRUE when inserted; doesn't ever reset, though
    HX_BITFIELD           m_bIsPausedInExcl : 1; // TRUE when active+paused in excl
    HX_BITFIELD           m_bIsDeferredInExcl : 1;
    HX_BITFIELD           m_bIsStoppedInExcl : 1;
    HX_BITFIELD           m_bCurrentSourceIsLive : 1;
    HX_BITFIELD           m_bRendererInitialized : 1;
    HX_BITFIELD           m_bIsRestarting : 1;
    // /long sync arc begin resolved before parent delay resolved:
    HX_BITFIELD           m_bAwaitingSyncAncestorBeginNotification : 1;
    HX_BITFIELD           m_bIndefiniteDuration : 1;
    HX_BITFIELD           m_bIndefiniteBegin : 1;
    HX_BITFIELD           m_bIndefiniteEnd : 1;
    HX_BITFIELD           m_bWallClockBegin : 1;
    HX_BITFIELD           m_bWallClockEnd : 1;
    HX_BITFIELD           m_bHasAtLeastOneEventBasedBegin : 1;
    HX_BITFIELD           m_bHasAtLeastOneNonEventBasedBegin : 1;
    HX_BITFIELD           m_bUsesExternalMediaMarkerFile : 1;
    HX_BITFIELD           m_bClipBeginUsesMarker : 1;
    HX_BITFIELD           m_bClipBeginMarkerResolved : 1;
    HX_BITFIELD           m_bWaitingOnClipBeginToResolve : 1;
    HX_BITFIELD           m_bClipEndUsesMarker : 1;
    HX_BITFIELD           m_bClipEndMarkerResolved : 1;
    HX_BITFIELD           m_bWaitingOnClipEndToResolve : 1;
};

class CSmilAddGroup: public CSmilElement
{
public:
    CSmilAddGroup();
    virtual ~CSmilAddGroup();

    virtual HX_RESULT handleElement();

    IHXValues* m_pValues;
    INT32       m_nGroup;
    INT32       m_nTotalTracks;
    INT32       m_nInitTracks;
    UINT32      m_ulDuration;
};

class CSmilRootLayout: public CSmilElement
{
public:
    CSmilRootLayout(SMILNode* pNode);
    virtual ~CSmilRootLayout();

    virtual HX_RESULT handleElement();

    double         m_dWidth;
    CSS2Type       m_eWidthType;
    double         m_dHeight;
    CSS2Type       m_eHeightType;
    UINT32         m_ulBackgroundColor;
    CSS2Type       m_eBackgroundColorType;
    ResizeBehavior m_eResizeBehavior;
    ContextWindow  m_eContextWindow;
};

class CSmilRegion: public CSmilElement
{
public:
    CSmilRegion(SMILNode* pNode);
    virtual ~CSmilRegion();

    virtual HX_RESULT handleElement();

    LayoutRect     m_Rect;
    INT32          m_lZIndex;
    CSS2Type       m_eZIndexType;
    Fit            m_eFit;
    ShowBackground m_eShowBackground;
    UINT32         m_ulBackgroundColor;
    CSS2Type       m_eBackgroundColorType;
    double         m_dSoundLevel;
    CHXString      m_RegionName;
    // ONLY HX_BITFIELD MEMBERS SHOULD GO BELOW THIS LINE!
    // ALL OTHER MEMBER TYPES SHOULD GO ABOVE THIS LINE!
    HX_BITFIELD    m_bRegionNameSpecified : 1;
};

class CSmilRegPoint: public CSmilElement
{
public:
    CSmilRegPoint(SMILNode* pNode);
    virtual ~CSmilRegPoint();

    virtual HX_RESULT handleElement();

    RegPoint m_RegPoint;
};

#if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT)

class CSmilViewport: public CSmilElement
{
public:
    CSmilViewport(SMILNode* pNode);
    virtual ~CSmilViewport();

    virtual HX_RESULT handleElement();

    UINT32         m_ulBackgroundColor;
    CSS2Type       m_eBackgroundColorType;
    double         m_dWidth;
    CSS2Type       m_eWidthType;
    double         m_dHeight;
    CSS2Type       m_eHeightType;
    ViewportOpen   m_eOpen;
    ViewportClose  m_eClose;
    ResizeBehavior m_eResizeBehavior;
    ContextWindow  m_eContextWindow;
};

#endif /* #if defined(HELIX_FEATURE_SMIL2_MULTIWINDOWLAYOUT) */

class CSmilMeta: public CSmilElement
{
public:
    CSmilMeta(SMILNode* pNode);
    virtual ~CSmilMeta();

    virtual HX_RESULT handleElement();

    CHXString m_name;
    CHXString m_content;
};

class CSmilMetadata: public CSmilElement
{
public:
    CSmilMetadata(SMILNode* pNode);
    virtual ~CSmilMetadata();

    virtual HX_RESULT handleElement();
};

class CSmilRendererPreFetch: public CSmilElement
{
public:
    CSmilRendererPreFetch(SMILNode* pNode);
    virtual ~CSmilRendererPreFetch();

    virtual HX_RESULT handleElement();

    CHXString m_mimeType;
};

class CSmilEndLayout: public CSmilElement
{
public:
    CSmilEndLayout();
    virtual ~CSmilEndLayout();

    virtual HX_RESULT handleElement();
};

class CSmilMetaValues: public CSmilElement
{
public:
    CSmilMetaValues();
    virtual ~CSmilMetaValues();

    IHXValues* m_pValues;
};

class CSmilCustomTest: public CSmilElement
{
public:
    CSmilCustomTest(SMILNode* pNode);
    virtual ~CSmilCustomTest();

    CHXString	m_uid;
    // ONLY HX_BITFIELD MEMBERS SHOULD GO BELOW THIS LINE!
    // ALL OTHER MEMBER TYPES SHOULD GO ABOVE THIS LINE!
    HX_BITFIELD m_bDefaultState : 1;
    HX_BITFIELD m_bOverrideVisible : 1;
};


class CSmilSource: public CSmilElement
{
public:
    CSmilSource(SMILNode* pNode);
    virtual ~CSmilSource();

    virtual HX_RESULT handleElement();
    void              setRange(const char* pRange);

    CHXString    m_src;
    CHXString    m_region;
    ULONG32      m_ulPrefetchAmount;
    PrefetchType m_typeOfPrefetchAmount;
    UINT32       m_ulColor;
    CSS2Type     m_eColorType;
    LayoutRect   m_Rect;
    INT32        m_lZIndex;
    CSS2Type     m_eZIndexType;
    Fit          m_eFit;
    UINT32       m_ulBackgroundColor;
    CSS2Type     m_eBackgroundColorType;
    CHXString    m_RegPoint;
    RegAlign     m_ePredefRegPoint;
    RegAlign     m_eRegAlign;
    UINT32       m_ulBackgroundOpacity;
    UINT32       m_ulMediaOpacity;
    UINT32       m_ulChromaKey;
    UINT32       m_ulChromaKeyTolerance;
    UINT32       m_ulChromaKeyOpacity;
    CHXString    m_MediaRepeat;
    HandledBy    m_eHandledBy;
    ULONG32      m_ulLinkTargetDestnLevel_pct;
    ULONG32      m_ulLinkTargetSourceLevel_pct;
    CHXString    m_Handler;
    CHXString    m_HandlerID;
    CHXString    m_HandlerFor;
    // ONLY HX_BITFIELD MEMBERS SHOULD GO BELOW THIS LINE!
    // ALL OTHER MEMBER TYPES SHOULD GO ABOVE THIS LINE!
    HX_BITFIELD  m_bFitSpecified : 1;
    HX_BITFIELD  m_bBackgroundColorSpecified : 1;
    HX_BITFIELD  m_bRegPointIsPredef : 1;
    HX_BITFIELD  m_bRegAlignSpecified : 1;
    HX_BITFIELD  m_bBackgroundOpacitySpecified : 1;
    HX_BITFIELD  m_bMediaOpacitySpecified : 1;
    HX_BITFIELD  m_bChromaKeySpecified : 1;
    HX_BITFIELD  m_bAudioDeviceReflushHintNeeded : 1;
};

class CSmilSourceUpdate: public CSmilElement
{
public:
    CSmilSourceUpdate();
    virtual ~CSmilSourceUpdate();

    virtual HX_RESULT handleElement();

    CHXString m_srcID;
    UpdateTag m_updateTag;
    UINT32    m_ulUpdatedDuration;
    BOOL      m_bDurationIsPureOfDelay;
    UINT32    m_ulUpdatedDelay;
};

class CSmilPriorityClassElement: public CSmilElement
{
public:
    CSmilPriorityClassElement(SMILNode* pNode);
    virtual ~CSmilPriorityClassElement();

    SMILPriorityClassPauseDisplay m_pauseDisplay;
    SMILPriorityClassPeersHigherLowerVal m_peers;
    SMILPriorityClassPeersHigherLowerVal m_higher;
    SMILPriorityClassPeersHigherLowerVal m_lower;
};

class CSmilAAnchorElement: public CSmilElement
{
public:
    CSmilAAnchorElement(SMILNode* pNode);
    virtual ~CSmilAAnchorElement();

    virtual BOOL isCurrentLink(UINT32 ulTime,
	    UINT32  ulXOffset, UINT32 ulYOffset, HXxRect regionRect,
	    // /These 3 are ignored for <a> links:
	    BOOL bResizeBehaviorIsZoom,
	    double dZoomX, double dZoomY);
    // /Tells whether the link is active at the current time (but doesn't
    // do any spatial bounds checking):
    virtual BOOL isLinkActiveAtTime(UINT32 ulTimeOffset,
	    REF(ULONG32)rulAnchorRelativeStartTime);

    virtual void rescale(double dXScale, double dYScale,
                         BOOL bResetOriginalCoords);

    virtual BOOL isAAnchor() {return TRUE;}

    CHXString         m_href;
    CHXString         m_show; // /(new|pause|replace) Default is "replace".
    UINT32            m_ulSourceLevel_pct; // /("0%"-"100%"); default is 100% (per DTD).
    UINT32            m_ulDestinationLevel_pct; // /("0%"-"100%"); default is 100%.
    SMILLinkPlaystate m_sourcePlaystate; // /(play|pause|stop); Default is:
				 // show=="new"?play:pause;
    SMILLinkPlaystate m_destinationPlaystate; // /(play|stop); Default=play.
    CHXString         m_actuate; // /(onLoad|onRequest) Default value is onRequest.
    CHXString         m_accesskey; // /(an ISO10646 character.  Default unspecified)
    UINT32            m_ulTabindex; // /((UINT32)-1) means value unspecified.
    // /Region name or frame name for where to open the link; if one doesn't
    // exist with that name, creates new one (think command:openwindow()):
    CHXString         m_target; 
    // /This is for RN-extension attribute which allows user to say
    // which browser an "external" link should go to, namely the RealPlayer
    // browser, or a truly external (OS default) browser:
    CHXString         m_sendTo;
    // /These are used for timing solely for the purposes of keeping track of
    // when the link is active (clickable) and NOT for the purposes of
    // constraining or otherwise affecting the times of child elements:
    INT32             m_lAnchorBeginOffset;
    INT32             m_lAnchorEndOffset;
    ULONG32           m_ulAnchorDuration;
    ULONG32           m_ulAnchorMinActiveDur;
    ULONG32           m_ulAnchorMaxActiveDur;
    // ONLY HX_BITFIELD MEMBERS SHOULD GO BELOW THIS LINE!
    // ALL OTHER MEMBER TYPES SHOULD GO ABOVE THIS LINE!
    HX_BITFIELD       m_bExternal : 1; // /(true|false) default is false.
    // /This is TRUE if target="x" and "x" is the id of a region in the
    // current presentation:
    HX_BITFIELD       m_bTargetIsARegion : 1;
    HX_BITFIELD       m_bAnchorBeginOffsetSet : 1;
    HX_BITFIELD       m_bAnchorEndOffsetSet : 1;
    HX_BITFIELD       m_bTimeValueSet : 1;
};

class CSmilAnchorVertex
{
public:
    CSmilAnchorVertex() {m_lX=m_lY=0; m_bXIsPercent=m_bYIsPercent=FALSE;}
    ~CSmilAnchorVertex() {};

    INT32       m_lX;
    INT32       m_lY;
    // ONLY HX_BITFIELD MEMBERS SHOULD GO BELOW THIS LINE!
    // ALL OTHER MEMBER TYPES SHOULD GO ABOVE THIS LINE!
    HX_BITFIELD m_bXIsPercent : 1;
    HX_BITFIELD m_bYIsPercent : 1;
};

class CSmilAnchorElement: public CSmilAAnchorElement
{
public:
    CSmilAnchorElement(SMILNode* pNode);
    virtual ~CSmilAnchorElement();

    virtual BOOL isCurrentLink(UINT32 ulTime,
	    UINT32  ulXOffset, UINT32 ulYOffset, HXxRect regionRect,
	    BOOL bResizeBehaviorIsZoom,
	    double dZoomX, double dZoomY);
    // /Tells whether the link is active at the current time (but doesn't
    // do any spatial bounds checking):
    virtual BOOL isLinkActiveAtTime(UINT32 ulTimeOffset,
	    REF(ULONG32)rulAnchorRelativeStartTime);

    virtual void rescale(double dXScale, double dYScale,
                         BOOL bResetOriginalCoords);

    virtual BOOL isAAnchor() {return FALSE;}

    // /This handles conversion of string of points ("0,0, 20,10, ...") to
    // array of CSmilAnchorVertex's (vertices) in m_pVertexArray:
    HX_RESULT convertRawPolyData(const char* pData);

    // /This is for handling hit-testing in a "poly" (polygon) shape:
    BOOL isPointInPolygon(INT32 lXOffset, INT32 lYOffset,
	    HXxRect regionRect,
	    double dZoomX, double dZoomY);

    void deleteVertexArrays();

    // /XXXEH- TODO: make these points be unsigned values because shapes
    // can stick out of frame, and thus can be negative in places:
    UINT32             m_ulLeftX;
    UINT32             m_ulOriginalLeftX;
    UINT32             m_ulTopY;
    UINT32             m_ulOriginalTopY;
    UINT32             m_ulRightX;
    UINT32             m_ulOriginalRightX;
    UINT32             m_ulBottomY;
    UINT32             m_ulOriginalBottomY;
    UINT32             m_ulRadius;
    UINT32             m_ulOriginalRadius;
    // /XXXEH- TODO: use these points for rectangles, too (but don't use the
    // hit-test code for them as it is slower for rectangles):
    // /The following three are for handling shape="poly":
    CSmilAnchorVertex* m_pVertexArray;
    CSmilAnchorVertex* m_pOriginalVertexArray;
    UINT16	       m_uiNumPoints;
    CHXString          m_shape;
    CHXString          m_fragmentID;
    INT32              m_zIndex;
    // ONLY HX_BITFIELD MEMBERS SHOULD GO BELOW THIS LINE!
    // ALL OTHER MEMBER TYPES SHOULD GO ABOVE THIS LINE!
    HX_BITFIELD        m_bCoordsSet : 1;
    HX_BITFIELD        m_bLeftXIsPercent : 1;
    HX_BITFIELD        m_bTopYIsPercent : 1;
    HX_BITFIELD        m_bRightXIsPercent : 1;
    HX_BITFIELD        m_bBottomYIsPercent : 1;
    HX_BITFIELD        m_bRadiusIsPercent : 1;
};

enum
{
    kCalcModeDiscrete,
    kCalcModeLinear,
    kCalcModePaced
#if defined(XXXMEH_SPLINE_ANIMATION)
    ,kCalcModeSpline
#endif
};

enum
{
    kAccumulateSum,
    kAccumulateNone
};

enum
{
    kAdditiveSum,
    kAdditiveReplace
};

enum
{
    kAnimTypeValues,
    kAnimTypeFromTo,
    kAnimTypeFromBy,
    kAnimTypeBy,
    kAnimTypeTo
};

#if defined(XXXMEH_SPLINE_ANIMATION)

struct KeySpline
{
    double x1;
    double y1;
    double x2;
    double y2;
};

typedef enum
{
    PathCmdTypeUnknown,
    PathCmdTypeMoveTo,
    PathCmdTypeLineTo,
    PathCmdTypeHorzLineTo,
    PathCmdTypeVertLineTo,
    PathCmdTypeClosePath,
    PathCmdTypeCubicBezierCurveTo
} PathCmdType;

class PathCmd
{
public:
    PathCmd();
    ~PathCmd();

    PathCmdType m_eType;
    BOOL        m_bRelative;
    UINT32      m_ulNumCoords;
    double*     m_pdCoord;
};

inline PathCmd::PathCmd()
{
    m_eType       = PathCmdTypeUnknown;
    m_bRelative   = FALSE;
    m_ulNumCoords = 0;
    m_pdCoord     = NULL;
}

inline PathCmd::~PathCmd()
{
    HX_VECTOR_DELETE(m_pdCoord);
}

#endif

#if defined(HELIX_FEATURE_SMIL2_ANIMATION)

class CSmilAnimateElement : public CSmilElement
{
public:
    CSmilAnimateElement(SMILNode* pNode);
    virtual ~CSmilAnimateElement();

    virtual HX_RESULT handleElement();
    // We override this since we handle repeat
    // differently than sources do.
    virtual HX_RESULT getCurrentScheduledStopTime(REF(ULONG32) ulActualStopTime);

    UINT32      m_ulSimpleDuration;
    UINT32      m_ulActiveDuration;
    UINT32      m_ulADNoSpeed;
    CHXString*  m_pTargetElementID;
    SMILNodeTag m_eTargetElementTag;
    UINT32      m_ulNumValues;
    CAttr**     m_ppValue;
    BYTE        m_ucAttributeName;
    BYTE        m_ucCalcMode;
    BYTE        m_ucAccumulate;
    BYTE        m_ucAdditive;
    BYTE        m_ucAnimationType;
    double      m_dRepeatCount;
    UINT32      m_ulRepeatDur;
    double      m_dAccelerate;
    double      m_dDecelerate;
    double      m_dSpeed;
#if defined(XXXMEH_SPLINE_ANIMATION)
    UINT32      m_ulNumKeyTimes;
    double*     m_pdKeyTime;
    UINT32      m_ulNumKeySplines;
    KeySpline*  m_pKeySpline;
    UINT32      m_ulNumPathCmds;
    PathCmd**   m_ppPathCmd;
    UINT32      m_ulNumPathPoints;
#endif
    // ONLY HX_BITFIELD MEMBERS SHOULD GO BELOW THIS LINE!
    // ALL OTHER MEMBER TYPES SHOULD GO ABOVE THIS LINE!
    HX_BITFIELD m_bRepeatDurIsIndefinite : 1;
    HX_BITFIELD m_bAutoReverse : 1;
    HX_BITFIELD m_bIndefiniteSimpleDuration : 1;
    HX_BITFIELD m_bIndefiniteActiveDuration : 1;
    HX_BITFIELD m_bCancelAnimation : 1;
};

#endif /* #if defined(HELIX_FEATURE_SMIL2_ANIMATION) */

class CSmilParamElement : public CSmilElement
{
public:
    CSmilParamElement(SMILNode* pNode);
    virtual ~CSmilParamElement();

    IHXBuffer*   m_pName;
    IHXBuffer*   m_pValue;
    ParamDelivery m_eDelivery;
};

class CSmilParElement: public CSmilElement
{
public:
    CSmilParElement(SMILNode* pNode);
    virtual ~CSmilParElement();
};

class CSmilSeqElement: public CSmilElement
{
public:
    CSmilSeqElement(SMILNode* pNode);
    virtual ~CSmilSeqElement();
};

class CSmilExclElement: public CSmilElement
{
public:
    CSmilExclElement(SMILNode* pNode);
    virtual ~CSmilExclElement();

    CHXStack* m_pPauseStack;
};

#if defined(HELIX_FEATURE_SMIL2_TRANSITIONS)

class CSmilTransition: public CSmilElement
{
public:
    CSmilTransition(SMILNode* pNode);
    virtual ~CSmilTransition();

    virtual HX_RESULT handleElement();

    CHXString              m_Type;
    CHXString              m_SubType;
    double                 m_dStartProgress;
    double                 m_dEndProgress;
    TransitionDirection    m_eDirection;
    UINT32                 m_ulFadeColor;
    UINT32                 m_ulHorzRepeat;
    UINT32                 m_ulVertRepeat;
    UINT32                 m_ulBorderWidth;
    UINT32                 m_ulBorderColor;
    // ONLY HX_BITFIELD MEMBERS SHOULD GO BELOW THIS LINE!
    // ALL OTHER MEMBER TYPES SHOULD GO ABOVE THIS LINE!
    HX_BITFIELD            m_bBlendBorder : 1;
};

#endif /* #if defined(HELIX_FEATURE_SMIL2_TRANSITIONS) */

class CSmilBodyElement : public CSmilElement
{
public:
    CSmilBodyElement(SMILNode* pNode);
    virtual ~CSmilBodyElement();
};

#endif

