#ifndef __PlayList__H
#define __PlayList__H

#include <stdbool.h>
#include "Media.h"
#include "MetaData.h"

// Config types in extra to MediaCfg
#define PlayList_CfgAutoStart   256
#define PlayList_CfgSeekable    257

struct Player;
struct PlayList_Cmds;

typedef struct PlayList
{
	int                    nr_tracks;
	const struct PlayList_Cmds*  pcmds;
	MediaObject*           m_pObject;
	struct Player*         m_pPlayer;
	unsigned int           m_Volume;
	const char*            m_pName;
	MediaPosition          m_Position;
} PlayList;

typedef bool (*FPlayList_Init)(PlayList* pPlayList, bool identify);
typedef int (*FPlayList_GetTrackList)(PlayList* pPlayList, const void*** ptracks, bool list, unsigned int shuffle);
typedef const char* (*FPlayList_GetText)(PlayList* pPlayList, void* ptrack, EMetaId id);
typedef bool (*FPlayList_PrepTrack)(PlayList* pPlayList,void* ptrack);
typedef bool (*FPlayList_PlayTrack)(PlayList* pPlayList,void* ptrack);
typedef Media_Status (*FPlayList_GetStatus)(PlayList* pPlayList);
typedef void (*FPlayList_SetLoopMode)(PlayList* pPlayList, Media_LoopMode mode);
typedef void (*FPlayList_Play)(PlayList* pPlayList, uint64_t pos);
typedef void (*FPlayList_Stop)(PlayList* pPlayList, bool bInError);
typedef int (*FPlayList_GetTrackNummer)(PlayList* pPlayList, void* ptrack);
typedef int (*FPlayList_GetModuleHandle)(PlayList* pPlayList, void* ptrack);
typedef void (*FPlayList_SetConfig)(PlayList* pPlayList, Media_Config type, const void* value);
typedef unsigned int (*FPlayList_GetConfig)(PlayList* pPlayList, Media_Config type);
typedef unsigned int (*FPlayList_GetUpdates)(PlayList* pPlayList);
typedef void (*FPlayList_GetPosition)(PlayList* pPlayList, void* ptrack, MediaPosition* pos);
typedef struct Player* (*throw_FPlayList_CreatePlayer)(PlayList* pPlayList);
typedef void (*FPlayList_DeletePlayer)(PlayList* pPlayList);

typedef struct PlayList_Cmds
{
	FPlayList_Init                  pInit;
	FPlayList_GetTrackList          pGetTrackList;
	FPlayList_GetText               pGetText;
	FPlayList_PrepTrack             pPrepTrack;
	FPlayList_PlayTrack             pPlayTrack;
	FPlayList_GetStatus             pGetStatus;
	FPlayList_SetLoopMode           pSetLoopMode;
	FPlayList_Play                  pPlay;
	FPlayList_Stop                  pStop;
	FPlayList_GetPosition           pGetPosition;
	FPlayList_GetTrackNummer        pGetTrackNummer;
	FPlayList_GetModuleHandle       pGetModuleHandle;
	FPlayList_SetConfig             pSetConfig;
	FPlayList_GetConfig             pGetConfig;
	FPlayList_GetUpdates            pGetUpdates;
	throw_FPlayList_CreatePlayer    pthrow_CreatePlayer;
	FPlayList_DeletePlayer          pDeletePlayer;
} PlayList_Cmds;

void throw_PlayList_PlayList(PlayList* pPlayList, const PlayList_Cmds* pcmds, const char* pName, MediaObject* pObject);
void PlayList_NotPlayList(PlayList* pPlayList);
bool PlayList_Init(PlayList* pPlayList, bool identify);
int PlayList_GetTrackList(PlayList* pPlayList, const void*** ptracks, bool list, unsigned int shuffle);
const char* PlayList_GetText(PlayList* pPlayList, void* ptrack, EMetaId id);
bool PlayList_PrepTrack(PlayList* pPlayList, void* ptrack);
bool PlayList_PlayTrack(PlayList* pPlayList, void* ptrack);
Media_Status PlayList_GetStatus(PlayList* pPlayList);
int PlayList_GetVolume(PlayList* pPlayList);
void PlayList_Seek(PlayList* pPlayList, EMedia_Seek set);
void PlayList_SetLoopMode(PlayList* pPlayList, Media_LoopMode mode);
void PlayList_SetVolume(PlayList* pPlayList, int volume);
void PlayList_RefreshParams(PlayList* pPlayList);
void PlayList_Play(PlayList* pPlayList, uint64_t pos);
void PlayList_SetStop(PlayList* pPlayList, bool bInError);
void PlayList_SetPause(PlayList* pPlayList, bool on);
void PlayList_GetPosition(PlayList* pPlayList, void* ptrack, MediaPosition* pos);
int PlayList_GetTrackNummer(PlayList* pPlayList, void* ptrack);
int PlayList_GetModuleHandle(PlayList* pPlayList, void* ptrack);
int PlayList_GetHardwareType(PlayList* pPlayList);
unsigned int PlayList_GetUpdates(PlayList* pPlayList);
void PlayList_ReportError(PlayList* This);
struct Player* throw_PlayList_EnsurePlayer(PlayList* This, bool bForce);

void throw_PlayLists_PlayLists(void);
void PlayLists_NotPlayLists(void);
int PlayLists_Count(void);
void throw_PlayLists_Add(PlayList* plist);
PlayList* PlayLists_Get(int i);
struct Player* PlayLists_GetPlayer(int i);
int PlayLists_Find(PlayList* plist);

#endif
