#include "dialog.hpp"

#ifdef _WIN32
  #include <windows.h>
#elif __unix__
#else
  #include "log.hpp"
  #include "strings.hpp"
  #include "toast.hpp"
#endif

#include <cstdlib>
#include <cstring>
#include <format>

#include "path.hpp"

using namespace anm2ed::util;

namespace anm2ed
{
  static void callback(void* userData, const char* const* filelist, int filter)
  {
    auto self = (Dialog*)(userData);

    if (filelist && filelist[0] && strlen(filelist[0]) > 0)
    {
      self->paths.clear();
      for (int i = 0; filelist[i] && strlen(filelist[i]) > 0; ++i)
        self->paths.push_back(path::from_utf8(filelist[i]));
      self->path = self->paths.empty() ? std::filesystem::path{} : self->paths.front();
      self->selectedFilter = filter;
    }
    else
    {
      self->selectedFilter = -1;
      self->path.clear();
      self->paths.clear();
    }
  }

  Dialog::Dialog(SDL_Window* window)
  {
    *this = Dialog();
    this->window = window;
  }

  void Dialog::file_open(Type type, bool isMany)
  {
    if (type == Dialog::NONE) return;
    path.clear();
    paths.clear();
    SDL_ShowOpenFileDialog(callback, this, window, FILTERS[TYPE_FILTERS[type]], std::size(FILTERS[TYPE_FILTERS[type]]),
                           nullptr, isMany);
    this->type = type;
  }

  void Dialog::file_save(Type type)
  {
    if (type == Dialog::NONE) return;
    path.clear();
    paths.clear();
    SDL_ShowSaveFileDialog(callback, this, window, FILTERS[TYPE_FILTERS[type]], std::size(FILTERS[TYPE_FILTERS[type]]),
                           nullptr);
    this->type = type;
  }

  void Dialog::folder_open(Type type)
  {
    if (type == Dialog::NONE) return;
    path.clear();
    paths.clear();
    SDL_ShowOpenFolderDialog(callback, this, window, nullptr, false);
    this->type = type;
  }

  void Dialog::file_explorer_open(const std::filesystem::path& path)
  {
    if (path.empty()) return;
#ifdef _WIN32
    ShellExecuteW(nullptr, L"open", path.native().c_str(), nullptr, nullptr, SW_SHOWNORMAL);
#elif __unix__
    auto pathUtf8 = path::to_utf8(path);
    system(std::format("xdg-open \"{}\" &", pathUtf8).c_str());
#else
    toasts.push(localize.get(TOAST_NOT_SUPPORTED));
    logger.warning(localize.get(TOAST_NOT_SUPPORTED, anm2ed::ENGLISH));
#endif
  }

  void Dialog::reset() { *this = Dialog(this->window); }

  bool Dialog::is_selected(Type type) const { return this->type == type && !paths.empty(); }

};
