/*
* Copyright (c) 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:   Loads textures.
*
*/



#ifndef C_ALFTEXTUREMANAGER_H
#define C_ALFTEXTUREMANAGER_H

#include <e32base.h>
#include <e32cmn.h>
#include <alf/alftexture.h>


/* Forward declarations */
class CAlfEnv;
class CAlfTextureProcessor;
class CAlfTextureManager;
class MAlfBitmapProvider;
struct TLoadQueueEntry;
struct TTextureEntry;

/**
 * Special texture id, can be used to let CAlfTextureManager to assign
 * ids for textures when those are created or loaded.
 * 
 * @see CAlfTextureManager
 */
const TInt KAlfAutoGeneratedTextureId = 0;

/**
 * Texture release level. 
 *
 * @see Release(), RestoreL()
 * @see CAlfTexture::SetPriority()
 */
enum TAlfTexturePriority
    {
    /** Texture is released only on destruction */
    EAlfTexturePriorityHighest = 0,
    
    /** Texture is released on the background only if memory is running out */ 
    EAlfTexturePriorityHigh = 1000,
    
    /** Texture is released when application goes into background */ 
    EAlfTexturePriorityNormal= 2000, // = default
    
    /** Texture is released on the foreground if memory is running out */
    EAlfTexturePriorityLow= 3000
    };

/**
 * Provides callback methods for getting notifications when texture manager
 * finishes asynchronous texture loads. An observer of a CAlfTextureManager.
 *
 * The class willing to receive these events must implement the methods
 * of this interface, and then register itself to the obsevers list of
 * the texture manager.
 *
 * @see CAlfTextureManager
 */
class MAlfTextureLoadingCompletedObserver
    {
public:
    /**
     * Called to notify the observer that loading of a texture has
     * been completed.
     * @param aTexture Reference to the texture that has been loaded.
     * @param aTextureId Id of the texture in the texture manager. Can be used
     * to identify the loaded texture, provided that an id was assigned to the
     * texture.
     * @param aErrorCode KErrNone if the load was successful, otherwise one of
     * the system-wide error codes indicating reason why the texture loading
     * failed.
     * @note One should not commence loading of a new texture in this callback method.
     */
    virtual void TextureLoadingCompleted(CAlfTexture& aTexture,
                                         TInt aTextureId,
                                         TInt aErrorCode) = 0;

    };

/**
 * Provides callback methods for getting notifications of texture manager state
 * changes. An observer of a CAlfTextureManager.
 *
 * @see CAlfTextureManager
 */
class MAlfTextureManagerStateChangedObserver
    {
public:
    /**
     * Called to notify the observer that the state of the texture manager
     * has changed. This is called when the state changes between Idle and
     * Loading.
     *
     * @param aManager  Texture manager.
     */
    virtual void TextureManagerStateChanged(const CAlfTextureManager& aManager) = 0;

    };



/**
 * Provides callback methods for getting notifications when texture manager
 * notices a texture which preferrred size is changed.
 *
 * The class willing to receive these events must implement the methods
 * of this interface, and then register itself to the obsevers list of
 * the texture manager.
 *
 */
class MAlfTextureAutoSizeObserver
    {
public:
    /**
     * Called to notify the observer that the preferred size of some texture
     * has been changed.
     *
     * @param aChangedTexture  Texture which preferred size has changed.
     * @param aPreferredSize preferred size for texture.
     * @return ETrue if observer accepts new size, EFalse if it does not accept or 
     * doesn't care. 
     */
    virtual TBool PreferredSizeChanged(const CAlfTexture& aChangedTexture, TSize aPreferredSize) = 0;
    };


/**
 * CAlfTextureManager is responsible for managing the texture objects used by
 * the application. It provides asynchronous loading of image data into
 * CAlfTexture instances. The texture manager also manages font textures,
 * which can be used for compositing text in text meshes.
 *
 * The texture manager makes sure that only one copy of each image is loaded
 * at a time, so even if the application requests the same image several times
 * it is only loaded once. Textures are identified either by an integer ID or
 * by their file name.
 *
 * CAlfTextureManager is owned by CAlfEnv, and should be accessed via a
 * CAlfEnv instance. You should never construct your own texturemanagers.
 * 
 * Usage:
 * @code
 * 
 *  //Get TextureManager
 * CAlfTextureManager* textureMgr =  &iEnv->TextureManager();
 * 
 * //Set texturemanager image path
 * textureMgr->setImagePath(_L( "C:\\data\\Images\\Pictures\\" ) );
 * 
 * //Load texture
 * CAlfTexture* texture = textureMgr->LoadTextureL( _L("1.bmp"), EAlfTextureFlagDefault, 10 );
 * 
 * //Unload texture. Here, texture instance itself is not destroyed, only its 
 * //contents are emptied.
 * textureMgr->UnloadTexture(10);
 * 
 *  //Update texturecontent without changing the texture istance
 *  textureMgr->updateTextureFromFile( 10, _L( "2.jpg" ) );
 * 
 *  //Create texture 
 *  //BitmapProviderTest - implements MalfBitMapProvider interface
 *  //Default implementation of this interface, provided by toolkit is
 *  //CAlfImageLoaderUtil
 *  BitmapProviderTest* callback = new (ELeave) BitmapProviderTest();
 *  textureMgr->CreateTextureL( 42, *callback, EAlfTextureFlagDefault );
 * 
 *  @endcode
 *  @lib alfclient.lib
 *  @since S60 v3.2
 */
NONSHARABLE_CLASS( CAlfTextureManager ): public CActive
    {
public:

    /**
     * States of a CAlfTextureManager object.
     */
    enum TState
        {
        /** Indicates that the manager is in idle state. A new bitmap loading
            operation can be started. */
        EIdle,

        /** Indicates that the manager is loading a bitmap. */
        ELoading
        };

    /* Constructors and destructor. */

    /**
     * Static factory method. Creates a texture appropriate for the current
     * renderer.
     */
    static CAlfTextureManager* NewL(CAlfEnv& aEnv, TUid aUid);

    /**
     * Static factory method. Creates a texture appropriate for the current
     * renderer.
     */
    static CAlfTextureManager* NewLC(CAlfEnv& aEnv, TUid aUid);

    /**
     * Destructor.
     */
    virtual ~CAlfTextureManager();


    /* Methods. */

    /** @beginAPI */

    /**
     * Determines the environment the manager belongs to.
     */
	IMPORT_C CAlfEnv& Env();

    /**
     * Retuns a texture having given id. Will return a default blank
     * texture if the id was not found.
     */
    IMPORT_C const CAlfTexture* Texture(TInt aId) const;

    /**
     * Returns a texture associated with the given id.
     * Will leave if no associated texture exists. 
     *
     * @param aId Id of the retrieved texture.
     * @return Pointer to the texture. If the method leaves the return value is undefined.
     * @leave KErrNotFound If a texture with the given id does not exist.
     */
    IMPORT_C CAlfTexture* TextureL(TInt aId);
 
    /**
     * Sets the path where bitmaps are loaded from. If drive is not included, tries to resolver that 
     * using CCoeEnv
     *
     * @param aPath  Path for bitmap files.
     * @see LoadTexture() Call to load textures from this location.
     */
    IMPORT_C void SetImagePathL(const TDesC& aPath);

    /**
     * Returns the current image path.
     * @see LoadTexture() Call to load textures from this location.
     */
    IMPORT_C const TDesC& ImagePath() const;

    /**
     * Returns the blank texture. This can be used as a dummy texture if
     * no real texture is available.
     */
    IMPORT_C const CAlfTexture& BlankTexture() const;

    /**
     * Returns the blank texture. This can be used as a dummy texture if
     * no real texture is available. Will generate the blank texture
     * if the texture is not yet available.
     */
    IMPORT_C CAlfTexture& BlankTexture();

    /**
     * Loads an image and makes it a texture. The bitmap files are searched in
     * the path specified with SetImagePathL. The format of the loaded image
     * must be supported by the system (Series 60) codecs.
     *
     * LoadTextureL is an asynchronous method, which returns an empty texture
     * which is loaded and filled in the background. Register an
     * MAlfTextureLoadingCompletedObserver instance to the iLoadedObservers
     * array, whose TextureLoadingCompleted() method will be called when
     * textures finish loading. The same observer is also called if an error
     * occurs during the loading process. The other method is to check if an
     * image has been loaded with TextureManagers IsLoaded().
     *
     * If a texture with the given id or filename is already loaded the previously
     * loaded texture is returned. If texture with the given id has been unloaded
     * with UnloadTexture() method then the id is reused by loading a new texture
     * on the id.
     *
     * @param aImageFileName    Name of the image bitmap file to load. Relative
     *                          to the image load path. If empty filename is
     *                          used, will check if a filename for the id has
     *                          been defined and load a texture using that resource
     *                          location, if possible.
     * @param aFlags            Specify flags for the texture loading and
     *                          uploading - how to convert the bitmap to
     *                          texture.
     * @param aId               Id for the texture. Must be unique.
     *                          KAlfAutoGeneratedTextureId can be used to let 
     *                          texture manager automatically decide id.
     *
     * @note                    If both image name and id are left undefined
     *                          ("" and zero), will return a blank texture.
     *
     * @return                  Reference to the texture.
     *
     * @see SetImagePathL() To set the image search path. Set to "" to use
     * absolute image filenames.
     * @see iLoadObservers
     * @see MAlfTextureLoadingCompletedObserver::TextureLoadingCompleted()
     * @see IsLoaded()
     */
    IMPORT_C CAlfTexture& LoadTextureL(const TDesC& aImageFileName,
                                       TAlfTextureFlags aFlags,
                                       TInt aId);

   /**
     * Loads an image based on pre-registered id and file name.
     *
     * @see DefineFileName()
     *
     * LoadTextureL is an asynchronous method, which returns an empty texture
     * which is loaded and filled in the background. Register an
     * MAlfTextureLoadingCompletedObserver instance to the iLoadedObservers
     * array, whose TextureLoadingCompleted() method will be called when
     * textures finish loading. The same observer is also called if an error
     * occurs during the loading process. The other method is to check if an
     * image has been loaded with TextureManagers IsLoaded().
     *
     * If a texture with the given id or filename is already loaded the previously
     * loaded texture is returned. If texture with the given id has been unloaded
     * with UnloadTexture() method then the id is reused by loading a new texture
     * on the id.
     *
     * @param aId             The id of the texture/filename to load. The id must
     *                        have a filename assigned by a call to DefineFileName().
     *                        
     * @param aTextureMaxSize Can be used to define a maximum dimensions for
     *                        the final texture. The image data loaded will be
     *                        scaled (down) and fitted to these dimensions. Use
     *                        zero or below-zero values if size does not matter.
     *                        If the texture size is larger than the texture size
     *                        supported by the GL, the texture will be split to
     *                        multiple segments.
     * @param aFlags          Specify upload behavior - how to convert the bitmap
     *                        to texture and other load/upload behavior.
     *
     * @return                Reference to the texture.
     *
     * @see SetImagePathL()   To set the image search path. Set to "" to use
     *                        absolute image filenames.
     * @see iLoadObservers
     * @see MAlfTextureLoadingCompletedObserver::TextureLoadingCompleted()
     * @see IsLoaded()
     */
    IMPORT_C CAlfTexture& LoadTextureL(const TInt aId,
                                       TSize aTextureMaxSize = TSize(0,0),
                                       TAlfTextureFlags aFlags = EAlfTextureFlagDefault);

    /**
     * Loads an image and makes it a texture. The bitmap files are searched in
     * the path specified with SetImagePathL. The format of the loaded image
     * must be supported by the system (Series 60) codecs.
     *
     * LoadTextureL is an asynchronous method, which returns an empty texture
     * which is loaded and filled in the background. Register an
     * MAlfTextureLoadingCompletedObserver instance to the iLoadedObservers
     * array, whose TextureLoadingCompleted() method will be called when
     * textures finish loading. The same observer is also called if an error
     * occurs during the loading process. The other method is to check if an
     * image has been loaded with TextureManagers IsLoaded().
     *
     * If a texture with the given id or filename is already loaded the previously
     * loaded texture is returned. If texture with the given id has been unloaded
     * with UnloadTexture() method then the id is reused by loading a new texture
     * on the id.
     *
     * @param aImageName            Name of the image bitmap file to load. If
     *                              empty filename is used, will check if a
     *                              filename for the aId has been defined
     *                              (using DefineFileNameL()) and load a texture
     *                              using that resource location, if possible.
     * @param aTextureMaxSize       Can be used to define a maximum dimensions
     *                              for the final texture. The image data
     *                              loaded will be scaled (down) and fitted to
     *                              these dimensions. Use zero or below-zero
     *                              values if size does not matter. If the
     *                              texture size is larger than the texture
     *                              size supported by the GL, the texture will
     *                              be split to multiple segments.
     * @param aFlags                Specify load/upload behavior - how to convert
     *                              the bitmap to texture.
     * @param aId                   Id for the texture. Must be unique.
     *                              KAlfAutoGeneratedTextureId can be used to let 
     *                              texture manager automatically decide id.
     *
     * @note                        If both image name and id are left undefined
     *                              ("" and zero), will return a blank texture.
     *
     * @return Reference to the texture.
     *
     * @see SetImagePathL() To set the image search path. Set to "" to use
     * absolute image filenames.
     * @see iLoadObservers
     * @see MAlfTextureLoadingCompletedObserver::TextureLoadingCompleted()
     * @see IsLoaded()
     */
    IMPORT_C CAlfTexture& LoadTextureL(const TDesC& aImageName,
                                       TSize aTextureMaxSize,
                                       TAlfTextureFlags aFlags,
                                       TInt aId);

    /**
     * Creates a texture by calling the ProvideBitmapL method of the passed MAlfBitmapProvider.
     *
     * If a texture with the given id is already created or loaded the previously
     * existing texture is returned. If texture with the given id has been unloaded
     * with UnloadTexture() method then the id is reused by loading a new texture
     * on the id.
     *
     * @param aBitmapProvider       A bitmap provider that will load the bitmaps for us. The
     *                              ProvideBitmapL method of this will be called, which should
     *                              load or generate the needed bitmaps.
     * @param aFlags                Specify load/upload behavior - how to convert
     *                              the bitmap to texture.
     * @param aId                   Id for the texture. Must be unique, use
     *                              KAlfAutoGeneratedTextureId to let texture manager
     *                              automatically decide id.
     *                              
     * @return Reference to the created texture.
     * @leave KErrArgument The bitmap and the mask bitmap are incompatible (different size).
     */
    IMPORT_C CAlfTexture& CreateTextureL(TInt aId,
                                         MAlfBitmapProvider* aBitmapProvider,
                                         TAlfTextureFlags aFlags);



    /**
     * Unloads a texture from memory.
     *
     * This method releases the texture id and image name for reusing.
     * @see LoadTexture().
     *
     * @note May unload several textures from memory, if they have the
     * sane image name assigned!
     */
    IMPORT_C void UnloadTexture(const TDesC& aImageName);

    /**
     * Unloads a texture from memory.
     *
     * This method releases the texture id and image name for reusing.
     * 
     */
    IMPORT_C void UnloadTexture(TInt aId);

    /**
     * Updates texture content without changing the texture address.
     *
     * this is an asynchronous method which is loaded and filled in 
     * the background. Register an MAlfTextureLoadingCompletedObserver instance
     * to the iLoadedObservers array, whose TextureLoadingCompleted() method 
     * will be called when textures finish loading. The same observer is also 
     * called if an error occurs during the loading process. The other method 
     * is to check if an image has been loaded with TextureManagers IsLoaded().
     *
     * @param aId               Id for the texture. Must be unique.
     *
     * @param aFileName    		Name of the image bitmap file to load. Relative
     *                          to the image load path. If filename is empty or
     *                          not given, will check if a filename for the id has
     *                          been defined and load a texture using that resource
     *                          location, if possible.
     * @leave 					If this method leaves the texture is not valid any more.
     *
     * @see SetImagePathL() To set the image search path. Set to "" to use
     * absolute image filenames.
     * @see iLoadObservers
     * @see MAlfTextureLoadingCompletedObserver::TextureLoadingCompleted()
     * @see IsLoaded()
     */
    IMPORT_C void UpdateTextureFromFileL(TInt aId, const TDesC* aFileName = NULL);

    /**
     * Updates texture content without changing the texture address.
     *
     * @param aId               Id for the texture. 
     * @param aBitmapProvider	A bitmap provider that will load the bitmaps for us. The
     *                          ProvideBitmapL method of this will be called, which should
     *                          load or generate the needed bitmaps. If this is not given 
     *                          the current provider is called instead.
     * @leave 					If this method leaves the texture is not valid any more.
     */
    IMPORT_C void UpdateTextureFromBitmapL(TInt aId, MAlfBitmapProvider* aBitmapProvider = NULL);

    /**
     * Define (register) a texture resource (filename/path) for
     * a texture id. Enables calling the LoadTextureL only with an id.
     * This resource will then be loaded when LoadTextureL
     * is called with the id.
     */
    IMPORT_C void DefineFileNameL(TInt aId, const TDesC& aImageName);

    /**
     * Prepends the image path to the beginning of the file name,
     * if necessary.
     */
    IMPORT_C void PrependImagePath(TDes& aFileName);

     /**
     * Adds texture loading observer
     *
     * @param aObserver observer to be added to array
     * @leave any system wide error code
     */
    IMPORT_C void AddLoadObserverL(MAlfTextureLoadingCompletedObserver* aObserver);

     /**
     * Removes texture loading observer, this must be done at latest when observer is being deleted
     *
     * @param aObserver observer to be removed from array
     */
    IMPORT_C void RemoveLoadObserver(MAlfTextureLoadingCompletedObserver* aObserver);

     /**
     * Adds texture manager state observer
     *
     * @param aObserver observer to be added to array
     * @leave any system wide error code
     */
    IMPORT_C void AddStateObserverL(MAlfTextureManagerStateChangedObserver* aObserver);

     /**
     * Removes texture manager state observer, this must be done at latest when observer is being deleted
     *
     * @param aObserver observer to be removed from array
     */
    IMPORT_C void RemoveStateObserver(MAlfTextureManagerStateChangedObserver* aObserver);

    /**
     * Returns a reference to the texture processor.
     * @return Texture processor
     */
    IMPORT_C CAlfTextureProcessor& Processor();

    /**
     * Sets the range where texture manager is allowed to assign new texture ids automatically.
     *
     * @param aLow  Smallest texture id that can be auto assigned.
     * @param aHigh Largest texture id that can be auto assigned.
     *
     */
    IMPORT_C void SetAutomaticTextureIdRange(TInt aLow, TInt aHigh);
    
    /**
     * Checks if a texture exists, has content and is not found
     * from the texture load queue.
     * 
     * Mainly meant for file-based textures to check if the 
     * texture is ready to be used. 
     * 
     * Note that textures may have some temporary placeholder
     * content already before they have been fully loaded!
     * 
     * For CreateTextureL -based textures it is recommended to use
     * CAlfTexture::HasContent() directly.
     * 
     * @see LoadTextureL()
     * @see CreateTextureL()
     * @see CAlfTexture::HasContent()
     *
     * @param aImageName  Name of the image bitmap file to check. 
     * 					  ImagePath (if set) will be prepended to 
     * 					  this name.
     * @return 			  ETrue if texture exists, has content and 
     * 					  is not found from the texture load queue.
     */
    IMPORT_C TBool IsLoaded(const TDesC& aImageName) const;
    
    /**
     * Returns the texture ID of the previously loaded file.
     *
     * @param aImageName  Name of the image bitmap file to check. 
     * 					  ImagePath (if set) will be prepended to 
     * 					  this name.
     * @return 			  Texture ID of the already created texture
     *                    KErrNotFound if the texture has not been created.
     */
    IMPORT_C TInt TextureId(const TDesC& aImageName) const;

    /**
     * Checks if a texture exists, has content and is not found
     * from the texture load queue.
     * 
     * Mainly meant for file-based textures to check if the 
     * texture is ready to be used. 
     * 
     * Note that textures may have some temporary placeholder
     * content already before they have been fully loaded!
     * 
     * For CreateTextureL -based textures it is recommended to use
     * CAlfTexture::HasContent() directly.
     * 
     * @see LoadTextureL()
     * @see CreateTextureL()
     * @see CAlfTexture::HasContent()
     *
     * @param aId 		Id of the texture.
     * @return 			ETrue if texture exists, has content and is not found
     * 					from the texture load queue.
     */
    IMPORT_C TBool IsLoaded(TInt aId) const;

    /**
     * Checks if a texture exists, has content and is not found
     * from the texture load queue.
     * 
     * Mainly meant for file-based textures to check when the 
     * texture is ready to be used. 
     * 
     * Note that textures may have some temporary placeholder
     * content already before they have been fully loaded!
     * 
     * For CreateTextureL -based textures it is recommended to use
     * CAlfTexture::HasContent() directly.
     * 
     * @see LoadTextureL()
     * @see CreateTextureL()
     * @see CAlfTexture::HasContent()
     *
     * @param aTexture Texture object.
     * @return True if texture exists, has content and is not found
     * from the texture load queue.
     */
    IMPORT_C TBool IsLoaded(const CAlfTexture * aTexture) const;

    /**
     * @deprecated <b>Always returns an invalid reference!</b>
     * 
     * Loads a sequence of images and makes it an animated texture.
     *
     * @param aSkinName             Logical name of animated element
     * @param aTextureMaxSize       Can be used to define a maximum dimensions
     *                              for the final texture. The image data
     *                              loaded will be scaled (down) and fitted to
     *                              these dimensions. Use zero or below-zero
     *                              values if size does not matter.
     * @param aFlags                Specify load/upload behavior
     * @param aId                   Id for the texture. Must be unique.
     *                              KAlfAutoGeneratedTextureId can be used to let 
     *                              texture manager automatically decide id.
     *
     * @return Reference to the texture.
     */
	IMPORT_C CAlfTexture& LoadAnimatedTextureL(const TDesC& aSkinName,
	                                       TSize aTextureMaxSize,
	                                       TAlfTextureFlags aFlags,
	                                       TInt aId);

    /** @endAPI */
    
    TUid ManagerUid();
    
    /**
     * Appends a texture to the texture manager's list of managed textures.
     * Ownership of the texture is transferred to the manager; when the manager
     * is destroyed, the texture will be destroyed, too.
     *
     * Checks already existing duplicate textures
     * having matching id and leaves with appropriate errorcode if needed.
     *
     * @param aTexture  Texture to transfer to the manager.
     * @param aId       Id for the texture. Must be unique.
     * @leave KErrAlreadyExists if a texture with the given id already exists.
     *
     */
    void AppendTextureL(CAlfTexture* aTexture);

    /**
     * Removes a texture from management. The texture's ownership is
     * transferred to the caller.
     *
     * @param aTexture  Texture to remove from management.
     */
    void RemoveTexture(CAlfTexture& aTexture);
    
    /**
     * Gets the state of the texture manager.
     *
     * @return State of the texture manager.
     */
    TState State() const;
    
    /**
     * Releases texture manager resources. Releases all textures. 
     * Called when AlfEnv is restored.
     *
     * While the release operation is in progress, it is not possible to delete
     * CAlfTexture instances or create new ones. After the release has been
     * completed, textures can again be deleted and created.
     *
     * @param aReleasePriorityLevel Priority level. All textures, which 
     *        priority has equal or higher value are released.
     *
     * @return Were all textures released? If ETrue all texture were released.
     *         If EFalse, some texture were not released.
     * 
     * @panic ETextureManagerTextureConstructedDuringRelease
     *      A new CAlfTexture was constructed and added to the texture
     *      manager during the release operation.
     * @panic ETextureManagerTextureDestroyedDuringRelease
     *      An existing CAlfTexture was destroyed and removed from the texture
     *      manager during the release operation.
     *
     * @see RestoreL()
     */
    TBool Release( TInt aReleasePriorityLevel = EAlfTexturePriorityNormal );

    /**
     * Restores texture manager resources. Restores the content of all textures
     * released in Release(). Called when AlfEnv is restored.
     *
     * While the restore operation is in progress, it is not possible to delete
     * CAlfTexture instances or create new ones. After the restore has been
     * completed, textures can again be deleted and created.
     *
     * @param aRestorePriorityLevel Priority level. All textures, which 
     *        priority has equal or lower value are restored.
     *
     * @return Were all textures restored? If ETrue all texture were restored.
     *         If EFalse, some texture were not restored.
     *
     * @panic ETextureManagerTextureConstructedDuringRestore
     *      A new CAlfTexture was constructed and added to the texture
     *      manager during the restore operation.
     * @panic ETextureManagerTextureDestroyedDuringRestore
     *      An existing CAlfTexture was destroyed and removed from the texture
     *      manager during the restore operation.
     *
     * @see Release()
     */
    TBool RestoreL( TInt aRestorePriorityLevel = EAlfTexturePriorityLow );

    /**
     * Releases and restores skin dependent textures. Usually called after
     * system skin has been changed.
     */
    void NotifySkinChangedL();

    /**
    * Increases the texture reference count based on texture id.
    *
    * @param aId the texture id
    */
    void IncRefcount(TInt aId);

    /**
    * Decreases the texture reference count based on texture id.
    *
    * @param aId the texture id
    */
    void DecRefcount(TInt aId);

    /**
     * Reports texture information, i.e. what's the size of texture in
     * display.
     * @param aTextureId texture identifier.
     * @param aSize texture size.
     */
    void ReportTextureInfoL( TInt aTextureId, const TSize& aTextureSize );

    /**
     * Adds texture manager texture auto size observer.
     *
     * @param aObserver observer to be added to array
     * @leave any system wide error code
     */
    IMPORT_C void AddAutoSizeObserverL(MAlfTextureAutoSizeObserver* aObserver);

    /**
     * Removes texture manager texture auto size observer.
     *
     * @param aObserver observer to be removed from array
     */
    IMPORT_C void RemoveAutoSizeObserver(MAlfTextureAutoSizeObserver* aObserver);

protected:

    /* Constructors. */

    /**
     * Constructor.
     */
    CAlfTextureManager();

    /**
     * Second-phase constructor.
     */
    void ConstructL(CAlfEnv& aEnv, TUid aUid);

private:

    /**
     * Check the existence of a texture.
     *
     * @param aFileName  File name of the texture.
     *
     * @return  Index of the texture, in the iTextures array, or KErrNotFound if not found.
     */
    TInt CheckTexture(const TDesC& aFileName) const;

    /**
     * Check if texture exists with given id.
     *
     * @return  Index of the texture, in the iTextures array, or KErrNotFound if not found.     
     */
    TInt CheckTexture(TInt aId) const;

    /**
     * Called when image loading (decoding) operation is complete.
     */
    void RunL();

    /**
     * Handles a leave occurring in the request completion event handler RunL().
     */
    TInt RunError(TInt aError);

    /**
     * Cancel active object operation.
     */
    void DoCancel();

    /**
     * Starts loading next images from the load queue. If scheduling a
     * queue entry fails for some reason, the entry is discarded and the
     * next queue entry is processed.
     */
    void StartLoading();

    /**
     * Cleans up the topmost load queue entry and removes it from the
     * load queue. Deletes the decoder, but not the loaded texture entry.
     */
    TLoadQueueEntry PopLoadedQueueEntry();

    /**
     * Sets up image decoding and starts to load the first entry in the load
     * queue.
     * @leave Standard error code if decoder initialization/resource read
     * fails.
     */
    void DoLoadNextL();

    /**
     * Called when an image has finished loading. Handles
     * uploading of the loaded bitmap to the texture.
     *
     * @param aEntry  Entry whose contents have been loaded.
     */
    void ImageLoadingCompleteL(TLoadQueueEntry& aEntry);

    /**
     * Helper method that notifies observers of texture manager state change.
     * 
     */
    void NotifyStateChange() const;

    /**
     * Helper method that notifies observers of texture load completion.
     */
    void NotifyTextureLoaded(CAlfTexture& aTexture,
                             TInt aTextureId,
                             TInt aErrorCode) const;
    

    /** Returns true if the given texture is still in the load queue. */
    TBool IsInLoadQueue(const CAlfTexture* texture) const;
    
    /** Cancels loading of a texture */
    void CancelLoadingOfTexture(CAlfTexture& aTexture);    

    /** Generates unique id for texture */
    TInt GenerateTextureId();
    
    /** Releases one texture */
    void ReleaseEntry(const TTextureEntry& aEntry);

    /** Restores one texture */
    void RestoreEntryL(const TTextureEntry& aEntry);
    
    /** Returns ETrue if this texturemanager is a shared texture manager */
    TBool IsShared();

    /** Updates texture by re-uploading content */    
    void UpdateTextureL(TInt aId, TSize aSize);

    /** Reloads texture from a file */    
    void ReloadTextureL(const TDesC& aImageName,
                        TSize aTextureMaxSize,
                        TAlfTextureFlags aFlags,
                        TInt aId);

    /** Recreates texture from a bitmap provider */    
    void RecreateTextureL(TInt aId,
                          MAlfBitmapProvider* aBitmapProvider,
                          TAlfTextureFlags aFlags);

    /** Starts the texture garbagecollecting, triggered
    * automatically when zero refcount textures are
    * detected
    */
    void StartGarbageCollect();
    
    /* Garbace collector callback function */
    static TInt GarbageCollect(TAny* aPtr);

    /* Modifies flags */
    void RemoveFlags(TAlfTextureFlags& aFlags, TInt aFlagsToBeRemoved);

    /* Modifies flags */
    void SetFlags(TAlfTextureFlags& aFlags, TInt aFlagsToBeSet);

private:

	/* Private data. Owned */
    struct TPrivateData;    
    TPrivateData* iData;
    
    };

#endif
