/***************************************************************************
 *   Copyright (C) 2003 by S�astien Laot                                 *
 *   slaout@linux62.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 BACKGROUNDMANAGER_H
#define BACKGROUNDMANAGER_H

#include <tqobject.h>
#include <tqvaluelist.h>
#include <tqstring.h>
#include <tqpixmap.h>
#include <tqcolor.h>
#include <tqtimer.h>

/** A node in the list of background images of BackgroundManager.
  * It can only be used by BackgroundManager because it is an internal structure of this manager.
  * @author S�astien Laot
  */
class BackgroundEntry
{
	friend class BackgroundManager;

  protected:
	BackgroundEntry(const TQString &location);
	~BackgroundEntry();

	TQString  name;
	TQString  location;
	bool     tiled;    /// << Only valid after some object subscribed to this image! Because it's only read at this time.
	TQPixmap *pixmap;   /// << Only valid (non-null) after some object subscribed to this image! Because it's only read at this time.
	TQPixmap *preview;  /// << Only valid (non-null) after some object requested the preview.
	int      customersCount;
};

/** A node in the list of opaque background images (with a background color applyed to an image) of BackgroundManager.
  * It can only be used by BackgroundManager because it is an internal structure of this manager.
  * @author S�astien Laot
  */
class OpaqueBackgroundEntry
{
	friend class BackgroundManager;

  protected:
	OpaqueBackgroundEntry(const TQString &name, const TQColor &color);
	~OpaqueBackgroundEntry();

	TQString  name;
	TQColor   color;
	TQPixmap *pixmap;
	int      customersCount;
};

/** Manage the list of background images.
  * BASIC FUNCTIONNING OF A BACKGROUND CHOOSER:
  *   It get all image names with imageNames() to put them in eg. a TQComboBox and then,
  *   when it's time to get the preview of an image it call preview() with the image name to get it.
  *   Preview are only computed on demand and then cached to fast the next demands (only the pointer will have to be returned).
  *   Previews are scalled to fit in a rectangle of 100 by 75 pixels, and with a white background color.
  *   They are also saved to files, so that the scalling/opaquification has not to be done later (they will be directly loaded from file).
  *   Previews are saved in Global::backgroundsFolder()+"previews/", so that emptying the folder is sufficient to remove them.
  * BASIC FUNCTIONNING OF AN IMAGE REQUESTER:
  *   When eg. a basket is assigned an image name, it register it with subscribe().
  *   The full pixmap is then loaded from file and cached (if it was not already loaded) and the "tiled" property is read from the image configuration file.
  *   If this object want to have the pixmap applyed on a background color (for no transparency => really faster drawing),
  *   it should register for the couple (imageName,color) with suscribe(): the pixmap will be created in the cache.
  *   Then, the object can get the subscribed images with pixmap() or opaquePixmap() and know if it's tiled with tiled().
  *   When the user removed the object background image (or when the object/basket/... is removed), the object should call unsubscribe() for
  *   EVERY subscribed image and image couples. Usage count is decreased for those images and a garbage collector will remove the cached images
  *   if nothing is subscribed to them (to free memory).
  * @author S�astien Laot
  */
class BackgroundManager : private TQObject
{
  Q_OBJECT
  
  private:
	/// LIST OF IMAGES:
	typedef TQValueList<BackgroundEntry*>       BackgroundsList;
	typedef TQValueList<OpaqueBackgroundEntry*> OpaqueBackgroundsList;

  public:
	/// CONTRUCTOR AND DESTRUCTOR:
	BackgroundManager();
	~BackgroundManager();
	/// SUBSCRIPTION TO IMAGES:
	bool subscribe(const TQString &image); /// << @Return true if the loading is a success. In the counter-case, calling methods below is unsafe with this @p image name.
	bool subscribe(const TQString &image, const TQColor &color); /// << Idem.
	void unsubscribe(const TQString &image);
	void unsubscribe(const TQString &image, const TQColor &color);
	/// GETTING THE IMAGES AND PROPERTIES:
	TQPixmap* pixmap(const TQString &image);
	TQPixmap* opaquePixmap(const TQString &image, const TQColor &color);
	bool tiled(const TQString &image);
	/// LIST OF IMAGES AND PREVIEWS:
	bool exists(const TQString &image);
	TQStringList imageNames();
	TQPixmap* preview(const TQString &image);
	/// USED FOR EXPORTATION:
	TQString pathForImageName(const TQString &image); /// << It is STRONGLY advised to not use those two methods unless it's to copy (export) the images or something like that...
	TQString previewPathForImageName(const TQString &image);
	/// USED FOR IMPORTATION:
	void addImage(const TQString &fullPath);

  private:
	BackgroundEntry*       backgroundEntryFor(const TQString &image);
	OpaqueBackgroundEntry* opaqueBackgroundEntryFor(const TQString &image, const TQColor &color);

  private:
	BackgroundsList       m_backgroundsList;
	OpaqueBackgroundsList m_opaqueBackgroundsList;
	TQTimer                m_garbageTimer;
  private slots:
	void requestDelayedGarbage();
	void doGarbage();
};

#endif // BACKGROUNDMANAGER_H