#ifndef NOATUNPLAYLIST_H
#define NOATUNPLAYLIST_H

#include <qobject.h>
#include <kurl.h>

class PlayListItem
{
	friend class Downloader;
public:
	/**
	 * if dl is true, then download this ASAP
	 * dl implicitly becomes false if u==0 or
	 * it's a local file
	 **/
	PlayListItem(const KURL &u=0, bool dl=true);
	virtual ~PlayListItem();

	/**
	 * title of the song
	 * it may just be the ID3 tag, but I can't guarantee it
	 **/
	QString title() const;
	/**
	 * set the title of the song (ID3 loaders do this)
	 * also, note that that rather then overridering
	 * this, you should prefer modified()
	 **/
	virtual void setTitle(const QString &t);
	
	/**
	 * return the location as local, or null if 
	 * file hasn't yet started downloading
	 **/
	QString file() const;

	/**
	 * is the file completely downloaded?
	 * if so, file() will return the name
	 **/
	bool isDownloaded() const;
	/**
	 * if false, don't try to play the file
	 * if true, go ahead, but it may not
	 * be complete
	 **/
	bool playable() const;
	
	KURL url() const;
	virtual void setUrl(const KURL &u, bool dl=true);
	
	/**
	 * length as a string
	 * The format is cc:cc/ll:ll where c is current
	 * and l is length
	 **/
	QString lengthString() const;

	/**
	 * If you can identify the length of this file
	 * set it, in seconds.  The engine will do it
	 * itself.
	 *
	 * If unknownm, the length will be -1
	 **/
	virtual void setLength(int sec);

	/**
	 * length of the song in seconds, or -1 if unknown
	 **/
	int length() const { return mLength; }

	/**
	 * retursn the mimetype for this file
	 * (potentially slow)
	 **/
	QCString mimetype() const;

	/**
	 * returns the mimetype's associated extentions
	 **/
	QStrList extension() const;

	/**
	 * if 1000 is the length, mille is less than 1000
	 * and mille is proportional to the length. (good for sliders)
	 **/
	int fromMille(int mille);
	
	/**
	 * exactly the same as file()
	 **/
	operator QString() const { return file(); }
	
	/**
	 * return the net-location
	 **/
	operator KURL() const { return url(); }

protected: // methods accessed by Downloader (friend)
	/**
	 * this file is done downloading
	 **/
	virtual void doneDownloading();
	
	/**
	 * called every so often when the percent of download
	 * changes.
	 **/
	virtual void downloaded(int percent);

	/**
	 * called when the title or  length, or when
	 * the file is done downloading
	 **/
	virtual void modified();

	/**
	 * download timed out, by default, delete this
	 **/
	virtual void timeout();
	
protected:
	QString mTitle;
	KURL mUrl;
	QString mFile;
	bool mDownloaded;
	int mLength;
};

/**
 * The playlist, which you derive from when creating
 * your own playlist.
 **/
class PlayList : public QObject
{
Q_OBJECT
	friend class PlayListItem;
public:
	PlayList(QObject *parent, const char *name);
	
	/**
	 * go to the front
	 **/
	virtual void reset()=0;
	
	/**
	 * empty the list
	 **/
	virtual void clear()=0;
	/**
	 * add a file
	 */
	virtual void addFile(const KURL&, bool play=false)=0;

	/**
	 * cycle forward, return that
	 **/	
	virtual PlayListItem *next()=0;
	/**
	 * current item
	 **/
	virtual PlayListItem *current()=0;
	/**
	 * cycle back, return that
	 **/
	virtual PlayListItem *previous()=0;

	/**
	 * get the first item
	 **/
	virtual PlayListItem *getFirst() const =0;

	/**
	 * get the item after item
	 **/
	virtual PlayListItem *getAfter(const PlayListItem *item) const =0;
	 
	/**
	 * is the view visible?
	 **/
	virtual bool listVisible() const =0;
	/**
	 * do the KCmdLineArgs stuff
	 **/
	int handleArguments();

public slots:
	/**
	 * show the list!
	 **/
	virtual void showList()=0;
	/**
	 * hide it
	 **/
	virtual void hideList()=0;
	/**
	 * toggle visibility
	 **/
	virtual void toggleList();
	/**
	 * remove the item
	 **/
	virtual void remove(PlayListItem*)=0;

signals:
	/**
	 * when item @p item is deleted from the 
	 * playlist.  the item itself has no such
	 * signal since it's not a QObject
	 *
	 * This is called by the internals to signal
	 * a deleted file
	 **/
	void removed(PlayListItem *item);
	/**
	 * when you want the engine to reload current()
	 **/
	void playCurrent();
	/**
	 * when the list is hidden
	 **/
	void listHidden();
	/**
	 * when the list is shown
	 **/
	void listShown();
	/**
	 * they just added one that will be played when
	 * the play button is pressed.  emit this when no file
	 * has been replace by some file, not always.
	 **/
	void newCurrent();

	/**
	 * A new item has been allocated, this is
	 * called by the internals
	 **/
	void added(PlayListItem *item);

private:
	void deleted(PlayListItem *item);
};

#endif

