///////////////////////////////////////////////////////////////////////////////
//
// wxFormBuilder - A Visual Dialog Editor for wxWidgets.
// Copyright (C) 2005 José Antonio Hurtado
//
// This program 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.
//
// This program 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 this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Written by
//   Andrea Zanellato - zanellato.andrea@gmail.com
//   based on original wizard.h include in wxWidgets source code
//
///////////////////////////////////////////////////////////////////////////////

#ifndef SDK_PLUGIN_INTERFACE_FORMS_WIZARD_H
#define SDK_PLUGIN_INTERFACE_FORMS_WIZARD_H

#include <vector>

#include <wx/wizard.h>

#include "wizardbase.h"


class WizardEvent;


class Wizard : public WizardBase
{
public:
    Wizard(
      wxWindow* parent, wxWindowID id = wxID_ANY, const wxPoint& pos = wxDefaultPosition,
      const wxSize& size = wxDefaultSize, long style = wxTAB_TRAVERSAL);
    ~Wizard() override;

    void SetBitmap(const wxBitmap& bitmap);
    void ShowHelpButton(bool showhelp) { m_btnHelp->Show(showhelp); }

    void AddPage(WizardPageSimple* page);
    WizardPageSimple* GetPage(size_t index) { return m_pages[index]; }
    size_t GetPageCount() const { return m_pages.size(); }
    size_t GetPageIndex(WizardPageSimple* wizpage) const;

    void SetSelection(size_t pageIndex);

protected:
    void OnBackOrNext(wxCommandEvent& event) override;
    void OnHelp(wxCommandEvent& event) override;
    void OnCancel(wxCommandEvent& event) override;

private:
    void OnWizEvent(WizardEvent& event);

private:
    std::vector<WizardPageSimple*> m_pages;
    WizardPageSimple* m_page;
};


// ----------------------------------------------------------------------------
// WizardEvent class represents an event generated by the wizard: this event
// is first sent to the page itself and, if not processed there, goes up the
// window hierarchy as usual
// ----------------------------------------------------------------------------
class WizardEvent : public wxNotifyEvent
{
public:
    explicit WizardEvent(
      wxEventType type = wxEVT_NULL, int id = wxID_ANY, bool direction = true, WizardPageSimple* page = nullptr);

    // for EVT_WXFB_WIZARD_PAGE_CHANGING, return true if we're going forward or
    // false otherwise and for EVT_WXFB_WIZARD_PAGE_CHANGED return true if we came
    // from the previous page and false if we returned from the next one
    // (this function doesn't make sense for CANCEL events)
    bool GetDirection() const { return m_direction; }
    WizardPageSimple* GetPage() const { return m_page; }

    wxEvent* Clone() const override { return new WizardEvent(*this); }

private:
    bool m_direction;
    WizardPageSimple* m_page;
};


// ----------------------------------------------------------------------------
// macros for handling WizardEvents
// ----------------------------------------------------------------------------
#define wxFBDLLIMPEXP

wxDECLARE_EXPORTED_EVENT(wxFBDLLIMPEXP, wxFB_EVT_WIZARD_PAGE_CHANGED, WizardEvent);
wxDECLARE_EXPORTED_EVENT(wxFBDLLIMPEXP, wxFB_EVT_WIZARD_PAGE_CHANGING, WizardEvent);
wxDECLARE_EXPORTED_EVENT(wxFBDLLIMPEXP, wxFB_EVT_WIZARD_CANCEL, WizardEvent);
wxDECLARE_EXPORTED_EVENT(wxFBDLLIMPEXP, wxFB_EVT_WIZARD_HELP, WizardEvent);
wxDECLARE_EXPORTED_EVENT(wxFBDLLIMPEXP, wxFB_EVT_WIZARD_FINISHED, WizardEvent);
wxDECLARE_EXPORTED_EVENT(wxFBDLLIMPEXP, wxFB_EVT_WIZARD_PAGE_SHOWN, WizardEvent);

using WizardEventFunction = void (wxEvtHandler::*)(WizardEvent&);
#define WizardEventHandler(func) wxEVENT_HANDLER_CAST(WizardEventFunction, func)
#define wxFB__DECLARE_WIZARDEVT(evt, id, fn) wx__DECLARE_EVT1(wxFB_EVT_WIZARD_##evt, id, WizardEventHandler(fn))

// notifies that the page has just been changed (can't be vetoed)
#define EVT_WXFB_WIZARD_PAGE_CHANGED(id, fn) wxFB__DECLARE_WIZARDEVT(PAGE_CHANGED, id, fn)

// the user pressed "<Back" or "Next>" button and the page is going to be
// changed - unless the event handler vetoes the event
#define EVT_WXFB_WIZARD_PAGE_CHANGING(id, fn) wxFB__DECLARE_WIZARDEVT(PAGE_CHANGING, id, fn)

// the user pressed "Cancel" button and the wizard is going to be dismissed -
// unless the event handler vetoes the event
#define EVT_WXFB_WIZARD_CANCEL(id, fn) wxFB__DECLARE_WIZARDEVT(CANCEL, id, fn)

// the user pressed "Finish" button and the wizard is going to be dismissed -
#define EVT_WXFB_WIZARD_FINISHED(id, fn) wxFB__DECLARE_WIZARDEVT(FINISHED, id, fn)

// the user pressed "Help" button
#define EVT_WXFB_WIZARD_HELP(id, fn) wxFB__DECLARE_WIZARDEVT(HELP, id, fn)

// the page was just shown and laid out
#define EVT_WXFB_WIZARD_PAGE_SHOWN(id, fn) wxFB__DECLARE_WIZARDEVT(PAGE_SHOWN, id, fn)

#endif  // SDK_PLUGIN_INTERFACE_FORMS_WIZARD_H
