#pragma once
#include <wx/wx.h>
class View3DFrame;
#include <wx/splitter.h>
#include <wx/filename.h>
#include "canvas/CanvasState.h"

class PalettePanel;
class CanvasPanel;
class PropertiesPanel;
class wxPrintData;
class wxPageSetupDialogData;
#include "PrintOptionsDialog.h"

enum {
    ID_New    = wxID_NEW,
    ID_Open   = wxID_OPEN,
    ID_Save   = wxID_SAVE,
    ID_SaveAs = wxID_SAVEAS,
    ID_Close  = wxID_CLOSE,
    ID_Import = 1900,
    ID_Export,
    ID_Print        = wxID_PRINT,
    ID_PrintPreview = wxID_PREVIEW,
    ID_PageSetup    = wxID_PAGE_SETUP,
    ID_View3D    = 2000,
    ID_SaveBlock,
    ID_Undo,
    ID_Redo,
    ID_Delete,
    ID_SelectAll,
    ID_ZoomIn,
    ID_ZoomOut,
    ID_ZoomFit,
    ID_GridToggle,
    ID_SnapToggle,
    ID_LabelToggle,
    ID_RailToggle,
    ID_Tunnel,
    ID_Measure,
    ID_Polygon,
    ID_Rectangle,
    ID_Elevation,
    ID_LayoutShape,
    ID_UnitMm,
    ID_UnitCm,
    ID_UnitInch,
    ID_Levels,
    ID_Validate,
    ID_LayoutProperties,
    ID_Help,
    ID_Options,
};

class MainFrame : public wxFrame {
public:
    MainFrame();
    ~MainFrame();

    MC::CanvasState& State()           { return m_state; }
    CanvasPanel*     Canvas()          { return m_canvas; }
    PropertiesPanel* Properties()      { return m_properties; }
    void             RefreshTally();

    void OnSelectionChanged();
    void OnCanvasEmptyClick(wxPoint screenPt);
    void MarkDirty();
    void RefreshCanvas();   // refreshes canvas panel without needing full CanvasPanel type

private:
    void BuildMenuBar();
    void BuildToolBar();
    void BuildPanels();
    void BuildStatusBar();

    bool ConfirmDiscard();
    bool SaveLayout(bool forceDialog);
    bool LoadLayout(const wxString& path);
    bool SaveBlock();
    void LoadLibraryBlocks();
    void UpdateTitleBar();

    void OnNew(wxCommandEvent&);
    void OnOpen(wxCommandEvent&);
    void OnSave(wxCommandEvent&);
    void OnSaveAs(wxCommandEvent&);
    void OnSaveBlock(wxCommandEvent&);
    void OnClose(wxCommandEvent&);
    void OnPageSetup(wxCommandEvent&);
    void OnPrint(wxCommandEvent&);
    void OnPrintPreview(wxCommandEvent&);
    void OnUndo(wxCommandEvent&);
    void OnRedo(wxCommandEvent&);
    void OnDelete(wxCommandEvent&);
    void OnSelectAll(wxCommandEvent&);
    void OnZoomIn(wxCommandEvent&);
    void OnZoomOut(wxCommandEvent&);
    void OnZoomFit(wxCommandEvent&);
    void OnGridToggle(wxCommandEvent&);
    void OnSnapToggle(wxCommandEvent&);
    void OnLabelToggle(wxCommandEvent&);
    void OnRailToggle(wxCommandEvent&);
    void OnTunnel(wxCommandEvent&);
    void OnMeasureTool(wxCommandEvent&);
    void OnPolygonTool(wxCommandEvent&);
    void OnRectangleTool(wxCommandEvent&);
    void OnElevation(wxCommandEvent&);

public:
    // Called by the palette drop-handler when the user drops the helix item
    // onto the canvas. World coordinates of the desired helix center.
    void PlaceHelix(const MC::Vec2& center, double heading = 0.0,
                    const std::string& variantId = "");

private:
    void OnLayoutShape(wxCommandEvent&);
    void OnImport(wxCommandEvent&);
    void OnExport(wxCommandEvent&);
    void OnUnitChange(wxCommandEvent&);
    void OnLevels(wxCommandEvent&);
    void OnValidate(wxCommandEvent&);
    void OnLayoutProperties(wxCommandEvent&);
    void OnHelp(wxCommandEvent&);
    void OnOptions(wxCommandEvent&);
    void ShowExperienceDialog();
    void OnView3D(wxCommandEvent&);
    void OnClose(wxCloseEvent&);
    void OnExit(wxCommandEvent&);
    void OnUpdateUI(wxUpdateUIEvent&);

    PalettePanel*    m_palette    = nullptr;
    CanvasPanel*     m_canvas     = nullptr;
    PropertiesPanel* m_properties = nullptr;

    MC::CanvasState  m_state;
    wxString         m_currentFile;
    wxString         m_layoutName;
    bool             m_dirty    = false;
    View3DFrame*     m_view3d   = nullptr;

    // Persistent print settings (paper, orientation, margins, last options)
    wxPrintData*               m_printData     = nullptr;
    wxPageSetupDialogData*     m_pageSetupData = nullptr;
    PrintOptionsDialog::Options m_printOptions;

    wxDECLARE_EVENT_TABLE();
};
