#include "RectangleDialog.h"

// Scale factor from millimetres to the display unit, and a suffix for labels.
static double UnitScale(int units) {
    if (units == 1) return 1.0 / 10.0;    // cm
    if (units == 2) return 1.0 / 25.4;    // inch
    return 1.0;                            // mm
}
static const char* UnitSuffix(int units) {
    if (units == 1) return "cm";
    if (units == 2) return "in";
    return "mm";
}

RectangleDialog::RectangleDialog(wxWindow* parent, int units,
                                 double defaultWmm, double defaultHmm)
    : wxDialog(parent, wxID_ANY, "Rectangle",
               wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE)
    , m_units(units)
    , m_wMm(defaultWmm)
    , m_hMm(defaultHmm)
{
    const double  scale  = UnitScale(units);
    const char*   suffix = UnitSuffix(units);
    // Inches want a couple of decimals; mm is fine as whole numbers.
    const int     digits = (units == 2) ? 2 : (units == 1 ? 1 : 0);
    const double  step   = (units == 2) ? 0.5 : (units == 1 ? 1.0 : 10.0);
    const double  maxVal = 20000.0 * scale;   // 20 m, generous

    wxBoxSizer* root = new wxBoxSizer(wxVERTICAL);

    root->Add(new wxStaticText(this, wxID_ANY,
                  "Enter the size of the rectangle."),
              0, wxALL, 10);

    wxFlexGridSizer* grid = new wxFlexGridSizer(2, 3, 6, 8);
    grid->AddGrowableCol(1, 1);

    auto addRow = [&](const wxString& label, wxSpinCtrlDouble*& ctrl,
                      double valueMm) {
        grid->Add(new wxStaticText(this, wxID_ANY, label),
                  0, wxALIGN_CENTER_VERTICAL);
        ctrl = new wxSpinCtrlDouble(this, wxID_ANY, wxEmptyString,
                                    wxDefaultPosition, wxSize(110, -1),
                                    wxSP_ARROW_KEYS,
                                    step, maxVal, valueMm * scale, step);
        ctrl->SetDigits(digits);
        grid->Add(ctrl, 1, wxEXPAND);
        grid->Add(new wxStaticText(this, wxID_ANY, suffix),
                  0, wxALIGN_CENTER_VERTICAL);
    };

    addRow("Width:",  m_spW, defaultWmm);
    addRow("Height:", m_spH, defaultHmm);

    root->Add(grid, 0, wxEXPAND | wxLEFT | wxRIGHT | wxBOTTOM, 10);

    wxSizer* btns = CreateButtonSizer(wxOK | wxCANCEL);
    if (btns) root->Add(btns, 0, wxEXPAND | wxALL, 10);

    Bind(wxEVT_BUTTON, &RectangleDialog::OnOK, this, wxID_OK);

    SetSizerAndFit(root);
    Centre();
    m_spW->SetFocus();
}

void RectangleDialog::OnOK(wxCommandEvent& e) {
    // Convert back to millimetres -- callers always work in mm.
    const double scale = UnitScale(m_units);
    m_wMm = m_spW->GetValue() / scale;
    m_hMm = m_spH->GetValue() / scale;
    e.Skip();   // let the dialog close normally
}
