#pragma once

#include <QDialog>

class QBoxLayout;
class QHBoxLayout;
class QKeyEvent;
class QString;

// Base of every modal the player meets while playing (REQ-UI-MODAL-CHROME). A modal is
// not an operating system window here: it is an ordinary child widget, hosted and placed
// by the ModalLayer that also paints the dim it sits on, so it has no title bar, no
// window border, and no window-manager close. What a window used to supply, this class
// supplies instead -- the panel background, the drawn header, and the dismissal gestures.
//
// It stays a QDialog for accept()/reject()/result() and the Escape handling built into
// them; only the window-ness is dropped (Qt::Widget flags). Nothing calls exec() on it:
// ModalLayer::execute() runs the modal loop, so that the layer knows what is open.
class ModalDialog : public QDialog
{
    Q_OBJECT

public:
    explicit ModalDialog(QWidget* parent = nullptr);

    // Whether Q and a click outside this dialog dismiss it (REQ-UI-DIALOG-DISMISS). One
    // predicate for both gestures because they reach exactly the same dialogs. The
    // default refuses both, so a dialog takes the gestures only by saying so: the two
    // name dialogs must let Q through as a character, and the schematic choice dialog
    // has no way out but choosing (REQ-DEF-SCHEMATIC-DROP).
    virtual bool isDismissible() const;

    // The widget that should hold the keyboard once the modal is open -- a name prompt's
    // line edit -- or nullptr to leave the focus on the modal itself. Asked for by
    // ModalLayer rather than read off focusWidget(), because hosting the modal reparents
    // it and a reparent clears the focus its constructor set.
    virtual QWidget* getInitialFocusWidget() const;

public slots:
    // What a dismissal does, whichever gesture asked for it. Cancelling is the default;
    // a dialog with modes of its own overrides this to back out of them one at a time
    // (ShipLayoutDialog, REQ-UI-DIALOG-DISMISS).
    virtual void requestDismiss();

protected:
    // Adds the drawn header row -- the title, and a close button at the far right when
    // asked for -- as the first row of mainLayout, and returns it so a subclass can
    // insert its own widgets after the title (REQ-UI-MODAL-CHROME). The close button
    // rejects the dialog, which is what the window-manager close used to do.
    QHBoxLayout* addHeader(QBoxLayout* mainLayout, const QString& title,
                           bool withCloseButton);

    void keyPressEvent(QKeyEvent* event) override;
};
