/*	Gwenview - A simple image viewer for TDE
	Copyright 2000-2004 Aur�lien G�teau
	This class is based on the ImagePreviewJob class from Konqueror.
	Original copyright follows.
*/
/*	This file is part of the KDE project
	Copyright (C) 2000 David Faure <faure@kde.org>

	This program is free software; you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation; either version 2 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program; if not, write to the Free Software
	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

#ifndef THUMBNAILLOADJOB_H
#define THUMBNAILLOADJOB_H

// TQt
#include <tqimage.h>
#include <tqpixmap.h>
#include <tqvaluelist.h>
#include <tqvaluevector.h>

// KDE
#include <tdeio/job.h>

// Local
#include "tsthread/tsthread.h"
#include "tsthread/tswaitcondition.h"

#include "libgwenview_export.h"
class TDEConfig;
class KFileItem;

typedef TQPtrList<KFileItem> KFileItemList;

namespace Gwenview {
class ThumbnailThread : public TSThread {
TQ_OBJECT
  
public:
	void load(
		const TQString& originalURI,
		time_t originalTime,
		int originalSize,
		const TQString& originalMimeType,
		const TQString& pixPath,
		const TQString& thumbnailPath,
		int size,
		bool storeThumbnail);
protected:
	virtual void run();
signals:
	void done( const TQImage&, const TQSize&);
private:
	bool isJPEG();
	bool loadJPEG();
	void loadThumbnail();
	TQImage mImage;
	TQString mPixPath;
	TQString mThumbnailPath;
	TQString mOriginalURI;
	time_t mOriginalTime;
	int mOriginalSize;
	TQString mOriginalMimeType;
	int mOriginalWidth;
	int mOriginalHeight;
	TQMutex mMutex;
	TSWaitCondition mCond;
	int mThumbnailSize;
	bool mStoreThumbnailsInCache;
};

/**
 * A job that determines the thumbnails for the images in the current directory
 */
class LIBGWENVIEW_EXPORT ThumbnailLoadJob : public TDEIO::Job {
TQ_OBJECT
  
public:
	/**
	 * Create a job for determining the pixmaps of the images in the @p itemList
	 */
	ThumbnailLoadJob(const TQValueVector<const KFileItem*>* itemList, int size);
	virtual ~ThumbnailLoadJob();

	/**
	 * Call this to get started
	 */
	void start();

	/**
	 * To be called whenever an item is removed from the view
	 */
	void itemRemoved(const KFileItem* item);


	/**
	 * Add an item to a running job
	 */
	void appendItem(const KFileItem* item);

	
	/**
	 * Sets items in range first..last to be generated first, starting with current.
	 */	
	void setPriorityItems(const KFileItem* current, const KFileItem* first, const KFileItem* last);

	/**
	 * Temporarily suspends loading. Used if there's a more
	 * important action going on (loading an image etc.).
	 */
	void suspend();

	/**
	 * Resumes loading if suspended.
	 */
	void resume();

	/**
	 * Returns the thumbnail base dir, independent of the thumbnail size
	 */
	static TQString thumbnailBaseDir();
	
	/**
	 * Returns the thumbnail base dir, for the @p size
	 */
	static TQString thumbnailBaseDir(int size);


	/**
	 * Delete the thumbnail for the @p url
	 */
	static void deleteImageThumbnail(const KURL& url);

signals:
	/**
	 * Emitted when the thumbnail for the @p item has been loaded
	 */
	void thumbnailLoaded(const KFileItem* item, const TQPixmap&, const TQSize&);

private slots:
	void slotResult( TDEIO::Job *job );
	void slotGotPreview(const KFileItem*, const TQPixmap&);
	void checkThumbnail();
	void thumbnailReady(const TQImage& im, const TQSize&);
	void emitThumbnailLoadingFailed();

private:
	enum { STATE_STATORIG, STATE_DOWNLOADORIG, STATE_PREVIEWJOB, STATE_NEXTTHUMB } mState;

	TQValueList<const KFileItem*> mItems;
	TQValueVector<const KFileItem* > mAllItems;
	TQValueVector< bool > mProcessedState;
	const KFileItem *mCurrentItem;
	int thumbnailIndex( const KFileItem* item ) const;
	void updateItemsOrder();

	// indexes of the current, fist and last visible thumbnails
	int mCurrentVisibleIndex, mFirstVisibleIndex, mLastVisibleIndex;

	// The URL of the current item (always equivalent to m_items.first()->item()->url())
	KURL mCurrentURL;

	// The URI of the original image (might be different from mCurrentURL.url())
	TQString mOriginalURI;
	
	// The modification time of the original image
	time_t mOriginalTime;

	// The thumbnail path
	TQString mThumbnailPath;

	// The temporary path for remote urls
	TQString mTempPath;

	// Thumbnail size
	int mThumbnailSize;

	TQPixmap mBrokenPixmap;

	bool mSuspended;

	ThumbnailThread mThumbnailThread;

	void determineNextIcon();
	void startCreatingThumbnail(const TQString& path);
	
	void emitThumbnailLoaded(const TQImage& img, TQSize size);

	void updateItemsOrderHelper( int forward, int backward, int first, int last );
};

inline
int ThumbnailLoadJob::thumbnailIndex( const KFileItem* item ) const {
	TQValueVector<const KFileItem* >::ConstIterator pos = tqFind( mAllItems.begin(), mAllItems.end(), item );
	if( pos != mAllItems.end()) return pos - mAllItems.begin();
	return -1;
}

} // namespace
#endif

