/**********************************************************************

  Audacity: A Digital Audio Editor

  VSTEditor.h

  Dominic Mazzoni

  Paul Licameli split from VSTEffect.h

**********************************************************************/

#ifndef __AUDACITY_VST_EDITOR__
#define __AUDACITY_VST_EDITOR__

#include "VSTWrapper.h"
#include "../EffectEditor.h"

#include <wx/dialog.h>
#include <wx/event.h>
#include <wx/weakref.h>

class VSTInstance;
class wxSlider;
class wxStaticText;
class NumericTextCtrl;
class VSTControl;

class VSTTimer;

class VSTEditor final
   : public wxEvtHandler
   , public EffectEditor
   , public VSTUIWrapper
{
public:

   VSTEditor(VSTInstance&       instance, EffectType type, bool gui,
      const EffectUIServices&  services,
      EffectSettingsAccess&    access,
      wxWindow*                pParent,
      int                      numParams
   );

   ~VSTEditor() override;

   VSTInstance& GetInstance() const;

   bool ValidateUI() override;
   bool UpdateUI() override;

   void OnClose() override;

   void BuildPlain(EffectSettingsAccess& access, EffectType effectType, double projectRate);
   void BuildFancy(EffectInstance& instance);

   void OnTimer();

   std::unique_ptr<VSTTimer> mTimer;

   void RefreshParameters(int skip = -1) const;

   void Automate(int index, float value) override;

   void OnSlider(wxCommandEvent& evt);

   int ShowDialog(bool nonModal);

   bool IsGraphicalUI() override;

   void Flush() override;

protected:
   void SizeWindow(int w, int h) override;

private:
   void NotifyParameterChanged(int index, float value);
   void OnIdle(wxIdleEvent &evt);

   VSTInstance& mInstance;
   const EffectType mType;
   const bool mGui;

   bool FetchSettingsFromInstance(EffectSettings& settings);
   bool StoreSettingsToInstance(const EffectSettings& settings);
   void NeedEditIdle(bool state);
   void NeedIdle() override;
   void Idle() override;

   void OnSizeWindow(wxCommandEvent& evt);

   int  mTimerGuard{ 0 };

   bool mWantsEditIdle{ false };
   bool mWantsIdle{ false };

   // Remembers last slider movements until idle time
   std::vector<std::pair<int, double>> mLastMovements{};

   ArrayOf<wxStaticText*> mNames;
   ArrayOf<wxSlider*> mSliders;
   ArrayOf<wxStaticText*> mDisplays;
   ArrayOf<wxStaticText*> mLabels;
   NumericTextCtrl* mDuration;

   wxWindow* mParent;
   wxWeakRef<wxDialog> mDialog;

   VSTControl* mControl{};

   // Mapping from parameter ID to string
   std::vector<wxString> mParamNames;

   int mNumParams{ 0 };
};

#endif
