#include "DesktopManager.h"

#include "AbstractDesktopApp.h"
#include "AbstractUiInterface.h"

#include "FileLogger.h"
#include "Widget.h"

#include <iostream>

DesktopManager::DesktopManager(AbstractDesktopApp* application)
    : mScreens(),
      mKeyboard(Keyboard::Create()),
      mFontsManager(FontsManager::Create()),
      mEventManager(EventManager::Create()),
      mThemeManager(std::make_unique<ThemeManager>()),
      mUiApplication(application)
{
    mWindowManager = WindowManager::Create(this);
}

DesktopManager::~DesktopManager()
{

}

std::unique_ptr<DesktopManager> DesktopManager::Create(AbstractDesktopApp* application)
{
    return std::make_unique<DesktopManager>(application);
}

void DesktopManager::clearEvents()
{
    mEventManager->ClearEvents();
}

FontsManager* DesktopManager::getFontsManager() const
{
    return mFontsManager.get();
}

ThemeManager* DesktopManager::getThemeManager() const
{
    return mThemeManager.get();
}

void DesktopManager::onKeyboardEvent(const KeyboardEvent* event)
{
    mWindowManager->onKeyboardEvent(event);
}

void DesktopManager::onPaintEvent(const PaintEvent* event)
{
    mWindowManager->onPaintEvent(event);
}

void DesktopManager::onMouseEvent(const MouseEvent* event)
{
    mWindowManager->onMouseEvent(event);
}

void DesktopManager::onUiEvent(UiEventUPtr eventUPtr)
{
    const auto event = mEventManager->AddEvent(std::move(eventUPtr));
    switch (event->getType())
    {
        case (UiEvent::Type::Paint):
        {
            onPaintEvent(dynamic_cast<const PaintEvent*>(event));
            break;
        }
        case (UiEvent::Type::Keyboard):
        {
            onKeyboardEvent(dynamic_cast<const KeyboardEvent*>(event));
            break;
        }
        case (UiEvent::Type::Resize):
        {
            auto resize_event = dynamic_cast<const ResizeEvent*>(event);
            mWindowManager->onResizeEvent(resize_event);
            break;
        }
        case (UiEvent::Type::Mouse):
        {
            auto mouseEvent = dynamic_cast<const MouseEvent*>(event);
            onMouseEvent(mouseEvent);
            break;
        }
        default:
            break;
    }
}

Keyboard* DesktopManager::getKeyboard() const
{
    return mKeyboard.get();
}

void DesktopManager::setKeyboard(KeyboardUPtr keyboard)
{
    mKeyboard = std::move(keyboard);
}

AbstractApp* DesktopManager::getMainApp() const
{
    return mUiApplication->getMainApplication();
}

void DesktopManager::addScreen(ScreenPtr screen)
{
    mScreens.push_back(std::move(screen));
}

mt::Screen* DesktopManager::getDefaultScreen() const
{
    if (mScreens.size() > 0)
    {
        return mScreens[0].get();
    }
    return nullptr;
}

void DesktopManager::setWindowManager(WindowManagerUPtr windowManager)
{
    mWindowManager = std::move(windowManager);
}

WindowManager* DesktopManager::getWindowManager() const
{
    return mWindowManager.get();
}

void DesktopManager::addWindow(mt::Window* window)
{
    if (auto ui_interface = mUiApplication->getUiInterface())
    {
        std::cout << "Adding popup window" << std::endl;
        ui_interface->addWindow(window);
        ui_interface->showWindow(window);
    }
}

void DesktopManager::onLoopIteration()
{
    auto defaultScreen = getDefaultScreen();

    mWindowManager->onLoopIteration(defaultScreen);
}
