#if ! defined SEQ66_QT5_HELPERS_HPP
#define SEQ66_QT5_HELPERS_HPP

/*
 *  This file is part of seq66.
 *
 *  seq66 is free software; you can redistribute it and/or modify it under the
 *  terms of the GNU General Public License as published by the Free Software
 *  Foundation; either version 2 of the License, or (at your option) any later
 *  version.
 *
 *  seq66 is distributed in the hope that it will be useful, but WITHOUT ANY
 *  WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with seq66; if not, write to the Free Software Foundation, Inc., 59 Temple
 *  Place, Suite 330, Boston, MA  02111-1307  USA
 */

/**
 * \file          qt5_helpers.hpp
 *
 *  This module declares/defines some helpful free functions to support Qt and
 *  C++ integration.
 *
 * \library       seq66 application
 * \author        Chris Ahlstrom
 * \date          2018-03-14
 * \updates       2026-08-05
 * \license       GNU GPLv2 or above
 *
 * Note:
 *
 *      We moved some #includes to here to avoid SFINAE warning with
 *      Qt using gcc 16.
 *
 *      class QAction;
 *      class QComboBox;
 *      class QIcon;
 *      class QInputEvent;
 *      class QKeyEvent;
 *      class QLabel;
 *      class QLayoutItem;
 *      class QLineEdit;
 *      class QMenu;
 *      class QMouseEvent;
 *      class QPushButton;
 *      class QScrollArea;
 *      class QSpinBox;
 *      class QTimer;
 *      class QWidget;
 */

#include <QAction>
#include <QComboBox>
#include <QColor>
#include <QErrorMessage>
#include <QFileDialog>                  /* prompt for full MIDI file's path */
#include <QIcon>
#include <QInputDialog>                 /* prompt for a simple string       */
#include <QLabel>
#include <QLayout>
#include <QLayoutItem>
#include <QLineEdit>
#include <QKeyEvent>
#include <QMouseEvent>
#include <QMenu>
#include <QMessageBox>
#include <QPalette>
#include <QPushButton>
#include <QRegularExpression>           /* SFINAE?                          */
#include <QScrollArea>
#include <QScrollBar>
#include <QSpinBox>
#include <QStandardItemModel>
#include <QTimer>
#include <QToolTip>

#include "ctrl/keymap.hpp"              /* seq66::qt_modkey_ordinal()       */
#include "ctrl/keystroke.hpp"           /* seq66::keystroke wrapper class   */
#include "qt5_helper.h"                 /* Qt versioning macros             */

/*
 *  Currently disabled because it's nearly impossible to get the absolute
 *  position of the mouse correct with multiple monitors.
 */

#undef  SEQ66_SHOW_GENERIC_TOOLTIPS

/**
 *  The install_scroll_filter_function is currently unused.
 */

#undef  SEQ66_INSTALL_SCROLL_FILTER

namespace seq66
{

class combolist;

/*
 *  Free constants in the seq66 namespace.  These values are simply visible
 *  booleans for using file dialogs.
 */

const bool SavingFile { true };
const bool OpeningFile { false };
const bool ConfigFile { true };
const bool NormalFile { false };

/**
 *  Sets the default size for QActions and QMenus. Here, it is set
 *  to match what Qt specifies by default. This is the font size in
 *  points (pt). Actually, after some consideration, set it to
 *  zero to avoid changing the font size, but keep the feature around
 *  just in case.
 */

const int c_menu_action_font_size { 0 };

/*
 * Free functions in the seq66 namespace.
 */

extern std::string qt_get_color (QPushButton * button);
extern std::string qt_set_color
(
    const std::string & colorname, QPushButton * button
);
extern void qt_set_icon (const char * pixmap_array [], QPushButton * button);
extern std::string qt_icon_theme ();
extern bool qt_prompt_ok
(
    const std::string & text,
    const std::string & info
);
extern void qt_info_box (QWidget * self, const std::string & msg);
extern void qt_error_box (QWidget * self, const std::string & msg);
extern std::string qt_get_string
(
    QWidget * self,
    const std::string & title,
    const std::string & label,
    const std::string & text = ""
);
extern keystroke qt_keystroke
(
    QKeyEvent * event,
    keystroke::action rp,
    bool testing = false
);
extern QString qt (const std::string & text);

/*
 * See qt5_helper.h for these macros.
 */

#if defined QT_VERSION_L58                              /* see qt5_helper.h */
#error Qt less than 5.8 is not supported.
#endif

extern int qt_mouse_x (QMouseEvent * ev);
extern int qt_mouse_y (QMouseEvent * ev);

#if defined QT_VERSION_7                                /* see qt5_helper.h */
#error Qt 7 is not supported.
#endif

extern void qt_set_layout_visibility (QLayoutItem * item, bool visible);
extern QTimer * qt_timer
(
    QObject * self,
    const std::string & name,
    int redraw_factor,
    const char * slotname
);
extern void enable_combobox_item
(
    QComboBox * box, int index, bool enabled = true
);
extern void set_combobox_item
(
    QComboBox * box, int index,
    const std::string & text
);
extern bool populate_midich_combo
(
    QComboBox * combo,
    int buss, int channel,
    bool add_free = true
);
extern bool fill_combobox
(
    QComboBox * box,
    const combolist & clist,
    const std::string & value   = "",
    const std::string & prefix  = "",
    const std::string & suffix  = ""
);

#if defined SEQ66_INSTALL_SCROLL_FILTER
extern bool install_scroll_filter (QWidget * monitor, QScrollArea * target);
#endif

extern void set_spin_value (QSpinBox * spin, int value);
extern QAction * new_qaction
(
    const std::string & text,
    const QIcon & micon,
    int fontsize = c_menu_action_font_size
);
extern QAction * new_qaction
(
    const std::string & text,
    QObject * parent,
    int fontsize = c_menu_action_font_size
);
extern QMenu * new_qmenu
(
    const std::string & text,
    QWidget * parent = nullptr,
    int fontsize = c_menu_action_font_size
);
extern bool show_open_midi_file_dialog (QWidget * parent, std::string & file);
extern bool show_import_midi_file_dialog (QWidget * parent, std::string & file);
extern bool show_select_project_dialog
(
    QWidget * parent,
    std::string & selecteddir,
    std::string & selectedfile
);
extern bool show_playlist_dialog
(
    QWidget * parent,
    std::string & file,
    bool saving
);
extern bool show_text_file_dialog (QWidget * parent, std::string & file);
extern bool show_exe_file_dialog (QWidget * parent, std::string & file);
extern bool show_file_dialog
(
    QWidget * parent,
    std::string & selectedfile,
    const std::string & prompt      = "",
    const std::string & filterlist  = "",
    bool saving                     = false,
    bool forceconfig                = false,
    const std::string & extension   = "",
    bool promptoverwrite            = true
);
extern bool show_file_select_dialog
(
    QWidget * parent,
    const std::string & extension,
    std::string & selecteddir,
    std::string & selectedfile
);
extern bool show_folder_dialog
(
    QWidget * parent,
    std::string & selectedfolder,
    const std::string & prompt      = "",
    bool forcehome                  = false
);
extern void tooltip_with_keystroke
(
    QWidget * widget,
    const std::string & keyname,
    int duration = -1
);
extern void tooltip_for_filename
(
    QLineEdit * lineedit,
    const std::string & filespec,
    int duration = -1
);

#if defined SEQ66_SHOW_GENERIC_TOOLTIPS

extern void generic_tooltip
(
    QWidget * widget,
    const std::string & tiptext,
    int x, int y,
    int msduration = -1
);

#endif

extern bool is_empty (const QLineEdit * lineedit);
extern bool qlabel_change_color (QLabel * qlabel, const std::string & color);

}               // namespace seq66

#endif          // SEQ66_QT5_HELPERS_HPP

/*
 * qt5_helpers.hpp
 *
 * vim: sw=4 ts=4 wm=4 et ft=cpp
 */

