// native_bridge/include/Vst3Instrument.h
// VST3 host instrument (A7). Compiled ALWAYS; the real vst3sdk wiring is
// inside #ifdef HAVE_VST3SDK (set by CMake when the vst3sdk submodule is
// present). Without the SDK the class degrades to a no-op stub so the bridge
// still builds for SF2/SF3/SFZ.
#ifndef VST3_INSTRUMENT_H
#define VST3_INSTRUMENT_H

#include "INativeInstrument.h"

#include <string>

class Vst3Instrument : public INativeInstrument {
public:
    Vst3Instrument();
    ~Vst3Instrument() override;

    bool loadPlugin(const std::string& path, double sampleRate);

    bool init(double sampleRate, uint32_t maxBlockSize) override;
    void selectProgram(uint32_t channel, uint32_t bank, uint32_t program) override;
    void noteOn(uint32_t channel, uint32_t pitch, float velocity, uint32_t sampleOffset) override;
    void noteOff(uint32_t channel, uint32_t pitch, uint32_t sampleOffset) override;
    void controlChange(uint32_t channel, uint32_t cc, uint32_t value) override;
    void programChange(uint32_t channel, uint32_t program) override;
    void pitchBend(uint32_t channel, uint32_t bend14) override;
    bool openGUI(void* parentWindowHandle) override;
    bool reloadForGUI() override;
    bool attachView(void* parentWindowHandle) override;
    void closeGUI() override;
    bool needsReload() const override { return hasAttachedOnce_ && !guiAttached_; }
    void setReloading(bool on) override { reloading_ = on; }
    void processAudioBlock(float* outputL, float* outputR, uint32_t numSamples) override;

private:
    // pimpl: all Steinberg SDK types live in Vst3Instrument.cpp (Vst3HostState).
    void* state_;
    std::string path_;
    double sampleRate_;
    uint32_t maxBlockSize_;
    bool loaded_;
    bool guiAttached_;
    bool hasAttachedOnce_;
    bool reloading_; // guarded by InstrumentEngineManager::mu_ (set via setReloading)
    bool reload();
};

#endif // VST3_INSTRUMENT_H
