int CALLBACK WinMain(HINSTANCE Instance, HINSTANCE PrevInstance, LPSTR CommandLine, int ShowCode)
{
    // Tick frequency
    {
        int64 TicksPerSecond;
        QueryPerformanceFrequency((LARGE_INTEGER *)&TicksPerSecond);
        Timer::Init(1000.0 / TicksPerSecond);
    }

    QueryPerformanceCounter((LARGE_INTEGER *)&Mem.Debug.Time);
    Timer::StartTime(&Mem.Debug.Timers[Timer_Startup]);

    Mem.IsRunning = true;

    // Set current path to this executable's path
    {
        HMODULE Module = GetModuleHandleA(NULL);
        char PathString[MAX_PATH];
        uint32 PathLength = GetModuleFileNameA(Module, PathString, MAX_PATH);
        if (PathLength != -1)
        {
            char *LastSlash = strrchr(PathString, '\\');
            if (LastSlash) { *LastSlash = '\0'; }
            SetCurrentDirectoryA(PathString);
        }
    }

    HWND Window;
    // Create Window
    {
        WNDCLASSA WindowClass = {};
        WindowClass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
        WindowClass.lpfnWndProc = Win32MainWindowCallback;
        WindowClass.hInstance = Instance;
        const char* IcoPath = "papaya.ico";
        WindowClass.hIcon = (HICON)LoadImage(0, IcoPath, IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_SHARED);
        WindowClass.lpszClassName = "PapayaWindowClass";

        if (!RegisterClassA(&WindowClass))
        {
            // TODO: Log: Register window class failed
            return 0;
        }

        Window =
            CreateWindowExA(
            0,                                                          // Extended window style
            WindowClass.lpszClassName,                                  // Class name,
            "Papaya",                                                   // Name,
            WS_POPUP | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE,    // Window style
            CW_USEDEFAULT,                                              // X,
            CW_USEDEFAULT,                                              // Y,
            CW_USEDEFAULT,                                              // Width,
            CW_USEDEFAULT,                                              // Height,
            0,                                                          // Window Parent,
            0,                                                          // Menu,
            Instance,                                                   // Handle to the instance,
            0);                                                         // lpParam

        if (!Window)
        {
            // TODO: Log: Create window failed
            return 0;
        }

        SystemParametersInfo(SPI_GETWORKAREA, 0, &WindowsWorkArea, 0);

#ifdef PAPAYARELEASE

        SetWindowPos(Window, HWND_TOP, 0, 0, 600, 600, NULL);
        ShowWindow(Window, SW_MAXIMIZE);
#else
        uint32 ScreenWidth = GetSystemMetrics(SM_CXSCREEN);
        uint32 ScreenHeight = GetSystemMetrics(SM_CYSCREEN);

        Mem.Window.Width = (uint32)((float)ScreenWidth * 0.5);
        Mem.Window.Height = (uint32)((float)ScreenHeight * 0.8);

        uint32 WindowX = (ScreenWidth - Mem.Window.Width) / 2;
        uint32 WindowY = (ScreenHeight - Mem.Window.Height) / 2;

        SetWindowPos(Window, HWND_TOP, WindowX, WindowY, Mem.Window.Width, Mem.Window.Height, NULL);
#endif // PAPAYARELEASE

        // Get window size
        {
            RECT WindowRect = { 0 };
            BOOL foo = GetClientRect(Window, &WindowRect);
            Mem.Window.Width  = WindowRect.right - WindowRect.left;
            Mem.Window.Height = WindowRect.bottom - WindowRect.top;
        }
    }

    // Initialize OpenGL
    {
        DeviceContext = GetDC(Window);

        // Setup pixel format
        {
            PIXELFORMATDESCRIPTOR PixelFormatDesc = { 0 };
            // TODO: Program seems to work perfectly fine without all other params except dwFlags.
            //       Can we skip other params for the sake of brevity?
            PixelFormatDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
            PixelFormatDesc.nVersion = 1;
            PixelFormatDesc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
            PixelFormatDesc.iPixelType = PFD_TYPE_RGBA;
            PixelFormatDesc.cColorBits = 32;
            PixelFormatDesc.cDepthBits = 32;
            PixelFormatDesc.dwLayerMask = PFD_MAIN_PLANE;
            //

            int32 PixelFormat = ChoosePixelFormat(DeviceContext, &PixelFormatDesc);
            if (!PixelFormat) { exit(1); } // TODO: Log: Choose pixel format failed
            if (!SetPixelFormat(DeviceContext, PixelFormat, &PixelFormatDesc)) { exit(1); } // TODO: Log: Set pixel format failed
        }

        // Create rendering context
        {
            // TODO: Create "proper" context?
            //       https://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation

            HGLRC RenderingContext = wglCreateContext(DeviceContext);
            wglMakeCurrent(DeviceContext, RenderingContext);

            if (!GL::InitAndValidate()) { exit(1); }

            glGetIntegerv(GL_MAJOR_VERSION, &Mem.System.OpenGLVersion[0]);
            glGetIntegerv(GL_MINOR_VERSION, &Mem.System.OpenGLVersion[1]);
        }

        // Disable vsync
        if (wglewIsSupported("WGL_EXT_swap_control")) { wglSwapIntervalEXT(0); }
    }

    // Initialize tablet
    EasyTab_Load(Window);

    Core::Initialize(&Mem);

    // Initialize ImGui
    {
        ImGuiIO& io = ImGui::GetIO();
        io.KeyMap[ImGuiKey_Tab] = VK_TAB;          // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
        io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
        io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
        io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
        io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
        io.KeyMap[ImGuiKey_Home] = VK_HOME;
        io.KeyMap[ImGuiKey_End] = VK_END;
        io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
        io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
        io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
        io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
        io.KeyMap[ImGuiKey_A] = 'A';
        io.KeyMap[ImGuiKey_C] = 'C';
        io.KeyMap[ImGuiKey_V] = 'V';
        io.KeyMap[ImGuiKey_X] = 'X';
        io.KeyMap[ImGuiKey_Y] = 'Y';
        io.KeyMap[ImGuiKey_Z] = 'Z';

        io.RenderDrawListsFn = Core::RenderImGui;
        io.ImeWindowHandle = Window;
    }


    Mem.Window.MenuHorizontalOffset = 32;
    Mem.Window.TitleBarButtonsWidth = 109;
    Mem.Window.TitleBarHeight = 30;

    Timer::StopTime(&Mem.Debug.Timers[Timer_Startup]);

    // Handle command line arguments (if present)
    if (strlen(CommandLine)) 
    {
        // Remove double quotes from string if present
        {
            char* PtrRead  = CommandLine;
            char* PtrWrite = CommandLine;
            while (*PtrRead) 
            {
                *PtrWrite = *PtrRead++;
                if (*PtrWrite != '\"') { PtrWrite++; }
            }
            *PtrWrite = '\0';
        }
        Core::OpenDocument(CommandLine, &Mem); 
    }

#ifdef PAPAYA_DEFAULT_IMAGE
    Core::OpenDocument(PAPAYA_DEFAULT_IMAGE, &Mem);
#endif // PAPAYA_DEFAULT_IMAGE

    while (Mem.IsRunning)
    {
        Timer::StartTime(&Mem.Debug.Timers[Timer_Frame]);

        // Windows message handling
        {
            MSG Message;
            while (PeekMessage(&Message, 0, 0, 0, PM_REMOVE))
            {
                if (Message.message == WM_QUIT)
                {
                    Mem.IsRunning = false;
                }

                TranslateMessage(&Message);
                DispatchMessageA(&Message);
            }
        }

        // Tablet input // TODO: Put this in papaya.cpp
        {
            Mem.Tablet.Pressure = EasyTab->Pressure;
            Mem.Tablet.PosX = EasyTab->PosX;
            Mem.Tablet.PosY = EasyTab->PosY;
            Mem.Tablet.Buttons = EasyTab->Buttons;
        }

        BOOL IsMaximized = IsMaximized(Window);
        if (IsIconic(Window)) { goto EndOfFrame; }

        // Start new ImGui frame
        {
            ImGuiIO& io = ImGui::GetIO();

            // Setup display size (every frame to accommodate for window resizing)
            RECT rect;
            GetClientRect(Window, &rect);
            io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));

            // Read keyboard modifiers inputs
            io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
            io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
            io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;

            // Setup time step
            INT64 current_time;
            QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
            io.DeltaTime = (float)(current_time - Mem.Debug.Time) * 
                           (float)Timer::GetFrequency() / 1000.0f;
            Mem.Debug.Time = current_time; // TODO: Move Imgui timers from Debug to their own struct

            // Hide OS mouse cursor if ImGui is drawing it
            //SetCursor(io.MouseDrawCursor ? NULL : LoadCursor(NULL, IDC_ARROW));

            // Start the frame
            ImGui::NewFrame();
        }

        // Title Bar Icon
        {
            ImGui::SetNextWindowSize(ImVec2((float)Mem.Window.MenuHorizontalOffset,(float)Mem.Window.TitleBarHeight));
            ImGui::SetNextWindowPos(ImVec2(1.0f, 1.0f));

            ImGuiWindowFlags WindowFlags = 0; // TODO: Create a commonly-used set of Window flags, and use them across ImGui windows
            WindowFlags |= ImGuiWindowFlags_NoTitleBar;
            WindowFlags |= ImGuiWindowFlags_NoResize;
            WindowFlags |= ImGuiWindowFlags_NoMove;
            WindowFlags |= ImGuiWindowFlags_NoScrollbar;
            WindowFlags |= ImGuiWindowFlags_NoCollapse;
            WindowFlags |= ImGuiWindowFlags_NoScrollWithMouse;

            ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0);
            ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(2,2));
            ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0));
            ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0,0));
            ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));

            ImGui::PushStyleColor(ImGuiCol_WindowBg, Mem.Colors[PapayaCol_Transparent]);

            bool bTrue = true;
            ImGui::Begin("Title Bar Icon", &bTrue, WindowFlags);

            #define CALCUV(X, Y) ImVec2((float)X/256.0f, (float)Y/256.0f)
            ImGui::Image((void*)(intptr_t)Mem.Textures[PapayaTex_UI], ImVec2(28,28), CALCUV(0,200), CALCUV(28,228));
            #undef CALCUV

            ImGui::End();

            ImGui::PopStyleColor(1);
            ImGui::PopStyleVar(5);
        }

        // Title Bar Buttons
        {
            ImGui::SetNextWindowSize(ImVec2((float)Mem.Window.TitleBarButtonsWidth,24.0f));
            ImGui::SetNextWindowPos(ImVec2((float)Mem.Window.Width - Mem.Window.TitleBarButtonsWidth, 0.0f));

            ImGuiWindowFlags WindowFlags = 0;
            WindowFlags |= ImGuiWindowFlags_NoTitleBar;
            WindowFlags |= ImGuiWindowFlags_NoResize;
            WindowFlags |= ImGuiWindowFlags_NoMove;
            WindowFlags |= ImGuiWindowFlags_NoScrollbar;
            WindowFlags |= ImGuiWindowFlags_NoCollapse;
            WindowFlags |= ImGuiWindowFlags_NoScrollWithMouse;

            ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0);
            ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0));
            ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0));
            ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0,0));
            ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));

            ImGui::PushStyleColor(ImGuiCol_Button, Mem.Colors[PapayaCol_Transparent]);
            ImGui::PushStyleColor(ImGuiCol_ButtonHovered, Mem.Colors[PapayaCol_ButtonHover]);
            ImGui::PushStyleColor(ImGuiCol_ButtonActive, Mem.Colors[PapayaCol_ButtonActive]);
            ImGui::PushStyleColor(ImGuiCol_WindowBg, Mem.Colors[PapayaCol_Transparent]);

            bool bTrue = true;

            #define CALCUV(X, Y) ImVec2((float)X/256.0f, (float)Y/256.0f)
            ImGui::Begin("Title Bar Buttons", &bTrue, WindowFlags);

            ImGui::PushID(0);
            if(ImGui::ImageButton((void*)(size_t)Mem.Textures[PapayaTex_UI], ImVec2(34,26), CALCUV(62,200),CALCUV(96,226), 1, ImVec4(0,0,0,0)))
            {
                ShowWindow(Window, SW_MINIMIZE);
            }

            ImVec2 StartUV = IsMaximized ? CALCUV(28,226) : CALCUV(62,226);
            ImVec2 EndUV   = IsMaximized ? CALCUV(62,252) : CALCUV(96,252);

            ImGui::PopID();
            ImGui::SameLine();
            ImGui::PushID(1);

            if(ImGui::ImageButton((void*)(size_t)Mem.Textures[PapayaTex_UI], ImVec2(34,26), StartUV, EndUV, 1, ImVec4(0,0,0,0)))
            {
                if (IsMaximized)
                {
                    ShowWindow(Window, SW_RESTORE);
                }
                else
                {
                    ShowWindow(Window, SW_MAXIMIZE);
                }
            }

            ImGui::PopID();
            ImGui::SameLine();
            ImGui::PushID(2);

            if(ImGui::ImageButton((void*)(size_t)Mem.Textures[PapayaTex_UI], ImVec2(34,26), CALCUV(28,200),CALCUV(62,226), 1, ImVec4(0,0,0,0)))
            {
                SendMessage(Window, WM_CLOSE, 0, 0);
            }

            ImGui::PopID();

            ImGui::End();
            #undef CALCUV

            ImGui::PopStyleVar(5);
            ImGui::PopStyleColor(4);
        }

        // ImGui::ShowTestWindow();
        Core::UpdateAndRender(&Mem);
        SwapBuffers(DeviceContext);

    EndOfFrame:
        Timer::StopTime(&Mem.Debug.Timers[Timer_Frame]);
        double FrameRate = (Mem.CurrentTool == PapayaTool_Brush && Mem.Mouse.IsDown[0]) ?
                           500.0 : 60.0;
        double FrameTime = 1000.0 / FrameRate;
        double SleepTime = FrameTime - Mem.Debug.Timers[Timer_Frame].ElapsedMs;
        Mem.Debug.Timers[Timer_Sleep].ElapsedMs = SleepTime;
        if (SleepTime > 0) { Sleep((int32)SleepTime); }
    }

    Core::Shutdown(&Mem);

    EasyTab_Unload();

    return 0;
}
int CALLBACK WinMain(HINSTANCE instance, HINSTANCE prev_instance, LPSTR cmd_line, int show_code)
{
    timer::init();

    QueryPerformanceCounter((LARGE_INTEGER *)&mem.profile);
    timer::start(Timer_Startup);

    mem.is_running = true;

    // Set current path to this executable's path
    {
        HMODULE module = GetModuleHandleA(NULL);
        char path_string[MAX_PATH];
        uint32 path_len = GetModuleFileNameA(module, path_string, MAX_PATH);
        if (path_len != -1) {
            char *last_slash = strrchr(path_string, '\\');
            if (last_slash) { *last_slash = '\0'; }
            SetCurrentDirectoryA(path_string);
        }
    }

    HWND window;
    // Create window
    {
        WNDCLASSA window_class = {};
        window_class.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
        window_class.lpfnWndProc = Win32MainWindowCallback;
        window_class.hInstance = instance;
        const char* ico_path = "papaya.ico";
        window_class.hIcon = (HICON)LoadImage(0, ico_path, IMAGE_ICON, 0, 0, LR_LOADFROMFILE | LR_DEFAULTSIZE | LR_SHARED);
        window_class.lpszClassName = "PapayaWindowClass";

        if (!RegisterClassA(&window_class)) {
            // TODO: Log: Register window class failed
            return 0;
        }

        window =
            CreateWindowExA(
            0,                                                          // Extended window style
            window_class.lpszClassName,                                  // Class name,
            "Papaya",                                                   // Name,
            WS_POPUP | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_VISIBLE,    // window style
            CW_USEDEFAULT,                                              // X,
            CW_USEDEFAULT,                                              // Y,
            CW_USEDEFAULT,                                              // width,
            CW_USEDEFAULT,                                              // height,
            0,                                                          // window Parent,
            0,                                                          // Menu,
            instance,                                                   // Handle to the instance,
            0);                                                         // lpParam

        if (!window) {
            // TODO: Log: Create window failed
            return 0;
        }

        SystemParametersInfo(SPI_GETWORKAREA, 0, &windows_work_area, 0);

#ifdef PAPAYARELEASE

        SetWindowPos(window, HWND_TOP, 0, 0, 600, 600, NULL);
        ShowWindow(window, SW_MAXIMIZE);
#else
        uint32 screen_width = GetSystemMetrics(SM_CXSCREEN);
        uint32 screen_height = GetSystemMetrics(SM_CYSCREEN);

        mem.window.width = (uint32)((float)screen_width * 0.5);
        mem.window.height = (uint32)((float)screen_height * 0.8);

        uint32 window_x = (screen_width - mem.window.width) / 2;
        uint32 window_y = (screen_height - mem.window.height) / 2;

        SetWindowPos(window, HWND_TOP, window_x, window_y, mem.window.width, mem.window.height, NULL);
#endif // PAPAYARELEASE

        // Get window size
        {
            RECT window_rect = { 0 };
            BOOL foo = GetClientRect(window, &window_rect);
            mem.window.width = window_rect.right - window_rect.left;
            mem.window.height = window_rect.bottom - window_rect.top;
        }
    }

    // Initialize OpenGL
    {
        device_context = GetDC(window);

        // Setup pixel format
        {
            PIXELFORMATDESCRIPTOR pixel_format_desc = { 0 };
            // TODO: Program seems to work perfectly fine without all other params except dwFlags.
            //       Can we skip other params for the sake of brevity?
            pixel_format_desc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
            pixel_format_desc.nVersion = 1;
            pixel_format_desc.dwFlags = PFD_SUPPORT_OPENGL | PFD_DRAW_TO_WINDOW | PFD_DOUBLEBUFFER;
            pixel_format_desc.iPixelType = PFD_TYPE_RGBA;
            pixel_format_desc.cColorBits = 32;
            pixel_format_desc.cDepthBits = 32;
            pixel_format_desc.dwLayerMask = PFD_MAIN_PLANE;
            //

            int32 pixel_format = ChoosePixelFormat(device_context, &pixel_format_desc);
            if (!pixel_format) { exit(1); } // TODO: Log: Choose pixel format failed
            if (!SetPixelFormat(device_context, pixel_format, &pixel_format_desc)) { exit(1); } // TODO: Log: Set pixel format failed
        }

        // Create rendering context
        {
            // TODO: Create "proper" context?
            //       https://www.opengl.org/wiki/Creating_an_OpenGL_Context_(WGL)#Proper_Context_Creation

            HGLRC rendering_context = wglCreateContext(device_context);
            wglMakeCurrent(device_context, rendering_context);

            if (!gl_lite_init()) { exit(1); }

            glGetIntegerv(GL_MAJOR_VERSION, &mem.system.gl_version[0]);
            glGetIntegerv(GL_MINOR_VERSION, &mem.system.gl_version[1]);
        }

        // Disable vsync
        //if (wglewIsSupported("WGL_EXT_swap_control")) { wglSwapIntervalEXT(0); }
    }

    // Initialize tablet
    EasyTab_Load(window);

    core::init(&mem);

    // Initialize ImGui
    {
        ImGuiIO& io = ImGui::GetIO();
        io.KeyMap[ImGuiKey_Tab] = VK_TAB;          // Keyboard mapping. ImGui will use those indices to peek into the io.KeyDown[] array that we will update during the application lifetime.
        io.KeyMap[ImGuiKey_LeftArrow] = VK_LEFT;
        io.KeyMap[ImGuiKey_RightArrow] = VK_RIGHT;
        io.KeyMap[ImGuiKey_UpArrow] = VK_UP;
        io.KeyMap[ImGuiKey_DownArrow] = VK_DOWN;
        io.KeyMap[ImGuiKey_Home] = VK_HOME;
        io.KeyMap[ImGuiKey_End] = VK_END;
        io.KeyMap[ImGuiKey_Delete] = VK_DELETE;
        io.KeyMap[ImGuiKey_Backspace] = VK_BACK;
        io.KeyMap[ImGuiKey_Enter] = VK_RETURN;
        io.KeyMap[ImGuiKey_Escape] = VK_ESCAPE;
        io.KeyMap[ImGuiKey_A] = 'A';
        io.KeyMap[ImGuiKey_C] = 'C';
        io.KeyMap[ImGuiKey_V] = 'V';
        io.KeyMap[ImGuiKey_X] = 'X';
        io.KeyMap[ImGuiKey_Y] = 'Y';
        io.KeyMap[ImGuiKey_Z] = 'Z';

        io.RenderDrawListsFn = core::render_imgui;
        io.ImeWindowHandle = window;
    }

    mem.window.menu_horizontal_offset = 32;
    mem.window.title_bar_buttons_width = 109;
    mem.window.title_bar_height = 30;

    timer::stop(Timer_Startup);

    // Handle command line arguments (if present)
    if (strlen(cmd_line)) {
        // Remove double quotes from string if present
        char* ptr_read  = cmd_line;
        char* ptr_write = cmd_line;
        while (*ptr_read) 
        {
            *ptr_write = *ptr_read++;
            if (*ptr_write != '\"') { ptr_write++; }
        }
        *ptr_write = '\0';
        core::open_doc(cmd_line, &mem); 
    }

#ifdef PAPAYA_DEFAULT_IMAGE
    core::open_doc(PAPAYA_DEFAULT_IMAGE, &mem);
#endif // PAPAYA_DEFAULT_IMAGE

    while (mem.is_running) {
        timer::start(Timer_Frame);

        // Windows message handling
        {
            MSG msg;
            while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
            {
                if (msg.message == WM_QUIT) {
                    mem.is_running = false;
                }

                TranslateMessage(&msg);
                DispatchMessageA(&msg);
            }
        }

        // Tablet input // TODO: Put this in papaya.cpp
        {
            mem.tablet.pressure = EasyTab->Pressure;
            mem.tablet.pos.x = EasyTab->PosX;
            mem.tablet.pos.y = EasyTab->PosY;
            mem.tablet.buttons = EasyTab->Buttons;
        }

        BOOL is_maximized = IsMaximized(window);
        if (IsIconic(window)) { goto EndOfFrame; }

        // Start new ImGui frame
        {
            ImGuiIO& io = ImGui::GetIO();

            // Setup display size (every frame to accommodate for window resizing)
            RECT rect;
            GetClientRect(window, &rect);
            io.DisplaySize = ImVec2((float)(rect.right - rect.left), (float)(rect.bottom - rect.top));

            // Read keyboard modifiers inputs
            io.KeyCtrl = (GetKeyState(VK_CONTROL) & 0x8000) != 0;
            io.KeyShift = (GetKeyState(VK_SHIFT) & 0x8000) != 0;
            io.KeyAlt = (GetKeyState(VK_MENU) & 0x8000) != 0;

            // Setup time step
            INT64 current_time;
            QueryPerformanceCounter((LARGE_INTEGER *)&current_time);
            io.DeltaTime = (float)(current_time - mem.profile.current_time) * 
                           (float)timer::get_freq() / 1000.0f;
            mem.profile.current_time = current_time; // TODO: Move Imgui timers from Debug to their own struct

            // Hide OS mouse cursor if ImGui is drawing it
            //SetCursor(io.MouseDrawCursor ? NULL : LoadCursor(NULL, IDC_ARROW));

            // Start the frame
            ImGui::NewFrame();
        }

        // Title Bar Icon
        {
            ImGui::SetNextWindowSize(ImVec2((float)mem.window.menu_horizontal_offset,(float)mem.window.title_bar_height));
            ImGui::SetNextWindowPos(ImVec2(1.0f, 1.0f));

            ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0);
            ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(2,2));
            ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0));
            ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0,0));
            ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));

            ImGui::PushStyleColor(ImGuiCol_WindowBg, mem.colors[PapayaCol_Transparent]);

            bool bTrue = true;
            ImGui::Begin("Title Bar Icon", &bTrue, mem.window.default_imgui_flags);

            #define CALCUV(X, Y) ImVec2((float)X/256.0f, (float)Y/256.0f)
            ImGui::Image((void*)(intptr_t)mem.textures[PapayaTex_UI], ImVec2(28,28), CALCUV(0,200), CALCUV(28,228));
            #undef CALCUV

            ImGui::End();

            ImGui::PopStyleColor(1);
            ImGui::PopStyleVar(5);
        }

        // Title Bar Buttons
        {
            ImGui::SetNextWindowSize(ImVec2((float)mem.window.title_bar_buttons_width,24.0f));
            ImGui::SetNextWindowPos(ImVec2((float)mem.window.width - mem.window.title_bar_buttons_width, 0.0f));

            ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0);
            ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0,0));
            ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0));
            ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, ImVec2(0,0));
            ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0));

            ImGui::PushStyleColor(ImGuiCol_Button, mem.colors[PapayaCol_Transparent]);
            ImGui::PushStyleColor(ImGuiCol_ButtonHovered, mem.colors[PapayaCol_ButtonHover]);
            ImGui::PushStyleColor(ImGuiCol_ButtonActive, mem.colors[PapayaCol_ButtonActive]);
            ImGui::PushStyleColor(ImGuiCol_WindowBg, mem.colors[PapayaCol_Transparent]);

            bool bTrue = true;

            #define CALCUV(X, Y) ImVec2((float)X/256.0f, (float)Y/256.0f)
            ImGui::Begin("Title Bar Buttons", &bTrue, mem.window.default_imgui_flags);

            ImGui::PushID(0);
            if(ImGui::ImageButton((void*)(size_t)mem.textures[PapayaTex_UI], 
                                  ImVec2(34,26), CALCUV(62,200), CALCUV(96,226),
                                  1, ImVec4(0,0,0,0))) {
                ShowWindow(window, SW_MINIMIZE);
            }

            ImVec2 start_uv = is_maximized ? CALCUV(28,226) : CALCUV(62,226);
            ImVec2 end_uv = is_maximized ? CALCUV(62,252) : CALCUV(96,252);

            ImGui::PopID();
            ImGui::SameLine();
            ImGui::PushID(1);

            if(ImGui::ImageButton((void*)(size_t)mem.textures[PapayaTex_UI],
                                  ImVec2(34,26), start_uv, end_uv,
                                  1, ImVec4(0,0,0,0))) {
                if (is_maximized) {
                    ShowWindow(window, SW_RESTORE);
                } else {
                    ShowWindow(window, SW_MAXIMIZE);
                }
            }

            ImGui::PopID();
            ImGui::SameLine();
            ImGui::PushID(2);

            if(ImGui::ImageButton((void*)(size_t)mem.textures[PapayaTex_UI],
                                  ImVec2(34,26), CALCUV(28,200), CALCUV(62,226),
                                  1, ImVec4(0,0,0,0))) {
                SendMessage(window, WM_CLOSE, 0, 0);
            }

            ImGui::PopID();
            ImGui::End();
            #undef CALCUV

            ImGui::PopStyleVar(5);
            ImGui::PopStyleColor(4);
        }

        // ImGui::ShowTestWindow();
        core::update(&mem);
        SwapBuffers(device_context);

    EndOfFrame:
        timer::stop(Timer_Frame);
        double frame_rate = (mem.current_tool == PapayaTool_Brush && mem.mouse.is_down[0]) ?
                           500.0 : 60.0;
        double frame_time = 1000.0 / frame_rate;
        double sleep_time = frame_time - timers[Timer_Frame].elapsed_ms;
        timers[Timer_Sleep].elapsed_ms = sleep_time;
        if (sleep_time > 0) { Sleep((int32)sleep_time); }
    }

    core::destroy(&mem);

    EasyTab_Unload();

    return 0;
}