// $Id: gc_dialog.h,v 1.21 2018/01/03 21:32:59 mkkuhner Exp $

/*
Copyright 2002-2005 Mary K. Kuhner, Peter Beerli, and Joseph Felsenstein

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

*/

/* Authors: Mary Kuhner, Jon Yamato, and Joseph Felsenstein */


#ifndef GC_DIALOG_H
#define GC_DIALOG_H

#include <vector>

#include "gc_structure_maps.h"

#include "wx/button.h"
#include "wx/dialog.h"
#include "wx/panel.h"
#include "wx/stattext.h"
#include "wx/string.h"
#include "wx/textctrl.h"

class GCDataStore;
class wxBoxSizer;
class wxCheckBox;
class wxChoice;
class wxRadioBox;
class wxStaticBoxSizer;

class gcUpdatingComponent : public wxPanel
{
  private:
    gcUpdatingComponent();      // undefined
  protected:
    // protected so inheritors can add objects
    wxStaticBoxSizer *          m_statBoxSizer;
  public:
    gcUpdatingComponent(wxWindow * parent, wxString instructions);
    virtual ~gcUpdatingComponent();

    // build initial display
    virtual void BuildDisplay(GCDataStore &)         = 0;

    // bring display of component in line with current data
    virtual void UpdateDisplay(GCDataStore &)        = 0;

    // update current data for most operations
    virtual void UpdateDataInterim(GCDataStore &)    = 0;

    // update current data as display of component ends
    virtual void UpdateDataFinal(GCDataStore &)      = 0;
};

class gcPlainTextHelper
// can get current text value from data store
{
  private:
  protected:
  public:
    gcPlainTextHelper();
    virtual ~gcPlainTextHelper();

    virtual wxString                FromDataStore(GCDataStore &) = 0;
};

class gcUpdatingPlainText : public gcUpdatingComponent
// uses gcPlainTextHelper to keep an uneditable text value up to date
{
  private:
    gcUpdatingPlainText();      // undefined
    wxStaticText *      m_statText;
    gcPlainTextHelper * m_textHelper;
  protected:
  public:
    gcUpdatingPlainText(wxWindow *          parent,
                        wxString            instructions,
                        gcPlainTextHelper * helper);
    virtual ~gcUpdatingPlainText();

    void BuildDisplay(GCDataStore &);
    void UpdateDisplay(GCDataStore &);
    void UpdateDataInterim(GCDataStore &) ;
    void UpdateDataFinal(GCDataStore &) ;
};

class gcTextHelper
// can get and set current text value from/to data store
{
  private:
  protected:
  public:
    gcTextHelper();
    virtual ~gcTextHelper();

    virtual wxString                FromDataStore(GCDataStore &) = 0;
    virtual void                    ToDataStore(GCDataStore &, wxString text) = 0;
    virtual const wxValidator &     GetValidator();
    virtual wxString                InitialString();
};

class gcTextCtrlWithInstructions : public wxTextCtrl
{
  private:
  protected:
    wxString        m_instructions;
  public:
    gcTextCtrlWithInstructions( wxWindow *          parent,
                                wxString            instructions,
                                const wxValidator & validator);
    virtual ~gcTextCtrlWithInstructions();

    void    OnMouse(wxMouseEvent & event);

    DECLARE_EVENT_TABLE()
};

class gcUpdatingTextCtrl : public gcUpdatingComponent
// uses gcTextHelper to keep an editable text value up to date
{
  private:
    gcUpdatingTextCtrl();           // undefined
    gcTextCtrlWithInstructions *    m_textCtrl;
    gcTextHelper *                  m_textHelper;
  protected:
  public:
    gcUpdatingTextCtrl( wxWindow *          parent,
                        wxString            instructions,
                        gcTextHelper *      helper);
    virtual ~gcUpdatingTextCtrl();

    void BuildDisplay(GCDataStore &);
    void UpdateDisplay(GCDataStore &);
    void UpdateDataInterim(GCDataStore &) ;
    void UpdateDataFinal(GCDataStore &) ;
};

class gcChoiceObject
{
  private:
  protected:
  public:
    gcChoiceObject();
    virtual ~gcChoiceObject();

    virtual void        UpdateDisplayInitial    (GCDataStore &) = 0;
    virtual void        UpdateDisplayInterim    (GCDataStore &) = 0;
    virtual void        UpdateDataInterim       (GCDataStore &) = 0;
    virtual void        UpdateDataFinal         (GCDataStore &) = 0;

    virtual wxWindow *  MakeWindow(wxWindow * parent)           = 0;
    virtual wxWindow *  FetchWindow()                           = 0;

    virtual size_t      GetRelevantId()                         = 0;
};

class gcUpdatingChoose : public gcUpdatingComponent
{
  private:
    gcUpdatingChoose();             // undefined
  protected:
    std::vector<gcChoiceObject*>    m_choices;
    std::vector<wxCheckBox*>        m_boxes;
  public:
    gcUpdatingChoose(   wxWindow *                      parent,
                        wxString                        instructions,
                        std::vector<gcChoiceObject*>    choices);
    virtual ~gcUpdatingChoose();

    virtual void BuildDisplay(GCDataStore &)         ;
    virtual void UpdateDisplay(GCDataStore &)        ;
    virtual void UpdateDataInterim(GCDataStore &)    ;
    virtual void UpdateDataFinal(GCDataStore &)      ;

    virtual void OnCheck(wxCommandEvent &);
    virtual void ProcessPositiveCheck(wxObject * checkBox);

    DECLARE_EVENT_TABLE()

};

class gcUpdatingChooseMulti : public gcUpdatingChoose
{
  public:
    gcUpdatingChooseMulti(  wxWindow *                      parent,
                            wxString                        instructions,
                            std::vector<gcChoiceObject*>    choices);
    virtual ~gcUpdatingChooseMulti();

    virtual void BuildDisplay(GCDataStore &)         ;

    virtual void    ProcessPositiveCheck(wxObject * checkBox);

    virtual void    UpdateDataFinal(GCDataStore &)      ;
    virtual void    DoFinalForMulti(GCDataStore &, gcIdVec checkedIds) = 0;
    virtual wxString    NoChoicesText() const;

    virtual void    OnSelectAll(wxCommandEvent &);
    virtual void    OnUnselectAll(wxCommandEvent &);

    DECLARE_EVENT_TABLE()
};

#if 0

class gcSelectObject
{
  public:
    gcSelectObject();
    virtual ~gcSelectObject();

    virtual wxString    GetCurrentLabel         (GCDataStore&) = 0;
    virtual void        UpdateDataInterim       (GCDataStore&) = 0;
    virtual void        UpdateDataFinal         (GCDataStore&) = 0;
};

class gcUpdatingSelect : public gcUpdatingComponent
{
  public:
    gcUpdatingSelect(   wxWindow *                      parent,
                        wxString                        instructions,
                        std::vector<gcSelectObject*>    selections);
    virtual ~gcUpdatingSelect();

    virtual void BuildDisplay(GCDataStore &);
    virtual void UpdateDisplay(GCDataStore &);
    virtual void UpdateDataInterim(GCDataStore &);
    virtual void UpdateDataFinal(GCDataStore &);
};

#endif

class gcUpdatingDialog : public wxDialog
// this needs to be built by the gcDialogCreator factory class
// that is its friend. When complete, it will contain any number
// of gcUpdatingComponent panels, plus a set of gcEditButtons
// at the bottom of the dialog
{
    friend class gcDialogCreator;
  private:
    gcUpdatingDialog();
  protected:
    virtual void DoDelete();
    virtual void DoUpdateData();
    virtual void DoBuildDisplay();
    //
    GCDataStore &                       m_dataStore;
    std::vector<gcUpdatingComponent*>   m_components;
    wxSizer *                           m_sizer;
  public:
    gcUpdatingDialog(   wxWindow *      parent,
                        GCDataStore &   dataStore,
                        wxString        title,
                        bool            forJustCreatedObj);
    virtual ~gcUpdatingDialog();

    virtual void OnButton       (wxCommandEvent &);
    virtual void ScreenEvent    (wxCommandEvent &);

    virtual bool Go();

    DECLARE_EVENT_TABLE()
};

class gcDialogCreator
{
  private:
  protected:
  public:
    gcDialogCreator();
    virtual ~gcDialogCreator();

    void AddComponent(gcUpdatingDialog&,gcUpdatingComponent*);
    void PlaceContent(gcUpdatingDialog&,wxSizer * sizerWithContent);
};

//------------------------------------------------------------------------------------

class gcEditButtons : public wxPanel
{
  private:
    gcEditButtons();        // undefined
  public:
    gcEditButtons(wxWindow * parent, bool forJustCreatedObj);
    virtual ~gcEditButtons();
};

//------------------------------------------------------------------------------------

#endif  // GC_DIALOG_H

//____________________________________________________________________________________
