#pragma once

#include <plugin_base/shared/value.hpp>
#include <plugin_base/shared/utility.hpp>
#include <plugin_base/dsp/block/shared.hpp>

#include <Client/libMTSClient.h>
#include <vector>
#include <cstdint>

namespace plugin_base {

enum class note_event_type { on, off, cut };
  
// once per block automation
struct block_event final {
  int param;
  normalized_value normalized;
};

// midi automation
struct midi_event final {
  // midi_source_id
  int id;
  int frame;
  normalized_value normalized;
};

// sample accurate automation
struct accurate_event final {
  int frame;
  int param;
  bool is_mod; // is_mod = clap nondestructive
  double value_or_offset; // [0, 1] automation value or [-1, 1] mod value
};

// keyboard event
struct note_event final {
  int frame;
  note_id id;
  float velocity;
  note_event_type type;
};

// these are translated to curves/values
struct host_events final {
  std::vector<midi_event> midi;
  std::vector<note_event> notes;
  std::vector<block_event> block;
  std::vector<accurate_event> accurate_automation;
  std::vector<accurate_event> accurate_modulation;
  // regular output params eg cpu usage, needs registering output params by the module
  std::vector<block_event> output_params;
  // lfo / env / parameter modulation outputs
  std::vector<modulation_output> modulation_outputs;

  // plugin_engine interpolates these as one
  std::vector<accurate_event> accurate_automation_and_modulation;

  void deactivate();
  void activate(bool graph, int module_count, int param_count, int midi_count, int polyphony, int max_frame_count);
  PB_PREVENT_ACCIDENTAL_COPY_DEFAULT_CTOR(host_events);
};

// shared block, note/automation events, host audio out
struct host_block final {
  int frame_count;
  host_events events;
  shared_block shared;
  float* const* audio_out;

  // MTS-ESP support
  MTSClient* mts_client = {};

  void prepare();
  PB_PREVENT_ACCIDENTAL_COPY_DEFAULT_CTOR(host_block);
};

}