#pragma once

#include <vector>
#include <memory>

#include "Keyboard.h"
#include "Screen.h"
#include "KeyboardEvent.h"
#include "PaintEvent.h"
#include "MouseEvent.h"
#include "WindowManager.h"
#include "UiEvent.h"
#include "AbstractApp.h"
#include "EventManager.h"

class AbstractDesktopApp;

class DesktopManager
{
public:

    DesktopManager(AbstractDesktopApp* application);

    ~DesktopManager();

    static std::unique_ptr<DesktopManager> Create(AbstractDesktopApp* application);

    void setWindowManager(WindowManagerUPtr windowManager);

    AbstractApp* getMainApp() const;

    WindowManager* getWindowManager() const;

    Keyboard* getKeyboard() const;

    void addScreen(ScreenPtr screen);

    mt::Screen* getDefaultScreen() const;

    void setKeyboard(KeyboardUPtr keyboard);

    void onUiEvent(UiEventUPtr event);

    void onKeyboardEvent(const KeyboardEvent* keyboardEvent);

    void onMouseEvent(const MouseEvent* mouseEvent);

    void onPaintEvent(const PaintEvent* paintEvent);

    void clearEvents();

    void onLoopIteration();

    void addWindow(mt::Window* window);

private:
    std::vector<ScreenPtr> mScreens;
    WindowManagerUPtr mWindowManager;
    KeyboardUPtr mKeyboard;
    EventManagerUPtr mEventManager;
    AbstractDesktopApp* mUiApplication;
};

using DesktopManagerUPtr = std::unique_ptr<DesktopManager>;
