#pragma once

#include "DrawingSurface.h"

#include <memory>
#include <vector>
#include <cstdint>
#include <string>
#include <functional>

class PaintEvent;
class MouseEvent;
class KeyboardEvent;

class DrawingContext;
class FontsManager;
enum class DrawingMode;

class Widget;
using WidgetPtr = std::unique_ptr<Widget>;
class IPlatformWindow;
using IPlatformWindowPtr = std::unique_ptr<IPlatformWindow>;

namespace mt
{

class Screen;

class Window : public DrawingSurface
{

public:

    using onPopupFunc = std::function<void(mt::Window* parent, std::unique_ptr<Widget> popup)>;

    Window();

    ~Window();

    static std::unique_ptr<Window> Create();

    void setWidget(WidgetPtr widget);

    void onPaint(const PaintEvent* event);

    void onMouseEvent(const MouseEvent* event);

    void onKeyboardEvent(const KeyboardEvent* event);

    IPlatformWindow* getPlatformWindow() const;

    void setPlatformWindow(IPlatformWindowPtr window, FontsManager* fontsManager, DrawingMode drawingMode);

    void map();

    void show();

    void doPaint(mt::Screen* screen);

    void clear();

    void clearPlatformWindow();

    void setSize(unsigned width, unsigned height) override;

    bool isDirty() const;

    void setTitle(const std::string& title)
    {
        mTitle = title;
    }

    const std::string& getTitle() const
    {
        return mTitle;
    }

    void addPopup(std::unique_ptr<Widget> popupWidget)
    {
        if (mPopupFunc)
        {
            mPopupFunc(this, std::move(popupWidget));
        }
    }

    void setPopupHandler(onPopupFunc func)
    {
        mPopupFunc = func;
    }

    void setParent(Window* parent)
    {
        mParent = parent;
    }

    Window* getParent() const
    {
        return mParent;
    }

private:
    WidgetPtr mWidget {nullptr};
    std::string mTitle;
    IPlatformWindowPtr mPlatformWindow {nullptr};
    std::unique_ptr<DrawingContext> mDrawingContext;

    onPopupFunc mPopupFunc;
    Window* mParent{nullptr};
};
}

using WindowUPtr = std::unique_ptr<mt::Window>;
