#include "panels/PiecePreviewPopup.h"
#include "io/CatalogLoader.h"
#include <wx/dcbuffer.h>
#include <cmath>

wxBEGIN_EVENT_TABLE(PiecePreviewPopup, wxPopupWindow)
    EVT_PAINT(PiecePreviewPopup::OnPaint)
wxEND_EVENT_TABLE()

PiecePreviewPopup::PiecePreviewPopup(wxWindow* parent)
    : wxPopupWindow(parent, wxBORDER_SIMPLE)
{
    SetBackgroundStyle(wxBG_STYLE_PAINT);
    SetSize(W, H);

    // Hide when parent window loses focus or is deactivated
    parent->Bind(wxEVT_KILL_FOCUS, [this](wxFocusEvent& e) {
        Hide(); e.Skip();
    });
    parent->Bind(wxEVT_ACTIVATE, [this](wxActivateEvent& e) {
        if (!e.GetActive()) Hide();
        e.Skip();
    });
}

void PiecePreviewPopup::ShowForPiece(const MC::TrackPiece* piece, const wxPoint& screenPos) {
    if (!piece) { Hide(); return; }
    m_piece = piece;
    Move(screenPos.x + 8, screenPos.y - H/2);
    Show();
    Refresh();
}

void PiecePreviewPopup::Hide() {
    m_piece = nullptr;
    wxPopupWindow::Show(false);
}

void PiecePreviewPopup::OnPaint(wxPaintEvent&) {
    wxAutoBufferedPaintDC dc(this);
    dc.SetBackground(wxBrush(wxColour(255, 255, 240)));
    dc.Clear();
    if (!m_piece) return;

    dc.SetBrush(*wxTRANSPARENT_BRUSH);
    dc.SetPen(wxPen(wxColour(180, 180, 180), 1));
    dc.DrawRectangle(0, 0, W, H);

    dc.SetFont(wxFont(7, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
    dc.SetTextForeground(wxColour(60, 60, 60));
    wxString name = wxString::FromUTF8(m_piece->catalogNumber.c_str());
    wxSize ts = dc.GetTextExtent(name);
    dc.DrawText(name, (W - ts.x)/2, 2);

    double pieceW = std::max(m_piece->lengthMm, 1.0);
    double pieceH = std::max(40.0,
        m_piece->radiusMm > 0
        ? std::abs(m_piece->radiusMm * (1 - std::cos(m_piece->angleDeg * M_PI / 180.0))) * 2.5
        : 40.0);
    if (m_piece->connections.size() > 2) pieceH = std::max(pieceH, 60.0);

    double margin = 6.0;
    double drawW  = W - 2*margin;
    double drawH  = H - 16.0 - margin;
    double scale  = std::min(drawW / pieceW, drawH / pieceH) * 0.8;
    scale = std::max(0.05, std::min(scale, 3.0));

    MC::ViewTransform view;
    view.scale = scale;
    view.panX  = margin + drawW/2 - (pieceW * scale)/2;
    view.panY  = 14 + drawH/2;

    MC::PlacedPiece placed;
    placed.catalogNumber = m_piece->catalogNumber;
    placed.transform.pos = { 0, 0 };
    placed.transform.heading = 0;
    placed.joints.resize(m_piece->connections.size(), {-1, -1});

    m_renderer.DrawPiece(dc, placed, *m_piece, view, false, false);
}
