#include "PrintOptionsDialog.h"
#include <wx/spinctrl.h>
#include <wx/sizer.h>
#include <wx/statbox.h>

enum {
    ID_ScaleRadio = wxID_HIGHEST + 1,
};

wxBEGIN_EVENT_TABLE(PrintOptionsDialog, wxDialog)
    EVT_BUTTON(wxID_OK, PrintOptionsDialog::OnOk)
    EVT_RADIOBOX(ID_ScaleRadio, PrintOptionsDialog::OnScaleModeChanged)
wxEND_EVENT_TABLE()

PrintOptionsDialog::PrintOptionsDialog(wxWindow* parent, const Options& initial)
    : wxDialog(parent, wxID_ANY, "Print Options",
               wxDefaultPosition, wxDefaultSize,
               wxDEFAULT_DIALOG_STYLE)
    , m_opts(initial)
{
    auto* top = new wxBoxSizer(wxVERTICAL);

    // ── Scaling ──
    wxArrayString scaleChoices;
    scaleChoices.Add("Fit to page");
    scaleChoices.Add("Actual scale 1 : N");
    scaleChoices.Add("Custom percentage");
    m_scaleRadio = new wxRadioBox(this, ID_ScaleRadio, "Scaling",
                                  wxDefaultPosition, wxDefaultSize,
                                  scaleChoices, 1, wxRA_SPECIFY_COLS);
    m_scaleRadio->SetSelection(static_cast<int>(initial.scale));
    top->Add(m_scaleRadio, 0, wxEXPAND | wxALL, 8);

    // 1 : N row
    {
        auto* row = new wxBoxSizer(wxHORIZONTAL);
        m_denomLabel = new wxStaticText(this, wxID_ANY, "    1 :");
        m_denomSpin  = new wxSpinCtrl(this, wxID_ANY, "",
                                      wxDefaultPosition, wxSize(80, -1),
                                      wxSP_ARROW_KEYS, 1, 1000, initial.scaleDenom);
        row->Add(m_denomLabel, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 6);
        row->Add(m_denomSpin,  0, wxALIGN_CENTER_VERTICAL);
        row->Add(new wxStaticText(this, wxID_ANY,
                                  "  (e.g. 1:10 -- 10 mm on layout = 1 mm on paper)"),
                 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 8);
        top->Add(row, 0, wxLEFT | wxRIGHT | wxBOTTOM, 12);
    }

    // Custom % row
    {
        auto* row = new wxBoxSizer(wxHORIZONTAL);
        m_pctLabel = new wxStaticText(this, wxID_ANY, "    Scale:");
        m_pctSpin  = new wxSpinCtrl(this, wxID_ANY, "",
                                    wxDefaultPosition, wxSize(80, -1),
                                    wxSP_ARROW_KEYS, 1, 1000, initial.scalePercent);
        row->Add(m_pctLabel, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT, 6);
        row->Add(m_pctSpin,  0, wxALIGN_CENTER_VERTICAL);
        row->Add(new wxStaticText(this, wxID_ANY, "  %"),
                 0, wxALIGN_CENTER_VERTICAL | wxLEFT, 4);
        top->Add(row, 0, wxLEFT | wxRIGHT | wxBOTTOM, 12);
    }

    // ── Levels ──
    wxArrayString levelChoices;
    levelChoices.Add("Active level only");
    levelChoices.Add("All levels (composite)");
    m_levelRadio = new wxRadioBox(this, wxID_ANY, "Levels",
                                  wxDefaultPosition, wxDefaultSize,
                                  levelChoices, 1, wxRA_SPECIFY_COLS);
    m_levelRadio->SetSelection(static_cast<int>(initial.levels));
    top->Add(m_levelRadio, 0, wxEXPAND | wxALL, 8);

    // ── Color ──
    wxArrayString colorChoices;
    colorChoices.Add("Color");
    colorChoices.Add("Grayscale");
    m_colorRadio = new wxRadioBox(this, wxID_ANY, "Color",
                                  wxDefaultPosition, wxDefaultSize,
                                  colorChoices, 2, wxRA_SPECIFY_COLS);
    m_colorRadio->SetSelection(static_cast<int>(initial.color));
    top->Add(m_colorRadio, 0, wxEXPAND | wxALL, 8);

    // ── Extras ──
    auto* extrasBox = new wxStaticBoxSizer(wxVERTICAL, this, "Include");
    m_gridChk = new wxCheckBox(extrasBox->GetStaticBox(), wxID_ANY, "Grid");
    m_gridChk->SetValue(initial.showGrid);
    m_baseChk = new wxCheckBox(extrasBox->GetStaticBox(), wxID_ANY, "Baseboard outline");
    m_baseChk->SetValue(initial.showBaseboard);
    extrasBox->Add(m_gridChk, 0, wxALL, 4);
    extrasBox->Add(m_baseChk, 0, wxALL, 4);
    top->Add(extrasBox, 0, wxEXPAND | wxALL, 8);

    // ── Buttons ──
    auto* btns = CreateButtonSizer(wxOK | wxCANCEL);
    top->Add(btns, 0, wxEXPAND | wxALL, 8);

    SetSizerAndFit(top);
    CenterOnParent();
    UpdateEnabledState();
}

void PrintOptionsDialog::OnScaleModeChanged(wxCommandEvent&) {
    UpdateEnabledState();
}

void PrintOptionsDialog::UpdateEnabledState() {
    int sel = m_scaleRadio->GetSelection();
    bool denomOn = (sel == static_cast<int>(ScaleMode::ActualScale));
    bool pctOn   = (sel == static_cast<int>(ScaleMode::CustomPercent));
    m_denomLabel->Enable(denomOn);
    m_denomSpin->Enable(denomOn);
    m_pctLabel->Enable(pctOn);
    m_pctSpin->Enable(pctOn);
}

void PrintOptionsDialog::OnOk(wxCommandEvent& e) {
    m_opts.scale         = static_cast<ScaleMode>(m_scaleRadio->GetSelection());
    m_opts.scaleDenom    = m_denomSpin->GetValue();
    m_opts.scalePercent  = m_pctSpin->GetValue();
    m_opts.levels        = static_cast<LevelMode>(m_levelRadio->GetSelection());
    m_opts.color         = static_cast<ColorMode>(m_colorRadio->GetSelection());
    m_opts.showGrid      = m_gridChk->GetValue();
    m_opts.showBaseboard = m_baseChk->GetValue();
    e.Skip();  // let the default OK handler dismiss the dialog
}
