// drag_out — pure implementation. See drag_out.h.

#include "core/ui/drag_out.h"

#include <unordered_set>

namespace reasampler::ui {

namespace {

bool insideClient(int px, int py, const PanelClientRect& c) {
    return px >= c.x && px < c.x + c.width &&
           py >= c.y && py < c.y + c.height;
}

} // namespace

DragGesture decideGesture(int px, int py, const PanelClientRect& client,
                          const DragState& state) {
    if (!state.dragging || !state.hasArmedSamples) return DragGesture::None;
    if (insideClient(px, py, client)) return DragGesture::Internal;
    // Outside the client: a single-capture drag still over REAPER's own UI is an instrument
    // drop; anything else (multi-capture, or pointer off REAPER entirely) is an OS drag-out.
    if (state.singleCapture && state.overReaperUi) return DragGesture::InstrumentDrop;
    return DragGesture::OsDrag;
}

PathList assemblePathList(const std::vector<ResolvedSample>& resolved) {
    PathList out;
    std::unordered_set<std::string> seen;
    seen.reserve(resolved.size());

    for (const ResolvedSample& s : resolved) {
        if (s.absolutePath.empty()) {
            ++out.skippedUnresolved;
            continue;
        }
        if (!s.fileExists) {
            ++out.skippedMissing;
            continue;
        }
        if (!seen.insert(s.absolutePath).second) {
            ++out.skippedDuplicate;
            continue;
        }
        out.paths.push_back(s.absolutePath);
    }
    return out;
}

OsHandoff decideOsHandoff(const std::vector<std::string>& paths) {
    OsHandoff out;
    out.handOffToOs = !paths.empty();
    return out;
}

} // namespace reasampler::ui
