#ifndef FORM_HPP_
#define FORM_HPP_

#include <Widget/IconLabel/IconLabel.hpp>
#include <Widget/Layout/CompoundWidget/CompoundWidget.hpp>
#include <Widget/Layout/Column/Column.hpp>
#include <Widget/Layout/Center/Center.hpp>
#include <Widget/Label/Label.hpp>
#include <Widget/Layout/Column/HorizontalSeparator/HorizontalSeparator.hpp>
#include <Widget/Layout/CompoundWidget/Deck/Deck.hpp>
#include <Widget/Layout/Margin/Margin.hpp>
#include <Widget/Layout/Row/Row.hpp>
#include <Widget/Layout/Frame/Frame.hpp>

/**
 * @brief A widget showing a caption, body and footer.
 */
class Form : public CompoundWidget
{
private:
    static constexpr int bodyMargin = 2;
    static constexpr int headerMagin = 2;

    template<typename... TFooterElements>
    static Widget* buildForm(Widget *header, Widget *body, TFooterElements... footerElements)
    {
        return new Column(
            new Center(
                (new Frame(
                    Color::sectionBackground,
                    header
                ))->withMargin(headerMagin)
            ),
            Layout::WithProportion<1>(),
            (new Frame(
                Color::sectionBackground,
                body
            ))->withMargin(bodyMargin),
            new Row(footerElements...)
        );
    }

public:
    /**
     * @brief Construct a form.
     * 
     * @param caption The caption to display in the header.
     * @param body The main element of the form.
     * @param footerElements The footer elements which will be placed in a row.
     */
    template<typename... TFooterElements>
    Form(std::string caption, Widget *body, TFooterElements... footerElements) : CompoundWidget(
        buildForm(
            new Label(caption),
            body,
            footerElements...
        )
    ) {}

    /**
     * @brief Construct a form.
     * 
     * @param icon The header icon.
     * @param caption The caption to display in the header.
     * @param body The main element of the form.
     * @param footerElements The footer elements which will be placed in a row.
     */
    template<typename... TFooterElements>
    Form(Material &icon, std::string caption, Widget *body, TFooterElements... footerElements) : CompoundWidget(
        buildForm(
            new Deck<Row, Center>(new IconLabel(icon), new Label(caption)),
            body,
            footerElements...
        )
    ) {}

    /**
     * @brief Construct a form.
     * 
     * @param header The widget to show in the header.
     * @param body The main element of the form.
     * @param footerElements The footer elements which will be placed in a row.
     */
    template<typename... TFooterElements>
    Form(Widget *header, Widget *body, TFooterElements... footerElements) : CompoundWidget(
        buildForm(
            header,
            body,
            footerElements...
        )
    ) {}
};

#endif