/*
* Copyright (c) 2009 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: Thumbnail manager for the social phonebook.
*
*/

#ifndef CPBK2THUMBNAILMANAGER_H_
#define CPBK2THUMBNAILMANAGER_H_

// external includes
#include <e32base.h>
#include <MVPbkSingleContactOperationObserver.h>
#include <MPbk2ImageOperationObservers.h>
#include <MVPbkContactViewObserver.h>
#include <TPbk2IconId.h>


//FORWARD declaration
class CPbk2ImageManager;
class CVPbkContactManager;
class MVPbkContactOperationBase;
class MVPbkContactLink;
class MVPbkStoreContact;
class MVPbkBaseContact;
class MVPbkFieldType;
class CPbk2TmItem;
class CPbk2IconArray;

//internal state of the loader
enum TTMLoadingState
	{
	ELoading,
	EIdle
	};

// state for determining whether to optimize or not
enum TTMOptimizationState
	{
	EOptimize,
	ENoOptimization
	};

/*
 * Observer class for the manager
 */
class MPbk2ThumbnailManagerObserver
	{
public:
	
	/*
	 * This is called after all thumbnails from the loading queue is loaded.
	 */
	virtual void LoadingFinished() = 0;
	
	/*
	 * Informs observer that loading of thumbnail is complete
	 * Param@   aError, KErrNone if success, KErrNotFound if not found.
	 * param@	index on listbox or KErrNotFound if not found
	 */
	virtual void ThumbnailLoadingComplete( TInt aError, TInt aIndex ) = 0;
	
	/*
	 * Informs the observer that thumbnail has been deleted from the manager's array. Listbox index is the index
	 * that is given when thumbnail is asked to be loaded
	 */
	virtual void ThumbnailRemoved( const MVPbkContactLink& aLink, TInt aIndex ) = 0;
	
	};


/*
 * Class for loading contact thumbnails
 */
NONSHARABLE_CLASS( CPbk2ThumbnailManager ) : public CBase,
											 public MVPbkSingleContactOperationObserver,
											 public MPbk2ImageGetObserver,
											 public MVPbkContactViewObserver
	{
public:	// constructor & destructor
	
	IMPORT_C static CPbk2ThumbnailManager* NewL( CVPbkContactManager& aContactManager );
	virtual ~CPbk2ThumbnailManager();
	
	
public:	// new functions
	
	/*
	 * Sets observer for the manager
	 */
	void SetObserver( MPbk2ThumbnailManagerObserver& aObserver );
	
	/*
	 * Removes observer
	 */
	void RemoveObserver();
	
	
	/*
	 * Returns icon index from Pbk2IconArray for double listbox index. 
	 * If icon is not set, default icon index is returned
	 */
	TInt GetPbkIconIndex( TInt aListboxIndex, const MVPbkBaseContact& aContactLink );
	
	/*
	 * Setter for default icon ID
	 */
	void SetDefaultIconId( TPbk2IconId aDefaultIconId );
		
	/*
	 * Returns default icon id
	 */
	const TPbk2IconId& GetDefaultIconId();
	
	/*
	 * Setter for Pbk2IconArray. Thumbnail manager doesn't own the array.
	 */
	void SetPbkIconArray( CPbk2IconArray* aIconArray );
	
	/*
	 * Removes icon array from the manager. Doesn't destroy the arrray
	 */
	void RemoveIconArray();
	
	/*
	 * Returns number of loaded thumbnails
	 */
	TInt ThumbnailCount();	
	
	/*
	 * Adds contact to the array and starts loading the thumbnail for it. 
	 * If loading is already in progress, contact is added to queue. 
	 * 
	 */
	void LoadThumbnailL(  const MVPbkContactLink& aContactLink, TInt aListboxIndex  );

	/*
	 * Removes contact from loader's array and deletes the thumbnail. 
	 * Returns KErrNone or KErrNotFound.
	 */
	TInt RemoveThumbnail( const MVPbkContactLink& aContactLink, TInt aListboxIndex  );
	
	/**
	 * Reset thumbnail manager. Clear cache and cancel all ongoing operations.
	 */
	void Reset();
	
	/*
	 * Setter for thumbnail icon size
	 */
	void SetThumbnailIconSize( TSize aSize );
	
	/*
	 * Getter for thumbnail icon size
	 */
	const TSize& GetThumbnailIconSize();
	
private:	// new functions
	
	/*
	 * If contact is added to  middle of the list, increase indexes that are added after the given index
	 */
	void IncreaseIndexes( TInt aListboxIndex );
	
	/*
	 * If contact is removed from middle of the list, decrease indexes that are added after the given index
	 */
	void DecreaseIndexes( TInt aListboxIndex );
	
	/*
	 * Removes allready loaded thumbnail from the last position of the priorization array. 
	 * Removes also image from Pbk2IconArray and iContactThumbnails. 
	 */
	void MakeRoomForNextThumbnail();
	
	/*
	 * Finds correct item from the iContactThumbnails based on the base contact
	 */
	CPbk2TmItem* FindItem( const MVPbkBaseContact& aContactLink );
	/*
	 * Starts loading of the contact thumbnails. 
	 */
	void StartLoading();
	
	/*
	 * Loads the thumbnail for the contact
	 */
	void DoLoadThumbnail( MVPbkBaseContact& aContact );
	
	/*
	 * Duplicates the bitmap handle
	 */
	CFbsBitmap* DuplicateBitmapL( CFbsBitmap* aSourceBitmap ); 
	
	/*
	 * Reads file type for the contact image
	 */
	void ReadFieldTypeL();
	
	/**
	 * Append bitmap into icon array
	 */
	void AppendIconL( TPbk2IconId& aIcon, CFbsBitmap* aBitmap );
	
	/*
	 * Icon indexes must be updated after icon(s) are removed from the icon array
	 */
	void UpdateIconIndexes( );

	/**
	 * Handle view ready events
	 */
	void DoContactViewReadyL( MVPbkContactViewBase& aView );

private: // From MVPbkSingleContactOperationObserver
   void VPbkSingleContactOperationComplete(
		   MVPbkContactOperationBase& aOperation,
		   MVPbkStoreContact* aContact );
   
   void VPbkSingleContactOperationFailed(
		   MVPbkContactOperationBase& aOperation,
		   TInt aError );

private: // From MPbk2ImageGetObserver
	void Pbk2ImageGetComplete(
			MPbk2ImageOperation& aOperation,
			CFbsBitmap* aBitmap );
	void Pbk2ImageGetFailed(
			MPbk2ImageOperation& aOperation,
			TInt aError );

private: // From MVPbkContactViewObserver
    void ContactViewReady( MVPbkContactViewBase& aView );
    void ContactViewUnavailable( MVPbkContactViewBase& aView );
    void ContactAddedToView(
        MVPbkContactViewBase& aView, 
        TInt aIndex, 
        const MVPbkContactLink& aContactLink );
    void ContactRemovedFromView(
        MVPbkContactViewBase& aView, 
        TInt aIndex, 
        const MVPbkContactLink& aContactLink );
    void ContactViewError(
        MVPbkContactViewBase& aView, 
        TInt aError, 
        TBool aErrorNotified );

	
private:	//constructors
	CPbk2ThumbnailManager( CVPbkContactManager& aContactManager );
	void ConstructL();
	
private:	//data
	
	//OWN: thumbnail size
	TSize							iIconSize;
	
	// internal state
	TTMLoadingState					iState;
	
	/// Own:	thumbnails
	RPointerArray<CPbk2TmItem>		iContactThumbnails;
	
	/// Own:	Loading queue for the thumbnails
	RPointerArray<CPbk2TmItem>		iLoadingQueue;
	
	/// Own: Thumbnail manager
	CPbk2ImageManager* 				iManager;
	
	// ref:
	CVPbkContactManager& 			iContactManager;
	
	 /// Own: Retrieve operation
	MVPbkContactOperationBase* 		iRetrieveOperation;
	
	/// Own: Store contact
	MVPbkStoreContact* 				iStoreContact;
	
	/// Own: Asynchronous thumbnail operation
	MPbk2ImageOperation* 			iThumbOperation;
	
	// REF: observer for the loader
	MPbk2ThumbnailManagerObserver*	iObserver;
	
	/// Ref: Field type
	const MVPbkFieldType* 			iFieldType;
	
	//REF:	listbox icon array
	CPbk2IconArray*					iIconArray;
	
	// default icon index and id
	TInt							iDefaultIconIndex;
	TPbk2IconId						iDefaultIconId;
	// icon index counter
	TInt							iIconIdCounter;
	// loading priority.
	RArray<MVPbkContactLink*>		iPriorityArray;
	/// Own: Holds the item whose thumbnail load is in progress
	/// This item needs to be removed when its safe
	CPbk2TmItem*                    iInProgressItemToBeRemoved;
	};

#endif /* CPBK2THUMBNAILMANAGER_H_ */
