/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Generic Win32 window class.
 *//*--------------------------------------------------------------------*/

#include "tcuWin32Window.hpp"

namespace tcu
{
namespace win32
{

static LRESULT CALLBACK windowProcCallback(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    Window *window = reinterpret_cast<Window *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
    if (window)
        return window->windowProc(uMsg, wParam, lParam);
    else
        return DefWindowProc(hWnd, uMsg, wParam, lParam);
}

Window::Window(HINSTANCE instance, int width, int height) : m_window(DE_NULL)
{
    try
    {
        static const char s_className[]  = "dEQP Test Process Class";
        static const char s_windowName[] = "dEQP Test Process";

        {
            WNDCLASS wndClass;
            memset(&wndClass, 0, sizeof(wndClass));
            wndClass.style         = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
            wndClass.lpfnWndProc   = windowProcCallback;
            wndClass.cbClsExtra    = 0;
            wndClass.cbWndExtra    = 0;
            wndClass.hInstance     = instance;
            wndClass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);
            wndClass.hCursor       = LoadCursor(NULL, IDC_ARROW);
            wndClass.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
            wndClass.lpszMenuName  = NULL;
            wndClass.lpszClassName = s_className;

            RegisterClass(&wndClass);
        }

        m_window = CreateWindow(s_className, s_windowName, WS_CLIPCHILDREN | WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT,
                                width, height, NULL, NULL, instance, NULL);

        if (!m_window)
            TCU_THROW(ResourceError, "Failed to create Win32 window");

        // Store this as userdata
        SetWindowLongPtr(m_window, GWLP_USERDATA, (LONG_PTR)this);

        setSize(width, height);
    }
    catch (...)
    {
        if (m_window)
            DestroyWindow(m_window);

        throw;
    }
}

Window::~Window(void)
{
    if (m_window)
    {
        // Clear this pointer from windowproc
        SetWindowLongPtr(m_window, GWLP_USERDATA, 0);
    }

    DestroyWindow(m_window);
}

void Window::setVisible(bool visible)
{
    ShowWindow(m_window, visible ? SW_SHOW : SW_HIDE);
}

void Window::setSize(int width, int height)
{
    RECT rc;

    rc.left   = 0;
    rc.top    = 0;
    rc.right  = width;
    rc.bottom = height;

    if (!AdjustWindowRect(&rc, GetWindowLong(m_window, GWL_STYLE), GetMenu(m_window) != NULL))
        TCU_THROW(TestError, "AdjustWindowRect() failed");

    if (!SetWindowPos(m_window, NULL, 0, 0, rc.right - rc.left, rc.bottom - rc.top,
                      SWP_NOACTIVATE | SWP_NOCOPYBITS | SWP_NOMOVE | SWP_NOZORDER))
        TCU_THROW(TestError, "SetWindowPos() failed");
}

IVec2 Window::getSize(void) const
{
    RECT rc;
    if (!GetClientRect(m_window, &rc))
        TCU_THROW(TestError, "GetClientRect() failed");

    return IVec2(rc.right - rc.left, rc.bottom - rc.top);
}

void Window::processEvents(void)
{
    MSG msg;
    while (PeekMessage(&msg, m_window, 0, 0, PM_REMOVE))
        DispatchMessage(&msg);
}

LRESULT Window::windowProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    switch (uMsg)
    {
        // \todo [2014-03-12 pyry] Handle WM_SIZE?

    case WM_DESTROY:
        PostQuitMessage(0);
        return 0;

    case WM_KEYDOWN:
        if (wParam == VK_ESCAPE)
        {
            PostQuitMessage(0);
            return 0;
        }
        // fall-through

    default:
        return DefWindowProc(m_window, uMsg, wParam, lParam);
    }
}

} // namespace win32
} // namespace tcu
