/*
 Copyright (c) 2026 - SD-Innovation S.A.S. - FRANCE
*/

/*
ver: 2.x.x - build: 2026-04-28
*/

/*
The zlib License

Copyright (c) 2026 SD-Innovation S.A.S.

This software is provided ‘as-is’, without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.

Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:

1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.

2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.

3. This notice may not be removed or altered from any source
distribution.
*/

#pragma once

#include <vector>
#include <wx/wx.h>

namespace sdi_toolBox::desktop::wxWidgets
{
//--------------------------------------------------------------
/**
 * @brief Manages a list of file wildcard entries for use in wxWidgets file dialogs.
 *
 * The Wildcard class provides a convenient way to build and format wildcard filter strings
 * compatible with wxWidgets file dialogs (e.g., `wxFileDialog`).
 *
 * Each entry consists of a human-readable description and a file pattern (e.g., `*.txt`).
 * The formatted string follows the wxWidgets wildcard format:
 * @code{.cpp}
 * "Description (*.ext)|*.ext|Other (*.other)|*.other"
 * @endcode
 *
 * @par Example
 * @code{.cpp}
 * sdi_toolBox::desktop::wxWidgets::Wildcard wc;
 * wc.addEntry("Text files", "*.txt");
 * wc.addEntry("CSV files", "*.csv");
 * wxString filter = wc.getWildcards(true);    // includes "All files (*.*)|*.*"
 * wxFileDialog dlg(this, "Open file", "", "", filter, wxFD_OPEN);
 * @endcode
 */
class Wildcard
{
  public:
  /**
   * @struct WildcardEntry
   * @brief Represents a single wildcard filter entry.
   */
  struct WildcardEntry
  {
    wxString description;     ///< Human-readable description of the file type (e.g., "Text files").
    wxString pattern;         ///< File pattern used for filtering (e.g., "*.txt").
  };

  public:
  /**
   * @brief Default constructor.
   */
  Wildcard() = default;

  /**
   * @brief Default destructor.
   */
  virtual ~Wildcard() = default;

  /**
   * @brief Copy constructor.
   * @param other The Wildcard instance to copy from.
   */
  Wildcard(const Wildcard &other) = default;

  /**
   * @brief Move constructor.
   * @param other The Wildcard instance to move from.
   */
  Wildcard(Wildcard &&other) noexcept = default;

  /**
   * @brief Copy assignment operator.
   * @param other The Wildcard instance to copy from.
   * @return Reference to this instance.
   */
  Wildcard &operator=(const Wildcard &other) = default;

  /**
   * @brief Move assignment operator.
   * @param other The Wildcard instance to move from.
   * @return Reference to this instance.
   */
  Wildcard &operator=(Wildcard &&other) noexcept = default;

  /**
   * @brief Removes all wildcard entries.
   */
  void clear();

  /**
   * @brief Adds a new wildcard filter entry.
   * @param description Human-readable description of the file type (e.g., "Text files").
   * @param pattern File pattern used for filtering (e.g., "*.txt").
   */
  void addEntry(const wxString &description, const wxString &pattern);

  /**
   * @brief Builds and returns the formatted wildcard string for use in wxWidgets file dialogs.
   * @param addAllFiles If @c true, appends an "All files (*.*)|*.*" entry at the end.
   * @return A formatted wildcard string compatible with wxWidgets file dialog filters.
   */
  [[nodiscard]] wxString getWildcards(bool addAllFiles = false) const;

  protected:
  std::vector<WildcardEntry> m_wildcards;     // List of wildcard strings
};
//--------------------------------------------------------------
/* Clear all wildcard entries */
inline void Wildcard::clear()
{
  m_wildcards.clear();
}
//--------------------------------------------------------------
/* Add a wildcard entry */
inline void Wildcard::addEntry(const wxString &description, const wxString &pattern)
{
  m_wildcards.push_back({ .description = description, .pattern = pattern });
}
//--------------------------------------------------------------
/* Get wildcard list */
inline wxString Wildcard::getWildcards(const bool addAllFiles) const
{
  wxString wildcardList;

  // Add wildcard entries to the list
  for (const auto &entry : m_wildcards)
  {
    if (!wildcardList.empty())
      wildcardList += _T("|");

    wildcardList += entry.description + _T(" (") + entry.pattern + _T(")|") + entry.pattern;
  }

  // Optionally add "All files" entry
  if (addAllFiles)
  {
    if (!wildcardList.empty())
      wildcardList += _T("|");

    wildcardList += _("All files") + _T(" (") + _T("*.*") + _T(")|") + _T("*.*");
  }

  return wildcardList;
}
//--------------------------------------------------------------
}     // namespace sdi_toolBox::desktop::wxWidgets
