#pragma once
// instrument_drop_win — the REAPER-facing shell half of drop-and-load: (a) resolves
// a screen point to a track + its FX-surface hotspot via REAPER's hit-test API, and
// (b) on release adds a ReaSampler 9000 instance and applies the dragged capture as
// its component state via a temp .vstpreset + TrackFX_SetPreset (the earlier
// "vst_chunk" named-config-parm write was silently unappliable for VST3 — don't
// revert to it). The pure gesture decision lives in drag_out; the pure payload
// construction in instrument_drop.
//
// LOAD-BEARING: an EXPLICIT user placement-of-the-player gesture — adds a READER of
// the bank on a track, pointed at an already-captured sample. NEVER captures, NEVER
// writes the bank, NEVER inserts a timeline item (the drag's arrange outcome is a
// separate shell, arrange_drop_win). The only writes are a new FX instance + its
// component state, both wrapped in one undo block (one Ctrl-Z), plus a transient
// .vstpreset deleted before returning.

#include <cstdint>
#include <vector>

#include "core/ui/drag_out.h"  // ReaperSurface

// Declared as a class (matching reaper_plugin.h) so the mangled name agrees, without
// pulling in the SDK.
class MediaTrack;

namespace reasampler {

// One evaluation of what sits under a screen point. Carries no verdict — the pure law
// (ui::decideDropClass) turns this plus the payload size into an outcome.
struct DropProbe {
    MediaTrack* track = nullptr;  // the track under the pointer (null if none / not a track)
    ui::ReaperSurface surface = ui::ReaperSurface::OffReaper;
};

// Wraps GetThingFromPoint and hands its (info string, track) pair to the pure
// wire::classifyReaperSurface. Cheap enough to run on every mouse-move, but the panel
// evaluates it only OUTSIDE its own client rect — the internal drag never pays for it.
DropProbe probeDropTarget(int screenX, int screenY);

// Adds a fresh ReaSampler 9000 instance to `track` and applies `presetBytes` as its
// component state. Wraps add + apply in one REAPER undo block. All-or-nothing: if
// the preset apply fails after a successful add, the FX instance is removed via
// TrackFX_Delete before returning false, leaving the track exactly as it was.
bool performInstrumentDrop(MediaTrack* track, const std::vector<std::uint8_t>& presetBytes);

// Same all-or-nothing add+apply contract as performInstrumentDrop but does NOT open
// its own undo block — the caller owns the undo grouping so persist + FX-add + apply
// collapses to one Ctrl-Z. The shared inner half performInstrumentDrop wraps.
bool loadInstrumentOntoTrack(MediaTrack* track, const std::vector<std::uint8_t>& presetBytes);

}  // namespace reasampler
