#pragma once

#include <fluidsynth.h>
#include <vector>
#include <string>
#include <array>

#include "midi.h"

namespace {
constexpr int NUM_MIDI_CHANNELS = 2;
}

typedef std::array<double, NUM_MIDI_KEYS> TuningFrequencies;

/**
 * C++ wrapper around the fluidsynth API.
 */
class Synth {
public:
    Synth();
    ~Synth();

    struct Soundfont {
        std::string name;
        int id;
    };

    struct Program {
        std::string name;
        int soundfontId;
        int bankNumber;
        int programNumber;
    };

    bool loadSoundfont(const std::string& filepath);
    bool loadProgram(const Program& program);

    bool setTuning(const TuningFrequencies& frequencies);
    bool resetTuning();

    const std::vector<Program>& getPrograms() const;

    // TODO JMT: remove this
    fluid_synth_t* getSynth();

private:
    bool activateTuning();

    std::vector<Soundfont> soundfonts;
    std::vector<Program> programs;

    fluid_settings_t* settings = NULL;
    fluid_synth_t* synth = NULL;
    fluid_audio_driver_t* adriver = NULL;
};


// Fluid logging redirector.
void fluid_log_function(int level, const char* message, void* data);
void redirect_fluid_logs();
