// Copyright (c) 2022 Giorgos Vougioukas
//
// The license can be found in the LICENSE file.

#ifndef _THA_PLAYLIST_H_
#define _THA_PLAYLIST_H_

#include "thalia/definitions.h"

#include "WDL/assocarray.h"
#include "WDL/wdlstring.h"
#include "WDL/ptrlist.h"
#include "WDL/mutex.h"

#define THA_PL_INTEGRITY 1

class THA_PlayList
{
public:
  THA_PlayList();
  ~THA_PlayList();

  void AddFilepath(const char *filepath);
  bool AddFilepathDirectly(const char *filepath);
  void AddUserFilepath(const char *filepath);
  bool AddURL(const char *url);
  void DeleteAllFilepaths();

  void MoveSelection(WDL_TypedBuf<int> *selection, int destination);
  void RemoveSelection(WDL_TypedBuf<int> *selection);
  void RemoveIndex(int index);
  void Sort(int subitem, bool reverse, bool selected, WDL_TypedBuf<int> *selection);
  void ReverseSelection(WDL_TypedBuf<int> *selection);
  void RandomizeSelection(WDL_TypedBuf<int> *selection);
  void DeleteAll();
  void Reload();
  void CutSelection(WDL_TypedBuf<int> *selection);
  void CopySelection(WDL_TypedBuf<int> *selection);
  void Paste(int destination);
  int GetPasteSize() const;
  WDL_INT64 GetClipboardBytes() const;
  void CopyFilepaths(WDL_PtrList<WDL_FastString> *filepath);
  void CopyUserFilepaths(WDL_PtrList<WDL_FastString> *filepath);
  double GetLength(WDL_TypedBuf<int> *selection);
  double GetSizeMB(WDL_TypedBuf<int> *selection);

  struct TitlePath
  {
    WDL_FastString title;
    WDL_FastString path;
  };

  typedef WDL_PtrList<TitlePath> Title;
  typedef WDL_StringKeyedArray<Title *> UserPlayLists;

  bool HasUserPlayList(const char *name);
  void SaveUserPlayList(const char *name);
  THA_PlayList::UserPlayLists *GetUserPlayLists();
  void RenameUserPlayList(const char *name, const char *new_name);
  void DeleteUserPlayList(const char *name);
  void DeleteAllUserPlayLists();

  struct PlayListEntry
  {
    int active;
    WDL_FastString type;
    WDL_FastString title;
    WDL_FastString artist;
    WDL_FastString album;
    double length;
    WDL_FastString genre;
    double srate;
    WDL_FastString filename;
    WDL_FastString filepath;
    WDL_FastString fileext;
    WDL_INT64 filesize;
    WDL_FastString comment;
  };

  bool WantPlayList();
  void DoneWithPlayList();
  WDL_PtrList<PlayListEntry> *GetPlayList() const;

  bool WantRefresh();
  void DoneWithRefresh();
  int GetRefreshStart() const { return m_refreshstart; }
  int GetRefreshEnd() const { return m_refreshend; }

  struct ActiveEntry
  {
    int pos;
    WDL_FastString filepath;
  };

  void SetActiveEntry(int position);
  void GetActiveEntry(ActiveEntry *active_entry);
  const char *GetNextActiveFilepath();

  WDL_PtrList<PlayListEntry> *GetClipboard() const;

#if defined(THA_PL_INTEGRITY) && defined(_DEBUG)
  void LockEnter() { m_mutex.Enter(); }
  void LockLeave() { m_mutex.Leave(); }
#endif

private:
  void SavePlayList();
  void LoadPlayList();
  void AskForRefresh();
  void AskForPlayList();

  WDL_PtrList<PlayListEntry> *m_entries;
  WDL_PtrList<PlayListEntry> *m_clip;

  WDL_Mutex m_mutex;
  bool m_wantplaylist;
  bool m_wantrefresh;
  int m_refreshstart;
  int m_refreshend;
  ActiveEntry m_active;

  THA_PlayList::UserPlayLists *m_userplaylists;
  WDL_FastString m_strbuf;
};

#endif // _THA_PLAYLIST_H_
