svgtopt/SVG/SVGImpl/src/SVGMediaAnimationElementImpl.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 07 Jan 2010 16:19:02 +0200
changeset 0 d46562c3d99d
permissions -rw-r--r--
Revision: 200951 Kit: 201001

/*
* Copyright (c) 2005-2006 Nokia Corporation and/or its subsidiary(-ies).
* All rights reserved.
* This component and the accompanying materials are made available
* under the terms of "Eclipse Public License v1.0"
* which accompanies this distribution, and is available
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
*
* Initial Contributors:
* Nokia Corporation - initial contribution.
*
* Contributors:
*
* Description:  SVG Implementation source file
 *
*/

#if !defined(__E32BASE_H__)
#include <e32base.h>
#endif

#include "Gfx2dGcOpenVG.h"
#include "GfxRoundRectangle2D.h"
#include "SVGMediaAnimationElementImpl.h"
#include "SVGDocumentImpl.h"
#include "SVGEngineImpl.h"
#include "SVGSchemaData.h"
#include "SVGEventHandler.h"

_LIT( KXlink, "xlink:href" );
_LIT( KFocusable, "focusable" );
_LIT(KInitialVisibility, "initialVisibility");
_LIT( KSvgFile, ".svg");
_LIT( KSvgbFile, ".svgb");
_LIT( KSvgzFile, ".svgz");
_LIT(msg, "Fail to open file for reading: ");
_LIT( KErrorMsg, "Failed to Load Svg Content: Read File Size Error." );
_LIT( KMemoryErrorMsg, "Failed to Load Svg Content: Out of memory");
_LIT( KReadErrorMsg, "Failed to Load Svg Content: Read File Data Error");
_LIT(KEngineFailed, "Failed to Create Svg Document: Out of Memory");
_LIT( KTmpDur, "dur" );
_LIT( KTmpDurMedia, "media" );

CSvgMediaAnimationElementImpl* CSvgMediaAnimationElementImpl::NewL(const TUint8
                                               aElemID,CSvgDocumentImpl* aDoc )
    {
    CSvgMediaAnimationElementImpl* self = CSvgMediaAnimationElementImpl::NewLC
                                                                (aElemID,aDoc);
    CleanupStack::Pop();
    return self;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
CSvgMediaAnimationElementImpl* CSvgMediaAnimationElementImpl::NewLC(const TUint8
                                              aElemID, CSvgDocumentImpl* aDoc )
    {
    CSvgMediaAnimationElementImpl* self = new ( ELeave ) CSvgMediaAnimationElementImpl( aDoc );
    CleanupStack::PushL( self );
    self->ConstructL(  aElemID,aDoc );
    return self;
    }

// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::SetSyncBehavior
// Set the Synchronised behaviour for the animation element
// -----------------------------------------------------------------------------
//        
void CSvgMediaAnimationElementImpl::SetSyncBehavior( const TDesC& aValue )
    {
    CSvgMediaElementBase::SetSyncBehavior( aValue );
    // If document is created then set the sync value to the time container
    if ( iNewDocument )
        {
        iNewDocument->SetTCSyncBehavior( iSyncBehavior );
        }
    }

// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::SetSyncTolerance
// Set the Synchronised Tolerance for the animation element
// -----------------------------------------------------------------------------
//        
void CSvgMediaAnimationElementImpl::SetSyncTolerance( const TDesC& aValue )
    {
    CSvgMediaElementBase::SetSyncTolerance( aValue );
    
    // If document is created then set the sync value to the time container
    if ( iNewDocument )
        {
        iNewDocument->SetTCSyncTolerance( iSyncTolerance );
        }
    }

// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::SetSyncMaster
// Set the animation element as Synchronised Master
// -----------------------------------------------------------------------------
//        
void CSvgMediaAnimationElementImpl::SetSyncMaster( const TDesC& aValue )
    {
    CSvgMediaElementBase::SetSyncMaster( aValue );

    // If document is created then set the sync value to the time container
    if ( iNewDocument )
        {
        iNewDocument->SetTCSyncMaster( iSyncMasterConfig );
        }
    }
    
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::ConstructL(  const TUint8 aElemID,
                                       CSvgDocumentImpl*  /* aDoc */ )
    {
	CSvgMediaElementBase::ConstructL( aElemID );
	iViewBoxImpl = CSvgFitToViewBoxImpl::NewL();
	iIsFocusable = ETrue;
	iDurMediaTime = ETrue;
    iSvgError = CSvgErrorImpl::NewL();
    if(!iSvgTransformable)
        iSvgTransformable = CSvgTransformableImpl::NewL();
    iChildSvgName = HBufC::NewL( 100 );
	#ifdef SVG_FLOAT_BUILD
    iX = ( 0 );
    iY = ( 0 );
	#else
    iX.operator = ( 0 );
    iY.operator = ( 0 );
	#endif
	
	#ifdef SVG_FLOAT_BUILD
   
    iScale = ( 0 );
	#else
    iScale.operator = ( 0 );
	#endif
	iIsOriginalRootTrSet = EFalse;
	if (OwnerDocument())
	{
	((CSvgDocumentImpl*)OwnerDocument())->AddInternalMouseListener( this );
	     ((CSvgDocumentImpl*)iOwnerDocument)->AddToEventReceiverListL(
                                               this, KSvgEventMaskExternalUI );
	}
	
    }

// ---------------------------------------------------------------------------
//  Constructor
// ---------------------------------------------------------------------------

CSvgMediaAnimationElementImpl::CSvgMediaAnimationElementImpl
                               ( CSvgDocumentImpl* aDoc ):CSvgMediaElementBase
                               ( aDoc ),iAnimationStatus(EPlayerStateIdle),iInitialVisibility(EAnimationNotVisible)
                          

    {
    iAttrId = KAtrMediaAnimationId;
	}
	
// ---------------------------------------------------------------------------
// perform a deep clone of this object
// ---------------------------------------------------------------------------
MXmlElement* CSvgMediaAnimationElementImpl::CloneL(MXmlElement* aParentElement)
    {
    CSvgMediaAnimationElementImpl* newElement = CSvgMediaAnimationElementImpl::
    NewL( this->ElemID(), ((CSvgDocumentImpl*)iOwnerDocument) );

    CleanupStack::PushL(newElement);
    newElement->iParentNode = aParentElement;
    // copy everything over
    this->CopyL(newElement);
    CleanupStack::Pop();
    return newElement;
    }
	
// ==========================================================================
// perform a deep copy of this object
// ==========================================================================
void CSvgMediaAnimationElementImpl::CopyL( CSvgMediaAnimationElementImpl* aDestElement )
    {
    if(aDestElement)
		{
	    // copy stuff from superclass
	    this->CSvgElementImpl::CopyL(aDestElement);
	    this->CSvgMediaElementBase::CopyL(aDestElement);
	    aDestElement->iWidth = iWidth;
        aDestElement->iHeight = iHeight;
        aDestElement->iInitialVisibility = iInitialVisibility;
        aDestElement->iDurMediaTime = iDurMediaTime;
        aDestElement->iX = iX;
        aDestElement->iY = iY;
        aDestElement->iScale = iScale;
        aDestElement->iOriginalRootTr = iOriginalRootTr;
        aDestElement->iIsOriginalRootTrSet = iIsOriginalRootTrSet;
        aDestElement->iAnimationStatus = iAnimationStatus;
        aDestElement->iTargetElement = ( CSvgElementImpl * ) ParentNode();
		aDestElement->iTargetSet = ETrue;
		TInt handle = 0;
        TInt engine = 0;
        TPtr    tPtr    = this->iChildSvgName->Des();
        aDestElement->PrepareDomChildSvg(tPtr,handle,engine);
		
	    }

    }
	
// ---------------------------------------------------------------------------
//  Destructor
// ---------------------------------------------------------------------------
CSvgMediaAnimationElementImpl::~CSvgMediaAnimationElementImpl()
    {
        
    delete iViewBoxImpl;
    delete iSvgError;
    delete iNewDocument;
    iSvgMouseEnteredElements.Close(); 
    delete iChildSvgName;        
    }

  
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
TInt CSvgMediaAnimationElementImpl::SetAttributeL( const TDesC& aName,
                                          const TDesC& aValue )
    {
     CSvgElementImpl::SetAttributeL(aName,aValue);
            //added for the bug if no begin is given
    if ( !iTargetSet )
			{
			// default is parent element
			iTargetElement = ( CSvgElementImpl * ) ParentNode();
			iTargetSet = ETrue;
			}

    // Encapsulates both viewBox and preserveAspectRatio attributes.
    if ( iViewBoxImpl->SetViewBoxL( aName, aValue ) )
        {
                if ( iNewDocument && iNewDocument->RootElement() )
                    {
                        MSvgPreserveAspectRatio* lAspectRatio;
                        iViewBoxImpl->GetPreserveAspectRatio(lAspectRatio);
                        
                        if ( lAspectRatio )
                            {
                            ((CSvgSvgElementImpl *)
                             (iNewDocument->RootElement()))->SetPreserveAspectRatioL
                             (lAspectRatio->GetAlign(), lAspectRatio->GetMeetOrSlice());                
                            }    
                    }
                
                return KErrNone;
        }
    
    if ( aName == KXlink )
        {
            if ( aValue.Length() != 0 )
            {
            iChildSvgName = iChildSvgName->ReAlloc(aValue.Length());
            TPtr    tPtr    = iChildSvgName->Des();
            tPtr.Copy( aValue );
            TInt length = tPtr.Length();
            TPtrC tPtrCSvg = tPtr.Right(4);
            TPtrC tPtrCSvgX = tPtr.Right(5);
            
            if ( tPtrCSvg.Find(KSvgFile) == KErrNotFound && 
                            tPtrCSvgX.Find(KSvgbFile) == KErrNotFound  
                            && tPtrCSvgX.Find(KSvgzFile) == KErrNotFound  )
                {
                return KErrGeneral;
                }
            else
                {
                TInt handle = 0;
                TInt engine = 0;
                TPtrC fileName;
                PrepareDomChildSvg(tPtr,handle,engine);
               
                // Check if error occured
                if ( !iSvgError->HasError() )
                    {
                    // If document is valid then set parameters of child svg
                    // element from animation element 
                    
                    if ( iNewDocument && iNewDocument->RootElement() )
                        {
                        ((CSvgSvgElementImpl *)
                         (iNewDocument->RootElement()))->iWidthInPercentage = EFalse;
                        ((CSvgSvgElementImpl *)
                         (iNewDocument->RootElement()))->iHeightInPercentage = EFalse;
                        ((CSvgSvgElementImpl *)
                         (iNewDocument->RootElement()))->SetWidth((TFloatFixPt)iWidth);
                        ((CSvgSvgElementImpl *)
                         (iNewDocument->RootElement()))->SetHeight((TFloatFixPt)iHeight);
                       
                  // Set the Sync Values from animation element to time container
                        // Sync Behaviour
                        iNewDocument->SetTCSyncBehavior( iSyncBehavior );
                        // Sync Tolerance
                        iNewDocument->SetTCSyncTolerance( iSyncTolerance );
                        // Sync Mastership
                        iNewDocument->SetTCSyncMaster( iSyncMasterConfig );
                        
                        MSvgPreserveAspectRatio* lAspectRatio;
                        iViewBoxImpl->GetPreserveAspectRatio(lAspectRatio);
                        
                        if ( lAspectRatio )
                            {
                            ((CSvgSvgElementImpl *)
                             (iNewDocument->RootElement()))->
                             SetPreserveAspectRatioL(lAspectRatio->GetAlign(), 
                             lAspectRatio->GetMeetOrSlice());                
                            }
                   
                        }
                    }
                 else  
                    {
                      return KErrGeneral;
                    }
                }
              }
		}
	
    else if ( aName == KFocusable )
        {
            if ( aValue == _L("true") )
                iIsFocusable = ETrue;
            if ( aValue == _L("false") )
                 iIsFocusable = EFalse;
        }
    else if ( aName == KInitialVisibility )    
        {
                if ( aValue == _L("always") )
                {
                    iInitialVisibility =  EAnimationVisible;
                }
        }
    else if ( aName == KTmpDur && aValue != KTmpDurMedia )
           {
           iDurMediaTime = EFalse;
           return CSvgMediaElementBase::SetAttributeL(aName, aValue);
           }
    else 
	    {
   	    return CSvgMediaElementBase::SetAttributeL(aName, aValue);
	    }

	return KErrNone;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
TInt  CSvgMediaAnimationElementImpl::SetAttributeDesL( const TInt aNameId,
											   const TDesC& aValue )
	{
	return CSvgMediaElementBase::SetAttributeDesL( aNameId, aValue );
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
TInt CSvgMediaAnimationElementImpl::GetAttributeFloat(const TInt aNameId,
                                                TFloatFixPt& aValue )
    {
     switch ( aNameId )
     {
     case KAtrX:
	   aValue = iX ;
	   break;

     case KAtrY:
	   aValue = iY ;
	   break;

     case KAtrWidth:
	   aValue = iWidth ;
	   break;

     case KAtrHeight:
	   aValue = iHeight ;
	   break;
     default:
       return CSvgMediaElementBase::GetAttributeFloat( aNameId, aValue );
     }
        
     return KErrNone;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
TInt CSvgMediaAnimationElementImpl::SetAttributeFloatL( const TInt aNameId,
                                               TFloatFixPt aValue )
    {
      switch ( aNameId )
      {
      case KAtrX:
          iX = aValue;
          SetInitialCTM();
          break;

      case KAtrY:
          iY = aValue;
          SetInitialCTM();
          break;
          
      case KAtrWidth:
          iWidth = aValue;
          break;

      case KAtrHeight:
          iHeight= aValue;
          break;
      
      default:
         return CSvgMediaElementBase::SetAttributeFloatL( aNameId, aValue );
        }
      return KErrNone;
    }

// ---------------------------------------------------------------------------
// From MSvgEventReceiver
// ---------------------------------------------------------------------------

TBool CSvgMediaAnimationElementImpl::ReceiveEventL( MSvgEvent* aEvent )
    {
    if( CSvgElementImpl::IsSVGEnginePaused())
    {
    	return EFalse;
    }
    
    if ( !iNewDocument )
        {
        return EFalse;
        }
    // Process animation element's events first    
    TBool lSelfRedrawReqd = CSvgMediaElementBase::ReceiveEventProcL( aEvent, 
        this );
    
    CSvgElementImpl::ReceiveEventL(aEvent);    
    // Only External UI events are sent to the child document
    if ( ( aEvent->EventMask() & KSvgEventMaskExternalUI ) )
        {
        TInt lEvtTime = 0;
        // Save the time as the ProcessEvent modifies the time of the event
        // to the document's current time for keypress events
        if ( aEvent->EventType() == ESvgEngineEventKeyPress )
            {
            lEvtTime = ( ( MSvgUiKeyEvent * ) aEvent )->Time();
            }
        
        // Send the events to the child document
        ( ( ( CSvgDocumentImpl* )
            iOwnerDocument )->Engine() )->ProcessEventL( iNewDocument, 
            aEvent, EFalse );
  
        // Restore the time, so that when the event is propogated to 
        // further elements in the DOM tree, the time is in sync with
        // respect to current document time. 
        if ( aEvent->EventType() == ESvgEngineEventKeyPress )
            {
            ( ( MSvgUiKeyEvent * ) aEvent )->SetTime( lEvtTime );
            }
            
        }
    return lSelfRedrawReqd;
     
  
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------

void CSvgMediaAnimationElementImpl::ResetAnimationL()
    {
  	// Check if document is valid
	if ( !iNewDocument || !iNewDocument->RootElement() )
	    {
	    return;
	    }

        if (( iAnimStatus == KAnimActive ) ||
		( iAnimStatus == KAnimFinished) ||
		( iAnimStatus == KAnimEnd))
		{
		if (( iAnimationStatus == EPlayerStatePlaying ) ||
			( iAnimationStatus == EPlayerStateStop ))
			{
			// if previously audio is still playing, and asked to play again...
	            iNewDocument->SetCurrentTime( 0 );
                
                   iNewDocument->iAnimationResetNeeded = ETrue;
                
                if(this->iNewDocument && this->iNewDocument->iEventHandler)
                    {
                    this->iNewDocument->iEventHandler->SetCurrentTime(0);
                    }
            	
            	 TSvgTimerEvent timeEvent(0);
            	
            	
            	 iNewDocument->Reset( &timeEvent );
        	// Save the animation start tick so that
        	// child document's tick can be correctly offset
	    	iBeginTick = ( ( CSvgDocumentImpl* )
	    	    iOwnerDocument )->TimeContainer()->GetCurTick(); 
	    	iAnimationStatus = EPlayerStatePlaying;
			}
		}
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::Reset( MSvgEvent* aEvent )
	{

	iIsUserSeek = ETrue;

	// call the animation base function.
	TSvgTimerEvent* timerEvent  = ( TSvgTimerEvent* ) aEvent;


	if ( (TInt32)timerEvent->Time() < iAbsoluteBeginTime )
		{
		// let it come to initial position.
		((CSvgDocumentImpl*)iOwnerDocument)->iInitialDrawFlag = ETrue;
		ReInitializeAnimation();
		// Seek to the initial position means that 
		// animation should also be drawn in initial position
    	if ( iNewDocument && iNewDocument->RootElement() )
    	    {
            iNewDocument->SetCurrentTime( 0 );
            iNewDocument->iAnimationResetNeeded = ETrue;

            if ( this->iNewDocument && this->iNewDocument->iEventHandler )
                {
                this->iNewDocument->iEventHandler->SetCurrentTime(0);
                }

            TSvgTimerEvent timeEvent(0);
            iNewDocument->Reset( &timeEvent );    	    
    	    }
		return;
		}
	TRAPD(error,CSvgMediaElementBase::ResetL( aEvent, this));

		if ( error != KErrNone )
		{
			// error processing not processed
			return;
		}
	}  

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------

TBool CSvgMediaAnimationElementImpl::DoAnimProcL(MSvgEvent* aEvent)
    {
        if ( !iNewDocument )
        {
            return EFalse;
        }
    return this->AnimProcL((MSvgTimerEvent*)aEvent);
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------

TBool CSvgMediaAnimationElementImpl::IsViewable()
    {
     if ( iInitialVisibility == EAnimationVisible )
        {
        return ETrue;
        }
        return EFalse;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::Print( TBool /*aIsEncodeOn */)
    {
	    // No implementation.
    }  
       
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
TBool CSvgMediaAnimationElementImpl::DrawL( CGfx2dGc* aGc, 
                                           CSvgElementImpl* /* aElement */)
    {
    // Check if document is valid
	if ( !iNewDocument || !iNewDocument->RootElement() || (TInt)iWidth==0 || 
	                                                      (TInt)iHeight==0 )
	    {
	    return EFalse;
	    }

    // if iInitialVisibility status is EAnimationInitialised then draw won't happen
    if ( iInitialVisibility == EAnimationNotVisible || 
                            iInitialVisibility == EAnimationVisible )
        {
        
            // visibility is set to initialised state to get font before actual draw
            if ( iInitialVisibility == EAnimationNotVisible )
                {
                    iInitialVisibility = EAnimationInitialised;    
                }
            
            TReal32 opacity = 1;
            TGfxRoundRectangle2D        Rectangle;
            TGfxAffineTransform aTr = GetCTM();
            ((CSvgSvgElementImpl *)(iNewDocument->RootElement()))->SetTransformList
                                                                   (iOriginalRootTr);
            ((CSvgElementImpl*)iNewDocument->RootElement())->UpdateCTM();   
            
            iNewDocument->iIsRendering = ETrue; 
            ((CGfx2dGcOpenVG*)aGc)->BindToMediaImageL(iScale * iWidth,iScale * iHeight);
            (iNewDocument->Engine())->DrawElementsL((CSvgElementImpl*)
                                      (iNewDocument->RootElement()));
            iNewDocument->iIsRendering = EFalse; 
            TGfxAffineTransform tMatrix;
            tMatrix = aTr;
            
            #ifdef SVG_FLOAT_BUILD
            tMatrix.Scale( ( TFloatFixPt( 1 ) / ( iScale ) ), 
                             ( TFloatFixPt( 1 ) / ( iScale ) ) );
            #else
            tMatrix.Scale( ( TFloatFixPt( 0x10000,ETrue ) / ( iScale ) ), 
                             ( TFloatFixPt( 0x10000,ETrue ) / ( iScale ) ) );
            #endif
            
            // draw happens only if iInitialVisibility status is EAnimationVisible
            // i.e. animation element has started its animation
            
            ((CGfx2dGcOpenVG*)aGc)->UnbindFromMediaImageL(tMatrix,opacity,150,150,iInitialVisibility);
            
            tMatrix.Concatenate(iOriginalRootTr);
            ((CSvgSvgElementImpl *)(iNewDocument->RootElement()))->SetTransformList
                                                                   (tMatrix);
            ((CSvgElementImpl*)iNewDocument->RootElement())->UpdateCTM();   
             return ETrue;
        }
        
      return EFalse;  
    }

//---------------------------------------------------------------------------
//
//---------------------------------------------------------------------------    
void CSvgMediaAnimationElementImpl::SetInitialCTM()
    {
 
       TGfxAffineTransform aTr(1,0,0,1,iX,iY);
       SetTransformList(aTr);
    }

// ---------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::GetChildDocument()
// Accessor function for obtaining the child SVG document
// ---------------------------------------------------------------------------
CSvgDocumentImpl* CSvgMediaAnimationElementImpl::GetChildDocument()
    {
        if ( iNewDocument )
         return iNewDocument;
        else 
          return NULL;
    }
    
// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::SetPreserveAspectRatioL
// From CSvgElementImpl
// -----------------------------------------------------------------------------
//        
void CSvgMediaAnimationElementImpl::SetPreserveAspectRatioL( 
    TSvgPreserveAspectAlignType aAlign,
    TSvgMeetOrSliceType aMeetSlice )
    {
    iViewBoxImpl->SetPreserveAspectRatioL( aAlign, aMeetSlice);
    }
    
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::SetWidth(TReal32 aValue)
    {
      iWidth = aValue;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::SetHeight(TReal32 aValue)
    {
     iHeight = aValue;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------    
MSvgError* CSvgMediaAnimationElementImpl::PrepareDomChildSvg
                           (const TDesC& aFileName,TInt& aHandle, TInt aEngine)
    {
         // Create session to open file
    RFs session;
    CSvgDocumentImpl::OpenSession( session, *iSvgError );
    if ( iSvgError->HasError() )
    {
        return iSvgError;
    }

    // Open file handle
    RFile fileHandle;
    TInt openError = 0;
    
    if ( ((CSvgDocumentImpl*)iOwnerDocument)->Engine() == NULL  )
       {
       return iSvgError;
       }
    if ( (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->iRequestObserver == NULL) 
       {
       return iSvgError;	
       }
    
    openError = (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->iRequestObserver
   									->FetchImage( aFileName, session,fileHandle  );
   
    if ( openError != KErrNone )
       {
       CSvgDocumentImpl::PrepareError( *iSvgError, ESvgUnknown, openError,
                                        msg, aFileName );
       fileHandle.Close();
       session.Close();
       return iSvgError;                                 
       }
     else
       {
       PrepareDomChildSvg( fileHandle, aHandle, aEngine );
       }
        
     // If iDurMediaTime is ETrue then it means dur has been set as sometime
     // else dur was not there and defauly media duration is set.
     // iDurMediaTime is set to ETrue by default.
        if ( iDurMediaTime  )
           {
           TUint32 dur =  iNewDocument->AnimationDuration();
           if ( dur == 0xFFFFFFFF )
              {
              fileHandle.Close();
    		  session.Close();
    		  return iSvgError;
              }
           dur /=  1000; 
           TBuf<10> number;
           number.Num(dur); 
           CSvgMediaElementBase::SetAttributeL(KTmpDur, number);    	
           }
        
        
     
    fileHandle.Close();
    session.Close();
    return iSvgError;
    }
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------    
 MSvgError* CSvgMediaAnimationElementImpl::PrepareDomChildSvg
                          ( RFile& aFileHandle, TInt& aHandle, TInt aEngine)
    {
        // reset to start of file
    TInt zero = 0;
    aFileHandle.Seek( ESeekStart, zero );

    TInt fileSize = 0;
    TInt sizeError = aFileHandle.Size( fileSize );
    if ( sizeError != KErrNone )
    {
        
        CSvgDocumentImpl::PrepareError( *iSvgError, ESvgUnknown, sizeError,
                                        KErrorMsg, KNullDesC );
        return iSvgError;
    }

    HBufC8* byteArray = NULL;
    TRAPD( error, byteArray = HBufC8::NewL( fileSize ) );
    if ( error != KErrNone )
    {
        
        CSvgDocumentImpl::PrepareError( *iSvgError, ESvgNoMemory, error,
                                        KMemoryErrorMsg, KNullDesC );
        return iSvgError;
    }

    TPtr8 des = byteArray->Des();
    TInt readError = aFileHandle.Read( des );
    if ( readError != KErrNone )
    {
        
        CSvgDocumentImpl::PrepareError( *iSvgError, ESvgNoMemory, error,
                                        KReadErrorMsg, KNullDesC );
        delete byteArray;
        return iSvgError;
    }

    PrepareDomChildSvg( *byteArray, aHandle, aEngine );
    delete byteArray;
    return iSvgError;
    
    }
    
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------  
    
MSvgError* CSvgMediaAnimationElementImpl::PrepareDomChildSvg(const TDesC8& aByteData, 
    TInt& aHandle, TInt /* aEngine */)  
    {
    aHandle = 0;

    // Clear Error
    iSvgError->SetErrorCode( ESvgNoError );


    // CSvgDocumentImpl* newDocument = NULL;
    CSvgSvgElementImpl* lRoot = (CSvgSvgElementImpl* )((CSvgDocumentImpl* )
                                            iOwnerDocument)->RootElement();
    
    // Get the default sync behaviour from SVG element
    TSvgSyncBehaviour lRootSB = lRoot->SyncBehaviorDefault();
    
    // Get the default tolerance from SVG element
    TInt32 lRootST = lRoot->SyncToleranceDefault();
    
    // Indicate ETrue while creating document to indicate that
    // document has a parent
    CSvgBitmapFontProvider *tempBitmapFontProvider = 
            ((CSvgDocumentImpl*)iOwnerDocument)->GetBitmapFontProvider();
            
    TRAPD( error, iNewDocument = CSvgDocumentImpl::NewL( tempBitmapFontProvider,
            ETrue, lRootSB, lRootST ) );
    
    // Check for error
    if ( error != KErrNone )
        {
        #ifdef _DEBUG
        RDebug::Print(KEngineFailed);
        #endif //_DEBUG
        CSvgDocumentImpl::PrepareError( *iSvgError, ESvgNoMemory, error,
                                        KEngineFailed, KNullDesC );
        return iSvgError;
        }

    // Set appropriate flags to documents
    iNewDocument->SetWasPrepared( !iIsLoadingRequest );
    iNewDocument->SetDRMMode( iDrmEnabled );
    iNewDocument->SetThumbNailMode( iIsThumbNailMode );
  

    iNewDocument->SetEngine(((CSvgDocumentImpl*)iOwnerDocument)->Engine());
    iNewDocument->SetLoadingListeners(((CSvgDocumentImpl*)iOwnerDocument)
                                                 ->GetLoadingListeners());

    // Parse document
    iNewDocument->Load( aByteData, *iSvgError );

    #ifdef _DEBUG
    if ( iNewDocument->GetError() && iNewDocument->GetError()->HasError() )
        {
        RDebug::Printf("Load warning: ");
        RDebug::RawPrint( iNewDocument->GetError()->Description() );
        }
    #endif

    iFileIsLoaded = !iSvgError->HasError() || iSvgError->IsWarning();

    // Parsing error or out of memory
    if ( !iFileIsLoaded )
        {
        return iSvgError;
        }

    aHandle = (TInt)iNewDocument;

    // Add the animation element as an observer on the child time 
    // container
    iNewDocument->TimeContainer()->SetTcObserver( this );

    return iSvgError;
    }
    
// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::ParentTimeContainerTick
// From CSvgMediaElementBase
// -----------------------------------------------------------------------------
//
void CSvgMediaAnimationElementImpl::ParentTimeContainerTick( 
    TSvgTick /* aTick */) // Current tick information 
    {
        //empty implementation
    }
       

// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::GetEntityCurrentTime
// From CSvgMediaElementBase
// -----------------------------------------------------------------------------
//        
void CSvgMediaAnimationElementImpl::GetEntityCurrentTime( TUint32& 
            aEntityCurTime ) // Current Entity Time in msecs. 
    {
    if ( iNewDocument )
        {
        // Access time container from child document
        CSvgTimeContainer* lChildTC = iNewDocument->TimeContainer();
            
        if ( lChildTC )
            {
            lChildTC->GetEntityCurrentTime( aEntityCurTime );        
            // Adjust the time from the timed entity to compensate
            // the BeginTick's parent time container tick
            aEntityCurTime += iBeginTick.iParentTcTick;
            }
        }
    }

// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::SetCurSyncMasterStatus
// From CSvgMediaElementBase
// -----------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::SetCurSyncMasterStatus( 
    TBool aSyncMasterStatus ) //  Indicates whether the element is currrently 
                              // Sync Master.
    {
    // Set the current sync master status
    CSvgMediaElementBase::SetCurSyncMasterStatus( aSyncMasterStatus );
    if ( iNewDocument )
        {
        // Access time container from child document
        CSvgTimeContainer* lChildTC = iNewDocument->TimeContainer();
            
        if ( lChildTC )
            {
            lChildTC->SetCurSyncMasterStatus( aSyncMasterStatus );        
            }    
        }
    }

// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::CanGenerateTick
// From CSvgMediaElementBase
// -----------------------------------------------------------------------------
TBool CSvgMediaAnimationElementImpl::CanGenerateTick()
    {
    if ( iNewDocument )
        {
        // Access time container from child document
        CSvgTimeContainer* lChildTC = iNewDocument->TimeContainer();
            
        if ( lChildTC )
            {
            return ( lChildTC->CanGenerateTick() );
            }
        }
    return EFalse; 
    }

// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::ResyncTimedEntity
// From CSvgMediaElementBase
// -----------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::ResyncTimedEntity( 
            TUint32 /* aSynctime */ ) // Time for resync in msecs.
    {
    // Empty Implementation
    }    
// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::PauseTimedEntity
// From CSvgMediaElementBase
// -----------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::PauseTimedEntity()
    {
    iIsSyncPauseIssued = ETrue;
    if ( iNewDocument && iAnimationStatus == EPlayerStatePlaying )
        {
        iAnimationStatus = EPlayerStatePaused;
        }
    }

// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::ResumeTimedEntity
// From CSvgMediaElementBase
// -----------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::ResumeTimedEntity()
    {
    iIsSyncPauseIssued =  EFalse;
    if ( iNewDocument && iAnimationStatus == EPlayerStatePaused )
    	{
    	// The child time container recieves the event from the parent time
    	// container directly.
	    iAnimationStatus = EPlayerStatePlaying;
    	}    
    }

// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::StopTimedEntity
// From CSvgMediaElementBase
// -----------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::StopTimedEntity()
    {
    if ( iNewDocument )
    	{
    	iAnimationStatus = EPlayerStateStop;
    	}    
    }
    

//From MSvgTimedEntityInterface
TSvgObjectType CSvgMediaAnimationElementImpl::ObjectType()
    {
	return ESvgMediaAnimationElement;	
    }


//returns the child time container of the element 
//used in timecontainer
CSvgTimeContainer* CSvgMediaAnimationElementImpl::GetChildTimeContainer()
    {
    //Check for valid document and get time container from documentimpl
    if ( iNewDocument )
        {
        return iNewDocument->TimeContainer();
        }
    else
        {
        return NULL;    
        }
    }
// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::TimeContainerReady
// From MSvgTimeContainerObserver
// -----------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::TimeContainerReady()
    {
    // Access time container from owner document
    CSvgTimeContainer* lOwnerTC = ((CSvgDocumentImpl* )
        iOwnerDocument)->TimeContainer();
        
    if ( lOwnerTC )
        {
        lOwnerTC->TimedEntityReady( this );        
        }
    }

// -----------------------------------------------------------------------------
// CSvgMediaAnimationElementImpl::TimeContainerNotReady
// From MSvgTimeContainerObserver
// -----------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::TimeContainerNotReady()
    {
    // Access time container from owner document
    CSvgTimeContainer* lOwnerTC = ((CSvgDocumentImpl* )
        iOwnerDocument)->TimeContainer();
        
    if ( lOwnerTC )
        {
        lOwnerTC->TimedEntityNotReady( this );        
        }    
    }
    
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------

TBool CSvgMediaAnimationElementImpl::AnimProcL( MSvgTimerEvent* /* aEvent */ )
    {
#ifdef _DEBUG    
	RDebug::Print(_L("%d %d"), iAnimStatus, IsAnimating());
#endif
	// Check if document is valid
	if ( !iNewDocument || !iNewDocument->RootElement() )
	    {
	    return EFalse;
	    }
    if ( iAnimationStatus == EPlayerProhibit )
        return EFalse;
    if ( iAnimTime->DurationTime() == KTimeIndefinite || iAnimTime->DurationTime() == 0 )
        {
         return EFalse;
        }
	
    if ( iAnimStatus != KAnimActive )
        {
        if ( iAnimationStatus == EPlayerStatePlaying )
    		{
             //stop child svg animation based on freeze/remove value.
            if( iFill == KAnimFillRemove )
                {
                    iNewDocument->SetCurrentTime( 0 );
                
                   iNewDocument->iAnimationResetNeeded = ETrue;
                 
                    if  (iNewDocument && iNewDocument->iEventHandler )
                    {
                    iNewDocument->iEventHandler->SetCurrentTime(0);
                    }
            	
            	    TSvgTimerEvent timeEvent(0);
            	
            	
            	    iNewDocument->Reset( &timeEvent );
                }
            
        	iAnimationStatus = EPlayerStateStop;
        	return EFalse;
    		}
        }
    else //iAnimStatus == KAnimActive
        {
        if ( !iHadBegun )
            {
            iHadBegun = ETrue;
            // animation element can be drawn now
            iInitialVisibility = EAnimationVisible;
            // this is a restart from begin list.
            if ( (iAnimationStatus != EPlayerStateIdle) )
//            	(iAnimationStatus != EPlayerStatePlayInit))
            	{
            	
            	//child svg animataion should begin from 0 again, seek it to zero.
            	
            	// Remember the current time as beginning of the animation.
            	
                   iNewDocument->SetCurrentTime(0);
                
                   iNewDocument->iAnimationResetNeeded = ETrue;
                
                if ( this->iNewDocument && this->iNewDocument->iEventHandler )
                    {
                    this->iNewDocument->iEventHandler->SetCurrentTime(0);
                    }
            	
            	 TSvgTimerEvent timeEvent(0);
            	
            	
            	 iNewDocument->Reset( &timeEvent );
            	
            	// Save the animation start tick so that
            	// child document's tick can be correctly offset
		    	iBeginTick = ( ( CSvgDocumentImpl* )
		    	    iOwnerDocument )->TimeContainer()->GetCurTick(); 
		    	iAnimationStatus = EPlayerStatePlaying;
		    	
            	}
            return ETrue;
            }
            
            
        if ( iAnimationStatus == EPlayerStateIdle ) // stopped
            {
            //child svg animataion should begin from 0 i.e for the first time
            // Remember the current time as beginning of the animation.
             iNewDocument->SetCurrentTime( 0 );
                
                   iNewDocument->iAnimationResetNeeded = ETrue;
                
                if ( this->iNewDocument && this->iNewDocument->iEventHandler )
                    {
                    this->iNewDocument->iEventHandler->SetCurrentTime(0);
                    }
            	
            	 TSvgTimerEvent timeEvent(0);
            	
            	
            	 iNewDocument->Reset( &timeEvent );
            	            
            	// Save the animation start tick so that
            	// child document's tick can be correctly offset
		    	iBeginTick = ( ( CSvgDocumentImpl* )
		    	    iOwnerDocument )->TimeContainer()->GetCurTick(); 
       		    iAnimationStatus = EPlayerStatePlaying;
           	    return ETrue;
            }
            
            if ( iAnimationStatus == EPlayerStatePlaying )
                {

                // child svg active and in running state so pass the tick
                // to the child svg's time container
                // Subtract the reference begin tick from the current tick 
                // before giving the tick.
                TSvgTick lChildTick = ( ( CSvgDocumentImpl* )
		    	    iOwnerDocument )->TimeContainer()->GetCurTick(); 
                
                lChildTick.iParentTcTick -= iBeginTick.iParentTcTick;
                lChildTick.iRealTimeTick -= iBeginTick.iRealTimeTick;
                lChildTick.iParentTcTick -= iNegativeBeginTime;
                lChildTick.iRealTimeTick -= iNegativeBeginTime;
                iNewDocument->TimeContainer()->ParentTimeContainerTick
                                               ( lChildTick );
                }
             if ( iAnimationStatus == EPlayerStateStop )
        	{
            	
        	       iNewDocument->SetCurrentTime( 0 );
                   iNewDocument->iAnimationResetNeeded = ETrue;
                
                if ( this->iNewDocument && this->iNewDocument->iEventHandler )
                    {
                    this->iNewDocument->iEventHandler->SetCurrentTime(0);
                    }
            	
            	 TSvgTimerEvent timeEvent(0);
            	
            	
            	 iNewDocument->Reset( &timeEvent );
            	            
            	// Save the animation start tick so that
            	// child document's tick can be correctly offset
		    	iBeginTick = ( ( CSvgDocumentImpl* )
		    	    iOwnerDocument )->TimeContainer()->GetCurTick(); 
       		    iAnimationStatus = EPlayerStatePlaying;
           	    return ETrue;   
        	}    
        }


    return ETrue;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------

void CSvgMediaAnimationElementImpl::InitAnimationL()
    {
        if ( !iNewDocument )
        {
            return;
        }
    CSvgMediaElementBase::InitAnimationL();
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::GetPreserveAspectRatio(
                                    MSvgPreserveAspectRatio*& aAspectRatio )
    {
    iViewBoxImpl->GetPreserveAspectRatio( aAspectRatio );
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
TFloatFixPt CSvgMediaAnimationElementImpl::X()
    {
    return iX;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
TFloatFixPt CSvgMediaAnimationElementImpl::Y()
    {
    return iY;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
TFloatFixPt CSvgMediaAnimationElementImpl::Width()
    {
    return iWidth;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
TFloatFixPt CSvgMediaAnimationElementImpl::Height()
    {
    return iHeight;
    }


// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------    
 void CSvgMediaAnimationElementImpl::GetBBox( TGfxRectangle2D& aBbox )
    {
        TGfxRoundRectangle2D        aRectangle;   
         
        aRectangle.iX = 0;
        aRectangle.iY = 0;
        aRectangle.iHeight = iHeight;
        aRectangle.iWidth =  iWidth;
        if ( !(TInt32)iHeight || !(TInt32)iWidth || iInitialVisibility != EAnimationVisible  )
            {
               aRectangle.iHeight = aRectangle.iWidth = 0;
            }
        aRectangle.GetBounds( GetCTM(), aBbox );
    }
    
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------    
void CSvgMediaAnimationElementImpl::GetFourPointBBox
                                    (TSvgFourPointRect& aFourPointBbox)
{
	const TGfxAffineTransform& ctm = GetCTM();
    TGfxRoundRectangle2D        aRectangle;   
    aRectangle.iX = 0;
    aRectangle.iY = 0;
    aRectangle.iHeight = iHeight;
    aRectangle.iWidth =  iWidth;
        
    if ( !(TInt32)iHeight || !(TInt32)iWidth )
    {
     aRectangle.iHeight = aRectangle.iWidth = 0;
    }
	TSvgFourPointRect lFourPointBox(aRectangle.iX, aRectangle.iY, aRectangle.iWidth, aRectangle.iHeight);

    TGfxPoint2D lPoint1, lPoint2, lPoint3, lPoint4;

    lFourPointBox.GetPoints(lPoint1, lPoint2, lPoint3, lPoint4);

    ctm.Transform(&lPoint1, &lPoint1, 1);
    ctm.Transform(&lPoint2, &lPoint2, 1);
    ctm.Transform(&lPoint3, &lPoint3, 1);
    ctm.Transform(&lPoint4, &lPoint4, 1);

    aFourPointBbox.SetRectPoints(lPoint1, lPoint2, lPoint3, lPoint4);
}

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::GetUnscaledBBox( TGfxRectangle2D& aBbox )
    {
    TGfxAffineTransform identityTx;
    TGfxRoundRectangle2D        aRectangle;   
    aRectangle.iX = iX;
    aRectangle.iY = iY;
    aRectangle.iHeight = iHeight;
    aRectangle.iWidth =  iWidth;
    aRectangle.GetBounds( identityTx, aBbox );
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------    
TBool CSvgMediaAnimationElementImpl::MouseEntered( 
                            RPointerArray<CSvgElementImpl>& /* aElements */,
                            TInt aX, TInt aY )
    
    {
    if ( !iNewDocument )
        {
        return EFalse;
        }
        
    TInt listenerCount = (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->
                                                     MouseListenerCount();

    if ( iNewDocument )
        {
        listenerCount += iNewDocument->MouseInternalListenerCount();
        }
    if ( listenerCount == 0 )
        {
        return EFalse;
        }
    // Get list of elements containing pointer (bounding-box)
    RPointerArray<CSvgElementImpl> viewableElements;
    RPointerArray<CSvgElementImpl> enteringElements;
    RPointerArray<CSvgElementImpl> stillInsideElements;
    (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->GetViewableElementsAtPoint
                                    (iNewDocument, viewableElements, aX, aY );

    // check for mouse entering of elements
    TInt viewableEleCnt = viewableElements.Count();
    for ( TInt i = 0; i < viewableEleCnt; i++ )
        {
        // If an element is in the view-list but NOT in the entered-list
        // then, it's copied to the entered-list
        // otherwise, ignore (still inside)
        if ( iSvgMouseEnteredElements.Find( viewableElements[i] ) 
             == KErrNotFound )
            {
            enteringElements.Append( viewableElements[i] );
            }
        else
            {
            stillInsideElements.Append( viewableElements[i] );
            }
        }

    // check for mouse exiting of elements
    RPointerArray<CSvgElementImpl> exitingElements;
    TInt svgMouseEnteredEleCnt = iSvgMouseEnteredElements.Count();
    for ( TInt i = 0; i < svgMouseEnteredEleCnt; i++ )
        {
        // If an element is in the entered-list but not the view-list
        // then, it's copied to the exiting list
        // otherwise, ignore (
        if ( viewableElements.Find( iSvgMouseEnteredElements[i] ) 
             == KErrNotFound )
            {
            exitingElements.Append( iSvgMouseEnteredElements[i] );
            }
        }

    // Remove exiting elements from entered list
    TInt exitingEleCnt = exitingElements.Count();
    for ( TInt i = 0; i < exitingEleCnt; i++ )
        {
        TInt index = iSvgMouseEnteredElements.Find( exitingElements[i] );
        if ( index != KErrNotFound )
            {
            iSvgMouseEnteredElements.Remove( index );
            }
        }

    // Add entering elements to entered-list
    TInt enteringEleCnt = enteringElements.Count();
    for ( TInt i = 0; i < enteringEleCnt; i++ )
        {
        iSvgMouseEnteredElements.Append( enteringElements[i] );
        }

    // Notify exiting
    if ( exitingElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMouseExited
                                                ( exitingElements, aX, aY );
        if ( iNewDocument )
            {
            iNewDocument->NotifyInternalMouseExited( exitingElements, aX, aY );
            }
        }

    // Notify entering
    if ( enteringElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMouseEntered
                                                ( enteringElements, aX, aY );
        if ( iNewDocument )
            {
            iNewDocument->NotifyInternalMouseEntered( enteringElements, aX, aY );
            }
        }

    // Notify moved
    if ( stillInsideElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMouseMoved
                                            ( stillInsideElements, aX, aY );
        if ( iNewDocument )
            {
            iNewDocument->NotifyInternalMouseMoved( stillInsideElements, aX, aY );
            }
        }

    exitingElements.Close();
    enteringElements.Close();
    stillInsideElements.Close();
    viewableElements.Close();
    
    
    return ETrue;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------    
TBool CSvgMediaAnimationElementImpl::MouseExited( 
    RPointerArray<CSvgElementImpl>& /* aElements */,
    TInt aX, TInt aY )
    {
     if ( !iNewDocument )
        {
        return EFalse;
        }
        
    TInt listenerCount = (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->
                                                    MouseListenerCount();

    if ( iNewDocument )
    {
        listenerCount += iNewDocument->MouseInternalListenerCount();
    }
    if ( listenerCount == 0 )
        {
        return EFalse;
        }
    // Get list of elements containing pointer (bounding-box)
    RPointerArray<CSvgElementImpl> viewableElements;
    RPointerArray<CSvgElementImpl> enteringElements;
    RPointerArray<CSvgElementImpl> stillInsideElements;
    (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->GetViewableElementsAtPoint
                                    (iNewDocument, viewableElements, aX, aY );

    // check for mouse entering of elements
    TInt viewableEleCnt = viewableElements.Count();
    for ( TInt i = 0; i < viewableEleCnt; i++ )
        {
        // If an element is in the view-list but NOT in the entered-list
        // then, it's copied to the entered-list
        // otherwise, ignore (still inside)
        if ( iSvgMouseEnteredElements.Find( viewableElements[i] ) 
             == KErrNotFound )
            {
            enteringElements.Append( viewableElements[i] );
            }
        else
            {
            stillInsideElements.Append( viewableElements[i] );
            }
        }

    // check for mouse exiting of elements
    RPointerArray<CSvgElementImpl> exitingElements;
    TInt svgMouseEnteredEleCnt = iSvgMouseEnteredElements.Count();
    for ( TInt i = 0; i < svgMouseEnteredEleCnt; i++ )
        {
        // If an element is in the entered-list but not the view-list
        // then, it's copied to the exiting list
        // otherwise, ignore (
        if ( viewableElements.Find( iSvgMouseEnteredElements[i] ) 
             == KErrNotFound )
            {
            exitingElements.Append( iSvgMouseEnteredElements[i] );
            }
        }

    // Remove exiting elements from entered list
    TInt exitingEleCnt = exitingElements.Count();
    for ( TInt i = 0; i < exitingEleCnt; i++ )
        {
        TInt index = iSvgMouseEnteredElements.Find( exitingElements[i] );
        if ( index != KErrNotFound )
            {
            iSvgMouseEnteredElements.Remove( index );
            }
        }

    // Add entering elements to entered-list
    TInt enteringEleCnt = enteringElements.Count();
    for ( TInt i = 0; i < enteringEleCnt; i++ )
        {
        iSvgMouseEnteredElements.Append( enteringElements[i] );
        }

    // Notify exiting
    if ( exitingElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMouseExited
                                                ( exitingElements, aX, aY );
        if ( iNewDocument )
            {
            iNewDocument->NotifyInternalMouseExited( exitingElements, aX, aY );
            }
        }

    // Notify entering
    if ( enteringElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMouseEntered
                                                ( enteringElements, aX, aY );
        if ( iNewDocument )
            {
            iNewDocument->NotifyInternalMouseEntered( enteringElements, aX, aY );
            }
        }

    // Notify moved
    if ( stillInsideElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMouseMoved
                                            ( stillInsideElements, aX, aY );
        if ( iNewDocument )
            {
            iNewDocument->NotifyInternalMouseMoved( stillInsideElements, aX, aY );
            }
        }

    exitingElements.Close();
    enteringElements.Close();
    stillInsideElements.Close();
    viewableElements.Close();
    
    
    return ETrue;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------    
TBool CSvgMediaAnimationElementImpl::MouseMoved( 
    RPointerArray<CSvgElementImpl>& /*aElements */,
                                TInt aX, TInt aY )
    {
    if( !iNewDocument ) 
        {
        return EFalse;
        }
        
    // Process for Mouse enter/exit
    TInt listenerCount = (((CSvgDocumentImpl*)iOwnerDocument)->Engine())
                                                   ->MouseListenerCount();

    if ( iNewDocument )
    {
        listenerCount += iNewDocument->MouseInternalListenerCount();
    }
    if ( listenerCount == 0 )
        {
        return EFalse;
        }
    // Get list of elements containing pointer (bounding-box)
    RPointerArray<CSvgElementImpl> viewableElements;
    RPointerArray<CSvgElementImpl> enteringElements;
    RPointerArray<CSvgElementImpl> stillInsideElements;
    (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->GetViewableElementsAtPoint
                                    (iNewDocument, viewableElements, aX, aY );

    // check for mouse entering of elements
    TInt viewableEleCnt = viewableElements.Count();
    for ( TInt i = 0; i < viewableEleCnt; i++ )
        {
        // If an element is in the view-list but NOT in the entered-list
        // then, it's copied to the entered-list
        // otherwise, ignore (still inside)
        if ( iSvgMouseEnteredElements.Find( viewableElements[i] ) 
             == KErrNotFound )
            {
            enteringElements.Append( viewableElements[i] );
            }
        else
            {
            stillInsideElements.Append( viewableElements[i] );
            }
        }

    // check for mouse exiting of elements
    RPointerArray<CSvgElementImpl> exitingElements;
    TInt svgMouseEnteredEleCnt = iSvgMouseEnteredElements.Count();
    for ( TInt i = 0; i < svgMouseEnteredEleCnt; i++ )
        {
        // If an element is in the entered-list but not the view-list
        // then, it's copied to the exiting list
        // otherwise, ignore (
        if ( viewableElements.Find( iSvgMouseEnteredElements[i] ) 
             == KErrNotFound )
            {
            exitingElements.Append( iSvgMouseEnteredElements[i] );
            }
        }

    // Remove exiting elements from entered list
    TInt exitingEleCnt = exitingElements.Count();
    for ( TInt i = 0; i < exitingEleCnt; i++ )
        {
        TInt index = iSvgMouseEnteredElements.Find( exitingElements[i] );
        if ( index != KErrNotFound )
            {
            iSvgMouseEnteredElements.Remove( index );
            }
        }

    // Add entering elements to entered-list
    TInt enteringEleCnt = enteringElements.Count();
    for ( TInt i = 0; i < enteringEleCnt; i++ )
        {
        iSvgMouseEnteredElements.Append( enteringElements[i] );
        }

    // Notify exiting
    if ( exitingElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMouseExited
                                                ( exitingElements, aX, aY );
        if ( iNewDocument )
            {
            iNewDocument->NotifyInternalMouseExited( exitingElements, aX, aY );
            }
        }

    // Notify entering
    if ( enteringElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMouseEntered
                                                ( enteringElements, aX, aY );
        if ( iNewDocument )
            {
            iNewDocument->NotifyInternalMouseEntered( enteringElements, aX, aY );
            }
        }

    // Notify moved
    if ( stillInsideElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMouseMoved
                                            ( stillInsideElements, aX, aY );
        if ( iNewDocument )
            {
            iNewDocument->NotifyInternalMouseMoved( stillInsideElements, aX, aY );
            }
        }

    exitingElements.Close();
    enteringElements.Close();
    stillInsideElements.Close();
    viewableElements.Close();
    

    return ETrue;
    }

// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
TBool CSvgMediaAnimationElementImpl::MousePressed( 
    RPointerArray<CSvgElementImpl>& /* aElements */,
    TInt aX, TInt aY )
    {
    
    if( !iNewDocument )
        {
        return EFalse;            
        }

        
     TInt listenerCount = (((CSvgDocumentImpl*)iOwnerDocument)->Engine())
                                                    ->MouseListenerCount();
        
      
    if (iNewDocument)
    {
        listenerCount += iNewDocument->MouseInternalListenerCount();
    }
    if ( listenerCount == 0 )
        {
           // return 0;
           return EFalse;
        }
    RPointerArray<CSvgElementImpl> viewableElements;
    // TInt topClickedElement = 0;

    (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->GetViewableElementsAtPoint
                                    (iNewDocument,viewableElements, aX, aY );
    if ( viewableElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMousePressed
                                                ( viewableElements, aX, aY );
        if ( iNewDocument)
            {
            iNewDocument->NotifyInternalMousePressed( viewableElements, aX, aY );
            }
        }
    viewableElements.Close();

    //return topClickedElement;
   
   
    return ETrue;
    }
    
TBool CSvgMediaAnimationElementImpl::MouseReleased( 
    RPointerArray<CSvgElementImpl>& /* aElements */,
    TInt aX, TInt aY )
    {
    // Process for MouseRelease
    if ( !iNewDocument )
        {
        return EFalse;    
        }
    
    TInt listenerCount = (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->
                                                        MouseListenerCount();

    if ( iNewDocument )
    {
        listenerCount += iNewDocument->MouseInternalListenerCount();
    }
    if ( listenerCount == 0 )
        {
        return ETrue;
        }
    RPointerArray<CSvgElementImpl> viewableElements;
    (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->GetViewableElementsAtPoint
                                    (iNewDocument, viewableElements, aX, aY );
    if ( viewableElements.Count() > 0 )
        {
        (((CSvgDocumentImpl*)iOwnerDocument)->Engine())->NotifyMouseReleased
                                                ( viewableElements, aX, aY );
        if ( iNewDocument )
            {
            iNewDocument->NotifyInternalMouseReleased( viewableElements, aX, aY );
            }
        }
    viewableElements.Close();
    return ETrue;
    }                
 
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
void CSvgMediaAnimationElementImpl::UpdateCTM()
    {
    if ( !iNewDocument )
    {
    return;
    }
        
    CSvgElementImpl::UpdateCTM();
    TGfxAffineTransform aTr = GetCTM();
          
    TGfxPoint2D ep( 1, 0 ), org( 2, 0 );
    aTr.Transform( &ep, & ep, 1 );
    aTr.Transform( &org, & org, 1 );
    ep.iX -= org.iX;
    ep.iY -= org.iY;
    iScale = TFloatFixPt::Sqrt( ep.iX * ep.iX + ep.iY * ep.iY );
   
    TGfxAffineTransform tMatrix;
    tMatrix = aTr;

    #ifdef SVG_FLOAT_BUILD
    tMatrix.Scale( ( TFloatFixPt( 1 ) / ( iScale ) ), ( TFloatFixPt( 1 ) / ( iScale ) ) );
    #else
    tMatrix.Scale( ( TFloatFixPt( 0x10000,ETrue ) / ( iScale ) ), ( TFloatFixPt( 0x10000,ETrue ) / ( iScale ) ) );
    #endif
    
    if ( !iIsOriginalRootTrSet )
    {
       MSvgTransformList* aTransformList;
       ((CSvgSvgElementImpl *)(iNewDocument->RootElement()))->GetTransform
                                                          (aTransformList);
        iOriginalRootTr = aTransformList->GetItem(0);
        iIsOriginalRootTrSet = ETrue;
    }
   
    iNewDocument->DocumentTransform(tMatrix);
    tMatrix.Concatenate(iOriginalRootTr);
   
    ((CSvgSvgElementImpl *)(iNewDocument->RootElement()))->SetTransformList
                                                            (tMatrix);
   
    TFloatFixPt  newWidth =        iScale * iWidth; 
    TFloatFixPt  newHeight =     iScale * iHeight; 
   

    ((CSvgSvgElementImpl *)(iNewDocument->RootElement()))->SetWidth(newWidth);
    ((CSvgSvgElementImpl *)(iNewDocument->RootElement()))->SetHeight(newHeight);
   
    ((CSvgElementImpl*)iNewDocument->RootElement())->UpdateCTM();
        
         
    }
    
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------    
void CSvgMediaAnimationElementImpl::DeactivateAnimation()
    {
        CSvgMediaElementBase::DeactivateAnimation(this);
    }
        
// End of file