#include "WindowClassManager.hpp"

WindowClassManager::WindowClassManager(const std::wstring& className) : mClassName(className), mhInstance(GetModuleHandleW(nullptr)), mIsRegistered(false)
{
}

WindowClassManager::~WindowClassManager()
{
    if (mIsRegistered)
        Unregister();
}

bool WindowClassManager::Register(WNDPROC wndProc)
{
    if (mIsRegistered)
        return true;

    if (!wndProc)
        return false;

    WNDCLASSEXW wc = CreateWindowClass(wndProc);
    return RegisterWindowClass(wc);
}

bool WindowClassManager::Unregister()
{
    if (!mIsRegistered)
        return true;

    return UnregisterWindowClass();
}

bool WindowClassManager::IsRegistered() const
{
    return mIsRegistered;
}

std::wstring WindowClassManager::GetWindowClassName() const
{
    return mClassName;
}

HINSTANCE WindowClassManager::GetInstance() const
{
    return mhInstance;
}

WNDCLASSEXW WindowClassManager::CreateWindowClass(WNDPROC wndProc) const
{
    WNDCLASSEXW wc = {};
    InitializeWindowClassDefaults(wc);
    wc.lpfnWndProc = wndProc;
    return wc;
}

bool WindowClassManager::RegisterWindowClass(const WNDCLASSEXW& wc)
{
    ATOM result = RegisterClassExW(&wc);
    if (result == 0)
        return false;

    SetRegistered(true);
    return true;
}

bool WindowClassManager::UnregisterWindowClass()
{
    BOOL result = UnregisterClassW(mClassName.c_str(), mhInstance);
    if (!result)
        return false;

    SetRegistered(false);
    return true;
}

void WindowClassManager::SetRegistered(bool registered)
{
    mIsRegistered = registered;
}

WNDCLASSEXW WindowClassManager::BuildWindowClassStruct(WNDPROC wndProc) const
{
    WNDCLASSEXW wc = {};
    wc.cbSize = sizeof(WNDCLASSEXW);
    wc.lpfnWndProc = wndProc;
    wc.hInstance = mhInstance;
    wc.lpszClassName = mClassName.c_str();
    return wc;
}

void WindowClassManager::InitializeWindowClassDefaults(WNDCLASSEXW& wc) const
{
    wc.cbSize = sizeof(WNDCLASSEXW);
    wc.lpfnWndProc = nullptr;
    wc.cbClsExtra = 0;
    wc.cbWndExtra = 0;
    wc.hInstance = mhInstance;
    wc.hIcon = nullptr;
    wc.hCursor = nullptr;
    wc.hbrBackground = nullptr;
    wc.lpszMenuName = nullptr;
    wc.lpszClassName = mClassName.c_str();
    wc.hIconSm = nullptr;
}