#include "DesktopManager.h"

#include "FileLogger.h"

DesktopManager::DesktopManager()
    : mScreens(),
      mWindowManager(WindowManager::Create()),
      mKeyboard(Keyboard::Create()),
      mMainApplication(),
      mModified(false),
      mEventManager(EventManager::Create())
{

}

DesktopManager::~DesktopManager()
{

}

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

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

void DesktopManager::OnKeyboardEvent(const KeyboardEvent* event)
{
    MLOG_INFO("Got key event: " << event->GetKeyString());
    GetWindowManager()->OnKeyboardEvent(event);
}

void DesktopManager::OnPaintEvent(const PaintEvent* event)
{
    GetWindowManager()->OnPaintEvent(event);
}

void DesktopManager::OnMouseEvent(const MouseEvent* event)
{
    GetWindowManager()->OnMouseEvent(event);
}

bool DesktopManager::IsModified() const
{
    return mModified;
}

void DesktopManager::OnUiEvent(UiEventUPtr eventUPtr)
{
    mModified = false;
    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));
            mModified = true;
            break;
        }
        case (UiEvent::Type::Mouse):
        {
            auto mouseEvent = dynamic_cast<const MouseEvent*>(event);
            OnMouseEvent(mouseEvent);
            if (mouseEvent->GetAction() == MouseEvent::Action::Pressed)
            {
                mModified = true;
            }
            else if(mouseEvent->GetAction() == MouseEvent::Action::Released)
            {
                mModified = true;
            }
            break;
        }
        default:
            break;
    }
}

void DesktopManager::SetIsModified(bool modified)
{
    mModified = modified;
}

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

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

void DesktopManager::SetMainApp(std::shared_ptr<AbstractApp> mainApp)
{
    mMainApplication = mainApp;
}

AbstractApp* DesktopManager::GetMainApp()
{
    return mMainApplication.get();
}

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();
}
