/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#include <vos/timer.hxx>
#include <tools/debug.hxx>
#include <vcl/outdev.hxx>
#include <tools/poly.hxx>
#include "grfcache.hxx"
#include <rtl/crc.h>
#include <memory>

// -----------
// - Defines -
// -----------

#define RELEASE_TIMEOUT 10000
#define MAX_BMP_EXTENT	4096

// -----------
// - statics -
// -----------

static const char aHexData[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };

// -------------
// - GraphicID -
// -------------

class GraphicID
{
private:

	sal_uInt32	mnID1;
	sal_uInt32	mnID2;
	sal_uInt32	mnID3;
	sal_uInt32	mnID4;

				GraphicID();

public:


				GraphicID( const GraphicObject& rObj );
				~GraphicID() {}

	sal_Bool		operator==( const GraphicID& rID ) const
				{
					return( rID.mnID1 == mnID1 && rID.mnID2 == mnID2 &&
							rID.mnID3 == mnID3 && rID.mnID4 == mnID4 );
				}
    
	ByteString	GetIDString() const;
    sal_Bool        IsEmpty() const { return( 0 == mnID4 ); }
};

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

GraphicID::GraphicID( const GraphicObject& rObj )
{
	const Graphic& rGraphic = rObj.GetGraphic(); 

	mnID1 = ( (sal_uLong) rGraphic.GetType() ) << 28;

	switch( rGraphic.GetType() )
	{
		case( GRAPHIC_BITMAP ):
		{
            if(rGraphic.getSvgData().get())
            {
                const SvgDataPtr& rSvgDataPtr = rGraphic.getSvgData();
                const basegfx::B2DRange& rRange = rSvgDataPtr->getRange();
                
                mnID1 |= rSvgDataPtr->getSvgDataArrayLength();
                mnID2 = basegfx::fround(rRange.getWidth());
                mnID3 = basegfx::fround(rRange.getHeight());
                mnID4 = rtl_crc32(0, rSvgDataPtr->getSvgDataArray().get(), rSvgDataPtr->getSvgDataArrayLength());
            }
			else if( rGraphic.IsAnimated() )
			{
				const Animation aAnimation( rGraphic.GetAnimation() );

				mnID1 |= ( aAnimation.Count() & 0x0fffffff );
				mnID2 = aAnimation.GetDisplaySizePixel().Width();
				mnID3 = aAnimation.GetDisplaySizePixel().Height();
				mnID4 = rGraphic.GetChecksum();
			}
			else
			{
				const BitmapEx aBmpEx( rGraphic.GetBitmapEx() );

				mnID1 |= ( ( ( (sal_uLong) aBmpEx.GetTransparentType() << 8 ) | ( aBmpEx.IsAlpha() ? 1 : 0 ) ) & 0x0fffffff );
				mnID2 = aBmpEx.GetSizePixel().Width();
				mnID3 = aBmpEx.GetSizePixel().Height();
				mnID4 = rGraphic.GetChecksum();
			}
		}
		break;

		case( GRAPHIC_GDIMETAFILE ):
		{
			const GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() );

			mnID1 |= ( aMtf.GetActionCount() & 0x0fffffff );
			mnID2 = aMtf.GetPrefSize().Width();
			mnID3 = aMtf.GetPrefSize().Height();
			mnID4 = rGraphic.GetChecksum();
		}
		break;

		default:
			mnID2 = mnID3 = mnID4 = 0;
		break;
	}
}

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

ByteString GraphicID::GetIDString() const
{
	ByteString	aHexStr;
	sal_Char*	pStr = aHexStr.AllocBuffer( 32 );
	sal_Int32	nShift;

	for( nShift = 28; nShift >= 0; nShift -= 4 )
		*pStr++ = aHexData[ ( mnID1 >> (sal_uInt32) nShift ) & 0xf ];

	for( nShift = 28; nShift >= 0; nShift -= 4 )
		*pStr++ = aHexData[ ( mnID2 >> (sal_uInt32) nShift ) & 0xf ];

	for( nShift = 28; nShift >= 0; nShift -= 4 )
		*pStr++ = aHexData[ ( mnID3 >> (sal_uInt32) nShift ) & 0xf ];

	for( nShift = 28; nShift >= 0; nShift -= 4 )
		*pStr++ = aHexData[ ( mnID4 >> (sal_uInt32) nShift ) & 0xf ];

	return aHexStr;
}

// ---------------------
// - GraphicCacheEntry -
// ---------------------

class GraphicCacheEntry
{
private:
	
	List				maGraphicObjectList;
	GraphicID			maID;
	GfxLink				maGfxLink;
	BitmapEx*			mpBmpEx;
	GDIMetaFile*		mpMtf;
	Animation*			mpAnimation;
	sal_Bool			mbSwappedAll;

    // SvgData support
    SvgDataPtr          maSvgData;

    sal_Bool			ImplInit( const GraphicObject& rObj );
	sal_Bool			ImplMatches( const GraphicObject& rObj ) const { return( GraphicID( rObj ) == maID ); }
	void				ImplFillSubstitute( Graphic& rSubstitute );
						
public:					
						
						GraphicCacheEntry( const GraphicObject& rObj );
						~GraphicCacheEntry();

	const GraphicID&	GetID() const { return maID; }
						
	void				AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute );
	sal_Bool				ReleaseGraphicObjectReference( const GraphicObject& rObj );
	sal_uLong				GetGraphicObjectReferenceCount() { return maGraphicObjectList.Count(); }
	sal_Bool				HasGraphicObjectReference( const GraphicObject& rObj );
						
	void				TryToSwapIn();
	void				GraphicObjectWasSwappedOut( const GraphicObject& rObj );
	sal_Bool				FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute );
	void				GraphicObjectWasSwappedIn( const GraphicObject& rObj );
};

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

GraphicCacheEntry::GraphicCacheEntry( const GraphicObject& rObj ) :
	maID			( rObj ),
	mpBmpEx			( NULL ),
	mpMtf			( NULL ),
	mpAnimation		( NULL ),
	mbSwappedAll    ( true )
{
	mbSwappedAll = !ImplInit(rObj);
	maGraphicObjectList.Insert( (void*) &rObj, LIST_APPEND );
}

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

GraphicCacheEntry::~GraphicCacheEntry()
{
	DBG_ASSERT( !maGraphicObjectList.Count(), "GraphicCacheEntry::~GraphicCacheEntry(): Not all GraphicObjects are removed from this entry" );

	delete mpBmpEx;
	delete mpMtf;
	delete mpAnimation;
}

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

sal_Bool GraphicCacheEntry::ImplInit( const GraphicObject& rObj )
{
	sal_Bool bRet;

	if( !rObj.IsSwappedOut() )
	{
		const Graphic& rGraphic = rObj.GetGraphic();

		if( mpBmpEx )
			delete mpBmpEx, mpBmpEx = NULL;

		if( mpMtf )
			delete mpMtf, mpMtf = NULL;

		if( mpAnimation )
			delete mpAnimation, mpAnimation = NULL;

		switch( rGraphic.GetType() )
		{
			case( GRAPHIC_BITMAP ):
			{
                if(rGraphic.getSvgData().get())
                {
                    maSvgData = rGraphic.getSvgData();
                }
				else if( rGraphic.IsAnimated() )
                {
					mpAnimation = new Animation( rGraphic.GetAnimation() );
                }
				else
                {
					mpBmpEx = new BitmapEx( rGraphic.GetBitmapEx() );
                }
			}
			break;
					
			case( GRAPHIC_GDIMETAFILE ):
			{
				mpMtf = new GDIMetaFile( rGraphic.GetGDIMetaFile() );
			}
			break;

			default:
				DBG_ASSERT( GetID().IsEmpty(), "GraphicCacheEntry::ImplInit: Could not initialize graphic! (=>KA)" );
			break;
		}

		if( rGraphic.IsLink() )
			maGfxLink = ( (Graphic&) rGraphic ).GetLink();
		else
			maGfxLink = GfxLink();

		bRet = sal_True;
	}
	else
		bRet = sal_False;

	return bRet;
}

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

void GraphicCacheEntry::ImplFillSubstitute( Graphic& rSubstitute )
{
	// create substitute for graphic;
	const Size			aPrefSize( rSubstitute.GetPrefSize() );
	const MapMode		aPrefMapMode( rSubstitute.GetPrefMapMode() );
	const Link			aAnimationNotifyHdl( rSubstitute.GetAnimationNotifyHdl() );
	const String		aDocFileName( rSubstitute.GetDocFileName() );
	const sal_uLong			nDocFilePos = rSubstitute.GetDocFilePos();
	const GraphicType	eOldType = rSubstitute.GetType();
	const sal_Bool			bDefaultType = ( rSubstitute.GetType() == GRAPHIC_DEFAULT );

	if( rSubstitute.IsLink() && ( GFX_LINK_TYPE_NONE == maGfxLink.GetType() ) )
		maGfxLink = rSubstitute.GetLink();

    if(maSvgData.get())
    {
        rSubstitute = maSvgData;
    }
	else if( mpBmpEx )
    {
		rSubstitute = *mpBmpEx;
    }
	else if( mpAnimation )
    {
		rSubstitute = *mpAnimation;
    }
	else if( mpMtf )
    {
		rSubstitute = *mpMtf;
    }
	else
    {
		rSubstitute.Clear();
    }

	if( eOldType != GRAPHIC_NONE )
	{
    	rSubstitute.SetPrefSize( aPrefSize );
	    rSubstitute.SetPrefMapMode( aPrefMapMode );
		rSubstitute.SetAnimationNotifyHdl( aAnimationNotifyHdl );
		rSubstitute.SetDocFileName( aDocFileName, nDocFilePos );
	}

	if( GFX_LINK_TYPE_NONE != maGfxLink.GetType() )
    {
		rSubstitute.SetLink( maGfxLink );
    }

	if( bDefaultType )
    {
		rSubstitute.SetDefaultType();
    }
}

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

void GraphicCacheEntry::AddGraphicObjectReference( const GraphicObject& rObj, Graphic& rSubstitute )
{	
	if( mbSwappedAll )
		mbSwappedAll = !ImplInit( rObj );

	ImplFillSubstitute( rSubstitute );
	maGraphicObjectList.Insert( (void*) &rObj, LIST_APPEND );
}	

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

sal_Bool GraphicCacheEntry::ReleaseGraphicObjectReference( const GraphicObject& rObj )
{
	sal_Bool bRet = sal_False;

	for( void* pObj = maGraphicObjectList.First(); !bRet && pObj; pObj = maGraphicObjectList.Next() )
	{
		if( &rObj == (GraphicObject*) pObj )
		{
			maGraphicObjectList.Remove( pObj );
			bRet = sal_True;
		}
	}

	return bRet;
}

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

sal_Bool GraphicCacheEntry::HasGraphicObjectReference( const GraphicObject& rObj )
{
	sal_Bool bRet = sal_False;

	for( void* pObj = maGraphicObjectList.First(); !bRet && pObj; pObj = maGraphicObjectList.Next() )
		if( &rObj == (GraphicObject*) pObj )
			bRet = sal_True;

	return bRet;
}

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

void GraphicCacheEntry::TryToSwapIn()
{
	if( mbSwappedAll && maGraphicObjectList.Count() )
		( (GraphicObject*) maGraphicObjectList.First() )->FireSwapInRequest();
}

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

void GraphicCacheEntry::GraphicObjectWasSwappedOut( const GraphicObject& /*rObj*/ )
{
	mbSwappedAll = sal_True;

	for( void* pObj = maGraphicObjectList.First(); mbSwappedAll && pObj; pObj = maGraphicObjectList.Next() )
		if( !( (GraphicObject*) pObj )->IsSwappedOut() )
			mbSwappedAll = sal_False;

	if( mbSwappedAll )
	{
		delete mpBmpEx, mpBmpEx = NULL;
		delete mpMtf, mpMtf = NULL;
		delete mpAnimation, mpAnimation = NULL;

        // #119176# also reset SvgData
        maSvgData.reset();
	}
}

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

sal_Bool GraphicCacheEntry::FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
{
	sal_Bool bRet;

	if( !mbSwappedAll && rObj.IsSwappedOut() )
	{
		ImplFillSubstitute( rSubstitute );
		bRet = sal_True;
	}
	else
		bRet = sal_False;

	return bRet;
}

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

void GraphicCacheEntry::GraphicObjectWasSwappedIn( const GraphicObject& rObj )
{
	if( mbSwappedAll )
		mbSwappedAll = !ImplInit( rObj );
}

// ----------------------------
// - GraphicDisplayCacheEntry -
// ----------------------------

class GraphicDisplayCacheEntry
{
private:

	::vos::TTimeValue           maReleaseTime;
    const GraphicCacheEntry*	mpRefCacheEntry;
	GDIMetaFile*				mpMtf;
	BitmapEx*					mpBmpEx;
	GraphicAttr					maAttr;
	Size						maOutSizePix;
	sal_uLong						mnCacheSize;
    sal_uLong						mnOutDevDrawMode;
    sal_uInt16						mnOutDevBitCount;

public:						
							
	static sal_uLong				GetNeededSize( OutputDevice* pOut, const Point& rPt, const Size& rSz, 
											   const GraphicObject& rObj, const GraphicAttr& rAttr );
							
public:						
							
								GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry,
														  OutputDevice* pOut, const Point& rPt, const Size& rSz, 
														  const GraphicObject& rObj, const GraphicAttr& rAttr,
														  const BitmapEx& rBmpEx ) :
									mpRefCacheEntry( pRefCacheEntry ),
									mpMtf( NULL ), mpBmpEx( new BitmapEx( rBmpEx ) ),
									maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ),
									mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ),
                                    mnOutDevDrawMode( pOut->GetDrawMode() ),
                                    mnOutDevBitCount( pOut->GetBitCount() )
                                    {
                                    }
								
								GraphicDisplayCacheEntry( const GraphicCacheEntry* pRefCacheEntry,
														  OutputDevice* pOut, const Point& rPt, const Size& rSz, 
														  const GraphicObject& rObj, const GraphicAttr& rAttr,
														  const GDIMetaFile& rMtf ) :
									mpRefCacheEntry( pRefCacheEntry ),
									mpMtf( new GDIMetaFile( rMtf ) ), mpBmpEx( NULL ),
									maAttr( rAttr ), maOutSizePix( pOut->LogicToPixel( rSz ) ),
									mnCacheSize( GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) ),
                                    mnOutDevDrawMode( pOut->GetDrawMode() ),
                                    mnOutDevBitCount( pOut->GetBitCount() ) 
                                    {
                                    }	
                                    	
								
								~GraphicDisplayCacheEntry();

	const GraphicAttr&			GetAttr() const { return maAttr; }
	const Size&					GetOutputSizePixel() const { return maOutSizePix; }
	sal_uLong					GetCacheSize() const { return mnCacheSize; }
	const GraphicCacheEntry*	GetReferencedCacheEntry() const { return mpRefCacheEntry; }
    sal_uLong					GetOutDevDrawMode() const { return mnOutDevDrawMode; }
    sal_uInt16				GetOutDevBitCount()	const { return mnOutDevBitCount; }
    
    void                        SetReleaseTime( const ::vos::TTimeValue& rReleaseTime ) { maReleaseTime = rReleaseTime; }
    const ::vos::TTimeValue&    GetReleaseTime() const { return maReleaseTime; }
								
	sal_Bool						Matches( OutputDevice* pOut, const Point& /*rPtPixel*/, const Size& rSzPixel,
										 const GraphicCacheEntry* pCacheEntry, const GraphicAttr& rAttr ) const
								{
                                    // #i46805# Additional match
                                    // criteria: outdev draw mode and
                                    // bit count. One cannot reuse
                                    // this cache object, if it's
                                    // e.g. generated for
                                    // DRAWMODE_GRAYBITMAP.
									return( ( pCacheEntry == mpRefCacheEntry ) &&
											( maAttr == rAttr ) &&
											( ( maOutSizePix == rSzPixel ) || ( !maOutSizePix.Width() && !maOutSizePix.Height() ) ) &&
                                            ( pOut->GetBitCount() == mnOutDevBitCount ) &&
                                            ( pOut->GetDrawMode() == mnOutDevDrawMode ) );
								}
								
	void						Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const;
};

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

sal_uLong GraphicDisplayCacheEntry::GetNeededSize( OutputDevice* pOut, const Point& /*rPt*/, const Size& rSz, 
											   const GraphicObject& rObj, const GraphicAttr& rAttr )
{
    const Graphic&      rGraphic = rObj.GetGraphic();
    const GraphicType	eType = rGraphic.GetType();
	sal_uLong				nNeededSize;

	if( GRAPHIC_BITMAP == eType )
	{
		const Size aOutSizePix( pOut->LogicToPixel( rSz ) );
		const long nBitCount = pOut->GetBitCount();

		if( ( aOutSizePix.Width() > MAX_BMP_EXTENT ) || 
            ( aOutSizePix.Height() > MAX_BMP_EXTENT ) )
        {
		    nNeededSize = ULONG_MAX;
        }
		else if( nBitCount )
		{
		    nNeededSize = aOutSizePix.Width() * aOutSizePix.Height() * nBitCount / 8;

    		if( rObj.IsTransparent() || ( rAttr.GetRotation() % 3600 ) )
	    		nNeededSize += nNeededSize / nBitCount;
		}
		else
	    {
     		DBG_ERROR( "GraphicDisplayCacheEntry::GetNeededSize(): pOut->GetBitCount() == 0" );
		    nNeededSize = 256000;
        }
	}
	else if( GRAPHIC_GDIMETAFILE == eType )
		nNeededSize = rGraphic.GetSizeBytes();
	else
		nNeededSize = 0;

	return nNeededSize;
}

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

GraphicDisplayCacheEntry::~GraphicDisplayCacheEntry()
{
	if( mpMtf )
		delete mpMtf;

	if( mpBmpEx )
		delete mpBmpEx;
}

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

void GraphicDisplayCacheEntry::Draw( OutputDevice* pOut, const Point& rPt, const Size& rSz ) const
{
	if( mpMtf )
		GraphicManager::ImplDraw( pOut, rPt, rSz, *mpMtf, maAttr );
	else if( mpBmpEx )
	{
		if( maAttr.IsRotated() )
		{
			Polygon aPoly( Rectangle( rPt, rSz ) );
			
			aPoly.Rotate( rPt, maAttr.GetRotation() % 3600 );
			const Rectangle aRotBoundRect( aPoly.GetBoundRect() );
			pOut->DrawBitmapEx( aRotBoundRect.TopLeft(), aRotBoundRect.GetSize(), *mpBmpEx );
		}
		else
			pOut->DrawBitmapEx( rPt, rSz, *mpBmpEx );
	}
}

// -----------------------
// - GraphicCache -
// -----------------------

GraphicCache::GraphicCache( GraphicManager& rMgr, sal_uLong nDisplayCacheSize, sal_uLong nMaxObjDisplayCacheSize ) :
	mrMgr				    ( rMgr ),
    mnReleaseTimeoutSeconds ( 0UL ),
	mnMaxDisplaySize	    ( nDisplayCacheSize ),
	mnMaxObjDisplaySize	    ( nMaxObjDisplayCacheSize ),
	mnUsedDisplaySize	    ( 0UL )
{
    maReleaseTimer.SetTimeoutHdl( LINK( this, GraphicCache, ReleaseTimeoutHdl ) );
    maReleaseTimer.SetTimeout( RELEASE_TIMEOUT );
    maReleaseTimer.Start();
}

// -----------------------------------------------------------------------------
										   
GraphicCache::~GraphicCache()
{
	DBG_ASSERT( !maGraphicCache.Count(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in cache" );
	DBG_ASSERT( !maDisplayCache.Count(), "GraphicCache::~GraphicCache(): there are some GraphicObjects in display cache" );
}

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

void GraphicCache::AddGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute, 
                                     const ByteString* pID, const GraphicObject* pCopyObj )
{
	sal_Bool bInserted = sal_False;

	if( !rObj.IsSwappedOut() && 
        ( pID || ( pCopyObj && ( pCopyObj->GetType() != GRAPHIC_NONE ) ) || ( rObj.GetType() != GRAPHIC_NONE ) ) )
	{
        if( pCopyObj )
        {
            GraphicCacheEntry* pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.First() );
        
            while( !bInserted && pEntry )
            {
                if( pEntry->HasGraphicObjectReference( *pCopyObj ) )
                {
                    pEntry->AddGraphicObjectReference( rObj, rSubstitute );
                    bInserted = sal_True;
                }
                else
                {
                    pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.Next() );
                }
            }
        }
        
        if( !bInserted )
        {
            GraphicCacheEntry* pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.First() );
            ::std::auto_ptr< GraphicID > apID;
            
            if( !pID )
            {
                apID.reset( new GraphicID( rObj ) );
            }
    
            while( !bInserted && pEntry )
            {
                const GraphicID& rEntryID = pEntry->GetID();
    
                if( pID )
                {
                    if( rEntryID.GetIDString() == *pID )
                    {
                        pEntry->TryToSwapIn();
    
                        // since pEntry->TryToSwapIn can modify our current list, we have to
                        // iterate from beginning to add a reference to the appropriate
                        // CacheEntry object; after this, quickly jump out of the outer iteration
                        for( pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.First() ); 
                             !bInserted && pEntry; 
                             pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.Next() ) )
                        {
                            const GraphicID& rID = pEntry->GetID();
    
                            if( rID.GetIDString() == *pID )
                            {
                                pEntry->AddGraphicObjectReference( rObj, rSubstitute );
                                bInserted = sal_True;
                            }
                        }
    
                        if( !bInserted )
                        {
                            maGraphicCache.Insert( new GraphicCacheEntry( rObj ), LIST_APPEND );
                            bInserted = sal_True;
                        }
                    }
                }
                else
                {
                    if( rEntryID == *apID )
                    {
                        pEntry->AddGraphicObjectReference( rObj, rSubstitute );
                        bInserted = sal_True;
                    }
                }
    
                if( !bInserted )
                    pEntry = static_cast< GraphicCacheEntry* >( maGraphicCache.Next() );
            }
        }
	}

	if( !bInserted )
		maGraphicCache.Insert( new GraphicCacheEntry( rObj ), LIST_APPEND );
}

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

void GraphicCache::ReleaseGraphicObject( const GraphicObject& rObj )
{
	// Release cached object
	GraphicCacheEntry*	pEntry = (GraphicCacheEntry*) maGraphicCache.First();
	sal_Bool				bRemoved = sal_False;

	while( !bRemoved && pEntry )
	{
		bRemoved = pEntry->ReleaseGraphicObjectReference( rObj );

		if( bRemoved )
		{
			if( 0 == pEntry->GetGraphicObjectReferenceCount() )
			{
				// if graphic cache entry has no more references,
				// the corresponding display cache object can be removed
				GraphicDisplayCacheEntry* pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First();

				while( pDisplayEntry )
				{
					if( pDisplayEntry->GetReferencedCacheEntry() == pEntry )
					{
						mnUsedDisplaySize -= pDisplayEntry->GetCacheSize();
						maDisplayCache.Remove( pDisplayEntry );
						delete pDisplayEntry;
						pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject();
					}
					else
						pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
				}

				// delete graphic cache entry
				maGraphicCache.Remove( (void*) pEntry );
				delete pEntry;
			}
		}
		else
			pEntry = (GraphicCacheEntry*) maGraphicCache.Next();
	}

	DBG_ASSERT( bRemoved, "GraphicCache::ReleaseGraphicObject(...): GraphicObject not found in cache" );
}

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

void GraphicCache::GraphicObjectWasSwappedOut( const GraphicObject& rObj )
{
    // notify cache that rObj is swapped out (and can thus be pruned
    // from the cache)
	GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );

    if( pEntry )
        pEntry->GraphicObjectWasSwappedOut( rObj );
}

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

sal_Bool GraphicCache::FillSwappedGraphicObject( const GraphicObject& rObj, Graphic& rSubstitute )
{
	GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );

    if( !pEntry )
        return sal_False;

	return pEntry->FillSwappedGraphicObject( rObj, rSubstitute );
}

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

void GraphicCache::GraphicObjectWasSwappedIn( const GraphicObject& rObj )
{
	GraphicCacheEntry* pEntry = ImplGetCacheEntry( rObj );

    if( pEntry )
    {
	    if( pEntry->GetID().IsEmpty() )
	    {
		    ReleaseGraphicObject( rObj );
		    AddGraphicObject( rObj, (Graphic&) rObj.GetGraphic(), NULL, NULL ); 
	    }
	    else
		    pEntry->GraphicObjectWasSwappedIn( rObj );
    }
}

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

void GraphicCache::SetMaxDisplayCacheSize( sal_uLong nNewCacheSize )
{
	mnMaxDisplaySize = nNewCacheSize;

	if( GetMaxDisplayCacheSize() < GetUsedDisplayCacheSize() )
		ImplFreeDisplayCacheSpace( GetUsedDisplayCacheSize() - GetMaxDisplayCacheSize() );
}

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

void GraphicCache::SetMaxObjDisplayCacheSize( sal_uLong nNewMaxObjSize, sal_Bool bDestroyGreaterCached )
{
	const sal_Bool bDestroy = ( bDestroyGreaterCached && ( nNewMaxObjSize < mnMaxObjDisplaySize ) );

	mnMaxObjDisplaySize = Min( nNewMaxObjSize, mnMaxDisplaySize );

	if( bDestroy )
	{
		GraphicDisplayCacheEntry* pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.First();

		while( pCacheObj )
		{
			if( pCacheObj->GetCacheSize() > mnMaxObjDisplaySize )
			{
				mnUsedDisplaySize -= pCacheObj->GetCacheSize();
				maDisplayCache.Remove( pCacheObj );
				delete pCacheObj;
				pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject();
			}
			else
				pCacheObj = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
		}
	}
}

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

void GraphicCache::SetCacheTimeout( sal_uLong nTimeoutSeconds )
{
    if( mnReleaseTimeoutSeconds != nTimeoutSeconds )
    {
        GraphicDisplayCacheEntry*   pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First();
        ::vos::TTimeValue           aReleaseTime;

        if( ( mnReleaseTimeoutSeconds = nTimeoutSeconds ) != 0 )
        {
            osl_getSystemTime( &aReleaseTime );
            aReleaseTime.addTime( ::vos::TTimeValue( nTimeoutSeconds, 0 ) );
        }

	    while( pDisplayEntry )
	    {
            pDisplayEntry->SetReleaseTime( aReleaseTime );
		    pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
	    }
    }
}

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

void GraphicCache::ClearDisplayCache()
{
	for( void* pObj = maDisplayCache.First(); pObj; pObj = maDisplayCache.Next() )
		delete (GraphicDisplayCacheEntry*) pObj;

	maDisplayCache.Clear();
	mnUsedDisplaySize = 0UL;
}

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

sal_Bool GraphicCache::IsDisplayCacheable( OutputDevice* pOut, const Point& rPt, const Size& rSz, 
									   const GraphicObject& rObj, const GraphicAttr& rAttr ) const
{
	return( GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr ) <= 
			GetMaxObjDisplayCacheSize() );
}

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

sal_Bool GraphicCache::IsInDisplayCache( OutputDevice* pOut, const Point& rPt, const Size& rSz, 
									 const GraphicObject& rObj, const GraphicAttr& rAttr ) const
{
	const Point					aPtPixel( pOut->LogicToPixel( rPt ) );
	const Size					aSzPixel( pOut->LogicToPixel( rSz ) );
	const GraphicCacheEntry*	pCacheEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj );
	//GraphicDisplayCacheEntry*	pDisplayEntry = (GraphicDisplayCacheEntry*) ( (GraphicCache*) this )->maDisplayCache.First(); // -Wall removed ....
	sal_Bool						bFound = sal_False;

    if( pCacheEntry )
    {
        for( long i = 0, nCount = maDisplayCache.Count(); !bFound && ( i < nCount ); i++ )
            if( ( (GraphicDisplayCacheEntry*) maDisplayCache.GetObject( i ) )->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) )
                bFound = sal_True;
    }

	return bFound;
}

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

ByteString GraphicCache::GetUniqueID( const GraphicObject& rObj ) const
{
	ByteString			aRet;
	GraphicCacheEntry*	pEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj );

	// ensure that the entry is correctly initialized (it has to be read at least once)
	if( pEntry && pEntry->GetID().IsEmpty() )
		pEntry->TryToSwapIn();

	// do another call to ImplGetCacheEntry in case of modified entry list
	pEntry = ( (GraphicCache*) this )->ImplGetCacheEntry( rObj );

	if( pEntry )
		aRet = pEntry->GetID().GetIDString();
	
	return aRet;
}

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

sal_Bool GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz, 
										  const GraphicObject& rObj, const GraphicAttr& rAttr,
										  const BitmapEx& rBmpEx )
{
	const sal_uLong nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr );
	sal_Bool		bRet = sal_False;

	if( nNeededSize <= GetMaxObjDisplayCacheSize() )
	{
		if( nNeededSize > GetFreeDisplayCacheSize() )
			ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() );

		GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ), 
																			pOut, rPt, rSz, rObj, rAttr, rBmpEx );

        if( GetCacheTimeout() )
        {
            ::vos::TTimeValue aReleaseTime;

            osl_getSystemTime( &aReleaseTime );
            aReleaseTime.addTime( ::vos::TTimeValue( GetCacheTimeout(), 0 ) );
            pNewEntry->SetReleaseTime( aReleaseTime );
        }
																			
		maDisplayCache.Insert( pNewEntry, LIST_APPEND );
		mnUsedDisplaySize += pNewEntry->GetCacheSize();
		bRet = sal_True;
	}

	return bRet;
}

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

sal_Bool GraphicCache::CreateDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz, 
										  const GraphicObject& rObj, const GraphicAttr& rAttr,
										  const GDIMetaFile& rMtf )
{
	const sal_uLong nNeededSize = GraphicDisplayCacheEntry::GetNeededSize( pOut, rPt, rSz, rObj, rAttr );
	sal_Bool		bRet = sal_False;

	if( nNeededSize <= GetMaxObjDisplayCacheSize() )
	{
		if( nNeededSize > GetFreeDisplayCacheSize() )
			ImplFreeDisplayCacheSpace( nNeededSize - GetFreeDisplayCacheSize() );

		GraphicDisplayCacheEntry* pNewEntry = new GraphicDisplayCacheEntry( ImplGetCacheEntry( rObj ), 
																			pOut, rPt, rSz, rObj, rAttr, rMtf );

        if( GetCacheTimeout() )
        {
            ::vos::TTimeValue aReleaseTime;

            osl_getSystemTime( &aReleaseTime );
            aReleaseTime.addTime( ::vos::TTimeValue( GetCacheTimeout(), 0 ) );
            pNewEntry->SetReleaseTime( aReleaseTime );
        }
																			
		maDisplayCache.Insert( pNewEntry, LIST_APPEND );
		mnUsedDisplaySize += pNewEntry->GetCacheSize();
		bRet = sal_True;
	}

	return bRet;
}

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

sal_Bool GraphicCache::DrawDisplayCacheObj( OutputDevice* pOut, const Point& rPt, const Size& rSz, 
										const GraphicObject& rObj, const GraphicAttr& rAttr )
{
	const Point					aPtPixel( pOut->LogicToPixel( rPt ) );
	const Size					aSzPixel( pOut->LogicToPixel( rSz ) );
	const GraphicCacheEntry*	pCacheEntry = ImplGetCacheEntry( rObj );
	GraphicDisplayCacheEntry*	pDisplayCacheEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First();
	sal_Bool						bRet = sal_False;

	while( !bRet && pDisplayCacheEntry )
	{
		if( pDisplayCacheEntry->Matches( pOut, aPtPixel, aSzPixel, pCacheEntry, rAttr ) )
		{
            ::vos::TTimeValue aReleaseTime;

			// put found object at last used position
			maDisplayCache.Insert( maDisplayCache.Remove( pDisplayCacheEntry ), LIST_APPEND );

            if( GetCacheTimeout() )
            {
                osl_getSystemTime( &aReleaseTime );
                aReleaseTime.addTime( ::vos::TTimeValue( GetCacheTimeout(), 0 ) );
            }

            pDisplayCacheEntry->SetReleaseTime( aReleaseTime );
			bRet = sal_True;
		}
		else
			pDisplayCacheEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
	}

	if( bRet )
		pDisplayCacheEntry->Draw( pOut, rPt, rSz );

	return bRet;
}

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

sal_Bool GraphicCache::ImplFreeDisplayCacheSpace( sal_uLong nSizeToFree )
{
	sal_uLong nFreedSize = 0UL;

	if( nSizeToFree )
	{
		void* pObj = maDisplayCache.First();

        if( nSizeToFree > mnUsedDisplaySize )
            nSizeToFree = mnUsedDisplaySize;

		while( pObj )
		{
			GraphicDisplayCacheEntry* pCacheObj = (GraphicDisplayCacheEntry*) pObj;

			nFreedSize += pCacheObj->GetCacheSize();
			mnUsedDisplaySize -= pCacheObj->GetCacheSize();
			maDisplayCache.Remove( pObj );
			delete pCacheObj;

			if( nFreedSize >= nSizeToFree )
				break;
			else
				pObj = maDisplayCache.GetCurObject();
		}
	}

	return( nFreedSize >= nSizeToFree );
}

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

GraphicCacheEntry* GraphicCache::ImplGetCacheEntry( const GraphicObject& rObj )
{
	GraphicCacheEntry* pRet = NULL;

	for( void* pObj = maGraphicCache.First(); !pRet && pObj; pObj = maGraphicCache.Next() )
		if( ( (GraphicCacheEntry*) pObj )->HasGraphicObjectReference( rObj ) )
			pRet = (GraphicCacheEntry*) pObj;

	return pRet;
}

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

IMPL_LINK( GraphicCache, ReleaseTimeoutHdl, Timer*, pTimer )
{
    pTimer->Stop();

    ::vos::TTimeValue           aCurTime;
	GraphicDisplayCacheEntry*   pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.First();

    osl_getSystemTime( &aCurTime );

	while( pDisplayEntry )
	{
        const ::vos::TTimeValue& rReleaseTime = pDisplayEntry->GetReleaseTime();

		if( !rReleaseTime.isEmpty() && ( rReleaseTime < aCurTime ) )
		{
			mnUsedDisplaySize -= pDisplayEntry->GetCacheSize();
			maDisplayCache.Remove( pDisplayEntry );
			delete pDisplayEntry;
			pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.GetCurObject();
		}
		else
			pDisplayEntry = (GraphicDisplayCacheEntry*) maDisplayCache.Next();
	}

    pTimer->Start();

    return 0;
}
