/**********************************************************************

   Audacity: A Digital Audio Editor
   Audacity(R) is copyright (c) 1999-2010 Audacity Team.
   License: GPL v2.  See License.txt.

   MultiDialog.h

   Monty
   Vaughan Johnson

*******************************************************************//**

\class MultiDialog
\brief A multi purpose dialog, mainly used to show lists of orphaned or
damaged block files.  It is a good alternative to having a dialog pop up
for each problem encountered, since there can be many orphans.

*//*******************************************************************/

#include "../Audacity.h"
#include "MultiDialog.h"

#include "../ShuttleGui.h"

#include <wx/app.h>
#include <wx/button.h>
#include <wx/dialog.h>
#include <wx/intl.h>
#include <wx/icon.h>
#include <wx/sizer.h>
#include <wx/stattext.h>
#include <wx/statbmp.h>
#include <wx/artprov.h>
#include <wx/radiobox.h>
#include <wx/bmpbuttn.h>


#include "../AudacityLogger.h"
#include "wxPanelWrapper.h"
#include "../Theme.h"
#include "../AllThemeResources.h"
#include "../widgets/HelpSystem.h"

class MultiDialog final : public wxDialogWrapper
{
public:
   MultiDialog(wxWindow * pParent, 
               const TranslatableString &message,
               const TranslatableString &title,
               const TranslatableStrings &buttons,
               const wxString &helpPage,
               const TranslatableString &boxMsg, bool log);
   ~MultiDialog() {};

private:
   void OnOK( wxCommandEvent &event );
   void OnShowLog(wxCommandEvent& event);
   void OnHelp(wxCommandEvent& event);

   wxRadioBox* mRadioBox;
   wxString mHelpPage;

   DECLARE_EVENT_TABLE()
};

#define ID_SHOW_LOG_BUTTON 3333

BEGIN_EVENT_TABLE(MultiDialog, wxDialogWrapper)
   EVT_BUTTON( wxID_OK, MultiDialog::OnOK )
   EVT_BUTTON(ID_SHOW_LOG_BUTTON, MultiDialog::OnShowLog)
   EVT_BUTTON(wxID_HELP, MultiDialog::OnHelp)
END_EVENT_TABLE()

MultiDialog::MultiDialog(wxWindow * pParent,
                         const TranslatableString &message,
                         const TranslatableString &title,
                         const TranslatableStrings &buttons,
                         const wxString &helpPage,
                         const TranslatableString &boxMsg, 
                         bool log
   )
   : wxDialogWrapper(pParent, wxID_ANY, title,
               wxDefaultPosition, wxDefaultSize,
               wxCAPTION), // not wxDEFAULT_DIALOG_STYLE because we don't want wxCLOSE_BOX and wxSYSTEM_MENU
    mHelpPage( helpPage)
{
   SetName();

   ShuttleGui S{ this, eIsCreating };
   {
      S.SetBorder( 5 );
      S.StartVerticalLay( 0 );
      {
         S.StartHorizontalLay(wxALIGN_LEFT | wxALL, 0);
         {
            S.SetBorder( 0 );
            wxBitmap bitmap = wxArtProvider::GetIcon(wxART_WARNING,
               wxART_MESSAGE_BOX);
            auto icon = safenew wxStaticBitmap(S.GetParent(), -1, bitmap);
            S
               .Position( wxCENTER )
               .AddWindow( icon );

            S.SetBorder( 15 );
            S.Prop(1).AddVariableText( message, false, wxCENTER | wxLEFT );
         }
         S.EndHorizontalLay();

         const auto buttonLabels = transform_container<wxArrayStringEx>(
            buttons, std::mem_fn( &TranslatableString::Translation ) );

         const auto count = buttons.size();
         
         const auto boxStr = boxMsg.Translation();

         S.SetBorder( 5 );

         mRadioBox = safenew wxRadioBox(S.GetParent(), -1,
            boxStr,
            wxDefaultPosition, wxDefaultSize,
            count, count ? &buttonLabels[0] : nullptr,
            1, wxRA_SPECIFY_COLS);
         mRadioBox->SetSelection(0);
         S.Prop( 1 )
            .Name( boxMsg )
            .Position(wxEXPAND | wxALL)
            .AddWindow( mRadioBox );


         S.StartHorizontalLay(wxALIGN_CENTER | wxALL, 0);
         {
            if (log)
            {
               S
                  .Id(ID_SHOW_LOG_BUTTON)
                  .AddButton(
                     XO("Show Log for Details"), wxALIGN_LEFT | wxALL,
                     // set default to encourage user to look at files.
                     true);

               S.AddSpace(40, 0);
            }

            auto pButton = S.Id(wxID_OK)
               .AddButton(XO("OK"), wxALIGN_CENTER, !log);

            if (!mHelpPage.IsEmpty()) {
               auto pHelpBtn = S.Id(wxID_HELP)
                  .AddBitmapButton(theTheme.Bitmap(bmpHelpIcon), wxALIGN_CENTER, false);
               pHelpBtn->SetToolTip(XO("Help").Translation());
               pHelpBtn->SetLabel(XO("Help").Translation());       // for screen readers
            }
         }
         S.EndHorizontalLay();
      }
      S.EndVerticalLay();
   }

   SetAutoLayout(true);
   GetSizer()->Fit(this);
   GetSizer()->SetSizeHints(this);
}

void MultiDialog::OnOK(wxCommandEvent & WXUNUSED(event))
{
   EndModal(mRadioBox->GetSelection());
}

void MultiDialog::OnShowLog(wxCommandEvent & WXUNUSED(event))
{
   auto logger = AudacityLogger::Get();
   if (logger) {
      logger->Show();
   }
}

void MultiDialog::OnHelp(wxCommandEvent & WXUNUSED(event))
{
   HelpSystem::ShowHelp(FindWindow(wxID_HELP), mHelpPage, true);
}

int ShowMultiDialog(const TranslatableString &message,
   const TranslatableString &title,
   const TranslatableStrings &buttons,
   const wxString &helpPage,
   const TranslatableString &boxMsg, bool log)
{
   wxWindow * pParent = wxTheApp->GetTopWindow();

   // We want a parent we can display over, so don't make it a parent if top
   // window is a STAY_ON_TOP.
   if (pParent) {
      if ((pParent->GetWindowStyle() & wxSTAY_ON_TOP) == wxSTAY_ON_TOP)
         pParent = NULL;
   }
   MultiDialog dlog(pParent,
      message, title, buttons, helpPage, boxMsg, log);
   // If dialog does not have a parent, cannot be centred on it.
   if (pParent != NULL)
      dlog.CentreOnParent();
   else {
      dlog.CenterOnScreen();
      // and after centring move the dialog left by the size of the dialog.
      // Likely to help if we have the splash screen visible, or if
      // we're spanning two equally sized monitors.
      // Unlikely to make things worse.
      wxSize Size = dlog.GetSize();
      Size.SetHeight( 10 );
      wxPoint Pos = dlog.GetPosition() -Size;
      dlog.Move(Pos);
   }
   return dlog.ShowModal();
}

const TranslatableString &DefaultMultiDialogMessage()
{
   static auto result = XO("Please select an action");
   return result;
}
