// package_pickers.cpp — see package_pickers.h. GetUserFileName cannot be null here:
// main.cpp defines REAPERAPI_IMPLEMENT without REAPERAPI_MINIMAL, so the generated
// resolver walks the FULL table, and it aborts the extension load if any single name
// fails to resolve. A fallback picker would be unreachable code.

#include "shell/package/package_pickers.h"

#include <algorithm>
#include <cctype>

#define REAPERAPI_MINIMAL
#define REAPERAPI_WANT_GetUserFileName
#include "reaper_plugin_functions.h"

namespace reasampler {

namespace {

// GetUserFileName's documented pair format: label|pattern|label|pattern.
const char kExtList[] =
    "ReaSampler bank package (*.rsbank)|*.rsbank|All files (*.*)|*.*";

bool runPicker(int mode, const char* caption, const char* initial,
               std::string& outAbsPath) {
    outAbsPath.clear();
    char buf[4096];
    buf[0] = '\0';
    if (!GetUserFileName(mode, caption, initial, kExtList, buf,
                         static_cast<int>(sizeof(buf)))) {
        return false;
    }
    outAbsPath = buf;
    return !outAbsPath.empty();
}

bool hasCaseInsensitiveSuffix(const std::string& path, const std::string& suffix) {
    if (path.size() < suffix.size()) return false;
    return std::equal(suffix.rbegin(), suffix.rend(), path.rbegin(),
                      [](unsigned char a, unsigned char b) {
                          return std::tolower(a) == std::tolower(b);
                      });
}

}  // namespace

bool pickPackageForImport(std::string& outAbsPath) {
    return runPicker(1, "Import bank package", "", outAbsPath);
}

bool pickPackageSavePath(const std::string& suggestedPath, std::string& outAbsPath,
                         bool* outAppended) {
    // [verify — DAW] GetUserFileName takes no owner window, so the dialog's parenting
    // is REAPER's to do; the previous Win32 path passed GetMainHwnd() explicitly.
    if (!runPicker(0, "Export bank package", suggestedPath.c_str(), outAbsPath)) {
        return false;
    }
    // GetUserFileName has no lpstrDefExt equivalent (the old Win32 picker's
    // ofn.lpstrDefExt = L"rsbank"); whether mode 0 appends one itself from
    // kExtList is [verify — DAW], so append it ourselves whenever it's missing.
    const bool appended = !hasCaseInsensitiveSuffix(outAbsPath, ".rsbank");
    if (appended) outAbsPath += ".rsbank";
    if (outAppended) *outAppended = appended;
    return true;
}

}  // namespace reasampler
