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

#ifndef _RSI_RENDER_SYSTEM_H_
#define _RSI_RENDER_SYSTEM_H_

#include "RSI/definitions.h"
#include "RSI/buffer_queue.h"
#include "RSI/preferences.h"
#include "RSI/plugin.h"

#include "WDL/mutex.h"
#include "WDL/heapbuf.h"
#include "WDL/wdlstring.h"

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

  void LoadFileTrack(const char *filename);

  void SetActiveTrack(int track);
  bool IsTrackAvailable() const;
  bool IsTrackActive() const;
  int GetActiveTrack() const;

  void DecreaseShift(bool altstep = false);
  void IncreaseShift(bool altstep = false);
  void DecreaseTempo(bool altstep = false);
  void IncreaseTempo(bool altstep = false);
  void ResetShiftTempo();

  void Pause();
  void Rewind(bool state);
  void FastForward(bool state);
  void Play(); void PlayReverse();
  void Stop();
  void StartStop(bool state);

  void Seek(double time);

  void ToggleRepeat();
  void ToggleReversePlayback();
  void ToggleHeadphone();

  void IncreaseVolume();
  void DecreaseVolume();
  void SetVolume(double db);

  void EjectTrack(int track);
  void EjectEverything();

  void GetInfo(WDL_PtrList<WDL_FastString> **desc,
    WDL_PtrList<WDL_FastString> **info);

  bool IsLoadingInProgress() const;
  int LoadingProgress() const;
  void AbortLoading();

  void StartThread();
  void StopThread();
  bool IsRunning() const;

  void AudioStreamerData(WDL_TypedBuf<SAM> *output, int frame_count, int nch);
private:
  static unsigned int WINAPI RenderingThreadFunction(void *arg);
  static unsigned int WINAPI LoadingThreadFunction(void *arg);
  int Rendering();
  int Loading();

  struct ThreadDetails
  {
    unsigned int id;
    HANDLE thread;
  };

  WDL_TypedBuf<ThreadDetails> m_renderthreads;
  bool m_killrenderthread;
  WDL_Mutex m_rendermutex;

  WDL_TypedBuf<ThreadDetails> m_loadthreads;
  bool m_killloadthread;
  WDL_Mutex m_loadmutex;

  int m_activetrack;

  double m_shiftstep;
  double m_tempostep;
  double m_shiftaltstep;
  double m_tempoaltstep;

  enum
  {
    TRACKNUM = 0,
    TRACKTIME,
    TRACKTITLE,
    TRACKARTIST,
    TRACKACTIVE,
    TRACKLOADED,
    TRACKPITCHSHIFT,
    TRACKTIMESTRETCH,
    TRACKREPEAT,
    TRACKVOLUME,
    TRACKEMPTYLINE,
    TRACKR128,
    TRACKREFERENCE,
    TRACKMOMENTARY,
    TRACKSHORTTERM,
    TRACKINTEGRATED,
    TRACKRANGE,
    TRACKSAMPLEPEAK,
    TRACKTRUEPEAK,
    TRACKGAIN,
    TRACKNORMALIZATION,
    TRACKMAX
  };

  WDL_PtrList<WDL_FastString> m_desc;
  WDL_PtrList<WDL_FastString> m_info;

  RSI_IFileInput *m_fi;
  int m_loadprogress;
  bool m_abortloading;
  bool m_running;
};

#endif // _RSI_RENDER_SYSTEM_H_
