/*
 * audio_playlist.h: The audio playlist interface
 *
 * See the README file for copyright information and how to reach the author.
 *
 * $Id: audio_playlist.h,v 1.2 2005/12/22 10:42:20 cm Exp $
 */

#ifndef __AUDIOPLAYLIST_H
#define __AUDIOPLAYLIST_H

#include <stdint.h>
#include "gen_dynarray.h"

#ifndef WITHOUT_PRELOADER
#  include <vdr/thread.h>
#endif

#if defined(PLUGIN_DAAP)
# include "daap_database.h"
#elif defined(PLUGIN_CDDA)
# include "cdda_device.h"
#endif

class cAudioPlaylist; // forward decl for cAudioTune

class cAudioTune {
  private:
    int m_songIndex;
    int m_songId;
    cAudioPlaylist *mpo_parent;
  public:
    cAudioTune(cAudioPlaylist *parent, int songid);
    virtual ~cAudioTune();
    bool operator==(const cAudioTune& tune) const;
    int GetSongId(void) const { return m_songId; };
    int SetSongId(int songid);
    cAudioPlaylist *Playlist(void) const { return mpo_parent; };
#if defined(PLUGIN_DAAP)
    // returns the data blob
    const cMediaDatabaseBlob *GetData(void);
#elif defined(PLUGIN_CDDA)
    cCddaTrack *GetData(void);
#endif
    // returns the data format
    const char *GetFormat(void);
};

#ifndef WITHOUT_PRELOADER

class cAudioTunePreloader : public cThread {
  private:
    bool m_ready;
    int m_numOfGets;
    cAudioTune *mpo_tune;
    const cMediaDatabaseBlob *mpo_blob;
    void Action(void);
  public:
    cAudioTunePreloader();
    virtual ~cAudioTunePreloader();
    void Clear(void);
    void SetItem(cAudioTune *tune);
    bool isEmpty(void) const { return NULL == mpo_tune; };
    bool isReady(void) const { return m_ready; };
    const cMediaDatabaseBlob *GetData(void) ;
};

#endif

class cAudioPlaylist {
  private:
    bool m_writeable;
    bool m_lock;
    char *mp_name;
    int m_id;
    int m_currentItem;
#if defined(PLUGIN_DAAP)
    cMediaDatabase *mpo_parent;
#elif defined(PLUGIN_CDDA)
    cCddaDisc *mpo_parent;
#endif
  protected:
    bool m_initialized;
    cDynamicArray<cAudioTune *> mo_items;
    virtual void Load(void);
  public:
#if defined(PLUGIN_DAAP)
    cAudioPlaylist(cMediaDatabase *parent, const char *name, int id, bool writeable = false);
#elif defined(PLUGIN_CDDA)
    cAudioPlaylist(cCddaDisc *parent, const char *name, int id, bool writeable = false);
#endif
    virtual ~cAudioPlaylist();
    const char *GetName(void) const { return mp_name; };
    const char *SetName(const char *name);
    int GetId(void) const { return m_id; };
    int SetId(int id);
    bool isWriteable(void) const { return m_writeable; };
    cAudioTune *Current(void);
    int SetCurrent(int current);
    int GetCurrent(void) const { return m_currentItem; };
    // (un)locks the playlist from the first up to the current track
    bool Lock(void);
    bool Unlock(void);
    virtual bool isLocked(void) const { return m_lock; };
    int Count(void);
    cAudioTune *Item(unsigned int index);
    cAudioTune *Add(cAudioTune *item);
    int Delete(int index);
    int Move(int dest, int src);
    bool Clear(void);
    int Contains(const cAudioTune *tune) const;
    int Contains(int songId);
#if defined(PLUGIN_DAAP)
    cMediaDatabase *Database(void) const { return mpo_parent; };
#elif defined(PLUGIN_CDDA)
    cCddaDisc *Disc(void) const { return mpo_parent; };
#endif
};

#if defined(PLUGIN_DAAP)

class cAudioPlaylists {
  private:
    cMediaDatabase *mpo_parent;
  protected:
    cDynamicArray<cAudioPlaylist *> mo_pls;
  public:
    cAudioPlaylists(cMediaDatabase *parent);
    virtual ~cAudioPlaylists();
    int Count(void) const { return mo_pls.Count(); };
    cAudioPlaylist *Item(unsigned int index) const { return mo_pls.Item(index); };
    // Add() takes ownership of list
    cAudioPlaylist *Add(cAudioPlaylist *list) { return mo_pls.Add(list); };
    virtual int Delete(int index) { return mo_pls.Delete(index); };
    int Contains(cAudioPlaylist *list) const;
    cMediaDatabase *Database(void) const { return mpo_parent; };
};

#endif // PLUGIN_DAAP
#endif // __AUDIOPLAYLIST_H
