//
// Copyright 2014 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//

// Win32Window.cpp: Implementation of OSWindow for Win32 (Windows)

#include "util/windows/win32/Win32Window.h"

#include <sstream>

#include "common/debug.h"

Key VirtualKeyCodeToKey(WPARAM key, LPARAM flags)
{
    switch (key)
    {
        // Check the scancode to distinguish between left and right shift
        case VK_SHIFT:
        {
            static unsigned int lShift = MapVirtualKey(VK_LSHIFT, MAPVK_VK_TO_VSC);
            unsigned int scancode      = static_cast<unsigned int>((flags & (0xFF << 16)) >> 16);
            return scancode == lShift ? KEY_LSHIFT : KEY_RSHIFT;
        }

        // Check the "extended" flag to distinguish between left and right alt
        case VK_MENU:
            return (HIWORD(flags) & KF_EXTENDED) ? KEY_RALT : KEY_LALT;

        // Check the "extended" flag to distinguish between left and right control
        case VK_CONTROL:
            return (HIWORD(flags) & KF_EXTENDED) ? KEY_RCONTROL : KEY_LCONTROL;

        // Other keys are reported properly
        case VK_LWIN:
            return KEY_LSYSTEM;
        case VK_RWIN:
            return KEY_RSYSTEM;
        case VK_APPS:
            return KEY_MENU;
        case VK_OEM_1:
            return KEY_SEMICOLON;
        case VK_OEM_2:
            return KEY_SLASH;
        case VK_OEM_PLUS:
            return KEY_EQUAL;
        case VK_OEM_MINUS:
            return KEY_DASH;
        case VK_OEM_4:
            return KEY_LBRACKET;
        case VK_OEM_6:
            return KEY_RBRACKET;
        case VK_OEM_COMMA:
            return KEY_COMMA;
        case VK_OEM_PERIOD:
            return KEY_PERIOD;
        case VK_OEM_7:
            return KEY_QUOTE;
        case VK_OEM_5:
            return KEY_BACKSLASH;
        case VK_OEM_3:
            return KEY_TILDE;
        case VK_ESCAPE:
            return KEY_ESCAPE;
        case VK_SPACE:
            return KEY_SPACE;
        case VK_RETURN:
            return KEY_RETURN;
        case VK_BACK:
            return KEY_BACK;
        case VK_TAB:
            return KEY_TAB;
        case VK_PRIOR:
            return KEY_PAGEUP;
        case VK_NEXT:
            return KEY_PAGEDOWN;
        case VK_END:
            return KEY_END;
        case VK_HOME:
            return KEY_HOME;
        case VK_INSERT:
            return KEY_INSERT;
        case VK_DELETE:
            return KEY_DELETE;
        case VK_ADD:
            return KEY_ADD;
        case VK_SUBTRACT:
            return KEY_SUBTRACT;
        case VK_MULTIPLY:
            return KEY_MULTIPLY;
        case VK_DIVIDE:
            return KEY_DIVIDE;
        case VK_PAUSE:
            return KEY_PAUSE;
        case VK_F1:
            return KEY_F1;
        case VK_F2:
            return KEY_F2;
        case VK_F3:
            return KEY_F3;
        case VK_F4:
            return KEY_F4;
        case VK_F5:
            return KEY_F5;
        case VK_F6:
            return KEY_F6;
        case VK_F7:
            return KEY_F7;
        case VK_F8:
            return KEY_F8;
        case VK_F9:
            return KEY_F9;
        case VK_F10:
            return KEY_F10;
        case VK_F11:
            return KEY_F11;
        case VK_F12:
            return KEY_F12;
        case VK_F13:
            return KEY_F13;
        case VK_F14:
            return KEY_F14;
        case VK_F15:
            return KEY_F15;
        case VK_LEFT:
            return KEY_LEFT;
        case VK_RIGHT:
            return KEY_RIGHT;
        case VK_UP:
            return KEY_UP;
        case VK_DOWN:
            return KEY_DOWN;
        case VK_NUMPAD0:
            return KEY_NUMPAD0;
        case VK_NUMPAD1:
            return KEY_NUMPAD1;
        case VK_NUMPAD2:
            return KEY_NUMPAD2;
        case VK_NUMPAD3:
            return KEY_NUMPAD3;
        case VK_NUMPAD4:
            return KEY_NUMPAD4;
        case VK_NUMPAD5:
            return KEY_NUMPAD5;
        case VK_NUMPAD6:
            return KEY_NUMPAD6;
        case VK_NUMPAD7:
            return KEY_NUMPAD7;
        case VK_NUMPAD8:
            return KEY_NUMPAD8;
        case VK_NUMPAD9:
            return KEY_NUMPAD9;
        case 'A':
            return KEY_A;
        case 'Z':
            return KEY_Z;
        case 'E':
            return KEY_E;
        case 'R':
            return KEY_R;
        case 'T':
            return KEY_T;
        case 'Y':
            return KEY_Y;
        case 'U':
            return KEY_U;
        case 'I':
            return KEY_I;
        case 'O':
            return KEY_O;
        case 'P':
            return KEY_P;
        case 'Q':
            return KEY_Q;
        case 'S':
            return KEY_S;
        case 'D':
            return KEY_D;
        case 'F':
            return KEY_F;
        case 'G':
            return KEY_G;
        case 'H':
            return KEY_H;
        case 'J':
            return KEY_J;
        case 'K':
            return KEY_K;
        case 'L':
            return KEY_L;
        case 'M':
            return KEY_M;
        case 'W':
            return KEY_W;
        case 'X':
            return KEY_X;
        case 'C':
            return KEY_C;
        case 'V':
            return KEY_V;
        case 'B':
            return KEY_B;
        case 'N':
            return KEY_N;
        case '0':
            return KEY_NUM0;
        case '1':
            return KEY_NUM1;
        case '2':
            return KEY_NUM2;
        case '3':
            return KEY_NUM3;
        case '4':
            return KEY_NUM4;
        case '5':
            return KEY_NUM5;
        case '6':
            return KEY_NUM6;
        case '7':
            return KEY_NUM7;
        case '8':
            return KEY_NUM8;
        case '9':
            return KEY_NUM9;
    }

    return Key(0);
}

LRESULT CALLBACK Win32Window::WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
        case WM_NCCREATE:
        {
            LPCREATESTRUCT pCreateStruct = reinterpret_cast<LPCREATESTRUCT>(lParam);
            SetWindowLongPtr(hWnd, GWLP_USERDATA,
                             reinterpret_cast<LONG_PTR>(pCreateStruct->lpCreateParams));
            return DefWindowProcA(hWnd, message, wParam, lParam);
        }
    }

    Win32Window *window = reinterpret_cast<Win32Window *>(GetWindowLongPtr(hWnd, GWLP_USERDATA));
    if (window)
    {
        switch (message)
        {
            case WM_DESTROY:
            case WM_CLOSE:
            {
                Event event;
                event.Type = Event::EVENT_CLOSED;
                window->pushEvent(event);
                break;
            }

            case WM_MOVE:
            {
                RECT winRect;
                GetClientRect(hWnd, &winRect);

                POINT topLeft;
                topLeft.x = winRect.left;
                topLeft.y = winRect.top;
                ClientToScreen(hWnd, &topLeft);

                Event event;
                event.Type   = Event::EVENT_MOVED;
                event.Move.X = topLeft.x;
                event.Move.Y = topLeft.y;
                window->pushEvent(event);

                break;
            }

            case WM_SIZE:
            {
                RECT winRect;
                GetClientRect(hWnd, &winRect);

                POINT topLeft;
                topLeft.x = winRect.left;
                topLeft.y = winRect.top;
                ClientToScreen(hWnd, &topLeft);

                POINT botRight;
                botRight.x = winRect.right;
                botRight.y = winRect.bottom;
                ClientToScreen(hWnd, &botRight);

                Event event;
                event.Type        = Event::EVENT_RESIZED;
                event.Size.Width  = botRight.x - topLeft.x;
                event.Size.Height = botRight.y - topLeft.y;
                window->pushEvent(event);

                break;
            }

            case WM_SETFOCUS:
            {
                Event event;
                event.Type = Event::EVENT_GAINED_FOCUS;
                window->pushEvent(event);
                break;
            }

            case WM_KILLFOCUS:
            {
                Event event;
                event.Type = Event::EVENT_LOST_FOCUS;
                window->pushEvent(event);
                break;
            }

            case WM_KEYDOWN:
            case WM_SYSKEYDOWN:
            case WM_KEYUP:
            case WM_SYSKEYUP:
            {
                bool down = (message == WM_KEYDOWN || message == WM_SYSKEYDOWN);

                Event event;
                event.Type        = down ? Event::EVENT_KEY_PRESSED : Event::EVENT_KEY_RELEASED;
                event.Key.Alt     = HIWORD(GetAsyncKeyState(VK_MENU)) != 0;
                event.Key.Control = HIWORD(GetAsyncKeyState(VK_CONTROL)) != 0;
                event.Key.Shift   = HIWORD(GetAsyncKeyState(VK_SHIFT)) != 0;
                event.Key.System =
                    HIWORD(GetAsyncKeyState(VK_LWIN)) || HIWORD(GetAsyncKeyState(VK_RWIN));
                event.Key.Code = VirtualKeyCodeToKey(wParam, lParam);
                window->pushEvent(event);

                break;
            }

            case WM_MOUSEWHEEL:
            {
                Event event;
                event.Type             = Event::EVENT_MOUSE_WHEEL_MOVED;
                event.MouseWheel.Delta = static_cast<short>(HIWORD(wParam)) / 120;
                window->pushEvent(event);
                break;
            }

            case WM_LBUTTONDOWN:
            case WM_LBUTTONDBLCLK:
            {
                Event event;
                event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
                event.MouseButton.Button = MOUSEBUTTON_LEFT;
                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
                window->pushEvent(event);
                break;
            }

            case WM_LBUTTONUP:
            {
                Event event;
                event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
                event.MouseButton.Button = MOUSEBUTTON_LEFT;
                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
                window->pushEvent(event);
                break;
            }

            case WM_RBUTTONDOWN:
            case WM_RBUTTONDBLCLK:
            {
                Event event;
                event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
                event.MouseButton.Button = MOUSEBUTTON_RIGHT;
                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
                window->pushEvent(event);
                break;
            }

            // Mouse right button up event
            case WM_RBUTTONUP:
            {
                Event event;
                event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
                event.MouseButton.Button = MOUSEBUTTON_RIGHT;
                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
                window->pushEvent(event);
                break;
            }

            // Mouse wheel button down event
            case WM_MBUTTONDOWN:
            case WM_MBUTTONDBLCLK:
            {
                Event event;
                event.Type               = Event::EVENT_MOUSE_BUTTON_PRESSED;
                event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
                window->pushEvent(event);
                break;
            }

            // Mouse wheel button up event
            case WM_MBUTTONUP:
            {
                Event event;
                event.Type               = Event::EVENT_MOUSE_BUTTON_RELEASED;
                event.MouseButton.Button = MOUSEBUTTON_MIDDLE;
                event.MouseButton.X      = static_cast<short>(LOWORD(lParam));
                event.MouseButton.Y      = static_cast<short>(HIWORD(lParam));
                window->pushEvent(event);
                break;
            }

            // Mouse X button down event
            case WM_XBUTTONDOWN:
            case WM_XBUTTONDBLCLK:
            {
                Event event;
                event.Type = Event::EVENT_MOUSE_BUTTON_PRESSED;
                event.MouseButton.Button =
                    (HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
                event.MouseButton.X = static_cast<short>(LOWORD(lParam));
                event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
                window->pushEvent(event);
                break;
            }

            // Mouse X button up event
            case WM_XBUTTONUP:
            {
                Event event;
                event.Type = Event::EVENT_MOUSE_BUTTON_RELEASED;
                event.MouseButton.Button =
                    (HIWORD(wParam) == XBUTTON1) ? MOUSEBUTTON_BUTTON4 : MOUSEBUTTON_BUTTON5;
                event.MouseButton.X = static_cast<short>(LOWORD(lParam));
                event.MouseButton.Y = static_cast<short>(HIWORD(lParam));
                window->pushEvent(event);
                break;
            }

            case WM_MOUSEMOVE:
            {
                if (!window->mIsMouseInWindow)
                {
                    window->mIsMouseInWindow = true;
                    Event event;
                    event.Type = Event::EVENT_MOUSE_ENTERED;
                    window->pushEvent(event);
                }

                int mouseX = static_cast<short>(LOWORD(lParam));
                int mouseY = static_cast<short>(HIWORD(lParam));

                Event event;
                event.Type        = Event::EVENT_MOUSE_MOVED;
                event.MouseMove.X = mouseX;
                event.MouseMove.Y = mouseY;
                window->pushEvent(event);
                break;
            }

            case WM_MOUSELEAVE:
            {
                Event event;
                event.Type = Event::EVENT_MOUSE_LEFT;
                window->pushEvent(event);
                window->mIsMouseInWindow = false;
                break;
            }

            case WM_USER:
            {
                Event testEvent;
                testEvent.Type = Event::EVENT_TEST;
                window->pushEvent(testEvent);
                break;
            }
        }
    }
    return DefWindowProcA(hWnd, message, wParam, lParam);
}

Win32Window::Win32Window()
    : mIsVisible(false),
      mIsMouseInWindow(false),
      mNativeWindow(0),
      mParentWindow(0),
      mNativeDisplay(0)
{}

Win32Window::~Win32Window()
{
    destroy();
}

bool Win32Window::initialize(const std::string &name, int width, int height)
{
    destroy();

    // Use a new window class name for ever window to ensure that a new window can be created
    // even if the last one was not properly destroyed
    static size_t windowIdx = 0;
    std::ostringstream nameStream;
    nameStream << name << "_" << windowIdx++;

    mParentClassName = nameStream.str();
    mChildClassName  = mParentClassName + "_Child";

    // Work around compile error from not defining "UNICODE" while Chromium does
    const LPSTR idcArrow = MAKEINTRESOURCEA(32512);

    WNDCLASSEXA parentWindowClass   = {};
    parentWindowClass.cbSize        = sizeof(WNDCLASSEXA);
    parentWindowClass.style         = 0;
    parentWindowClass.lpfnWndProc   = WndProc;
    parentWindowClass.cbClsExtra    = 0;
    parentWindowClass.cbWndExtra    = 0;
    parentWindowClass.hInstance     = GetModuleHandle(nullptr);
    parentWindowClass.hIcon         = nullptr;
    parentWindowClass.hCursor       = LoadCursorA(nullptr, idcArrow);
    parentWindowClass.hbrBackground = 0;
    parentWindowClass.lpszMenuName  = nullptr;
    parentWindowClass.lpszClassName = mParentClassName.c_str();
    if (!RegisterClassExA(&parentWindowClass))
    {
        return false;
    }

    WNDCLASSEXA childWindowClass   = {};
    childWindowClass.cbSize        = sizeof(WNDCLASSEXA);
    childWindowClass.style         = CS_OWNDC;
    childWindowClass.lpfnWndProc   = WndProc;
    childWindowClass.cbClsExtra    = 0;
    childWindowClass.cbWndExtra    = 0;
    childWindowClass.hInstance     = GetModuleHandle(nullptr);
    childWindowClass.hIcon         = nullptr;
    childWindowClass.hCursor       = LoadCursorA(nullptr, idcArrow);
    childWindowClass.hbrBackground = 0;
    childWindowClass.lpszMenuName  = nullptr;
    childWindowClass.lpszClassName = mChildClassName.c_str();
    if (!RegisterClassExA(&childWindowClass))
    {
        return false;
    }

    DWORD parentStyle = WS_CAPTION | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_SYSMENU;
    DWORD parentExtendedStyle = WS_EX_APPWINDOW | WS_EX_TOOLWINDOW;

    RECT sizeRect = {0, 0, static_cast<LONG>(width), static_cast<LONG>(height)};
    AdjustWindowRectEx(&sizeRect, parentStyle, FALSE, parentExtendedStyle);

    mParentWindow = CreateWindowExA(parentExtendedStyle, mParentClassName.c_str(), name.c_str(),
                                    parentStyle, CW_USEDEFAULT, CW_USEDEFAULT,
                                    sizeRect.right - sizeRect.left, sizeRect.bottom - sizeRect.top,
                                    nullptr, nullptr, GetModuleHandle(nullptr), this);

    mNativeWindow = CreateWindowExA(0, mChildClassName.c_str(), name.c_str(), WS_CHILD, 0, 0,
                                    static_cast<int>(width), static_cast<int>(height),
                                    mParentWindow, nullptr, GetModuleHandle(nullptr), this);

    mNativeDisplay = GetDC(mNativeWindow);
    if (!mNativeDisplay)
    {
        destroy();
        return false;
    }

    return true;
}

void Win32Window::destroy()
{
    if (mNativeDisplay)
    {
        ReleaseDC(mNativeWindow, mNativeDisplay);
        mNativeDisplay = 0;
    }

    if (mNativeWindow)
    {
        DestroyWindow(mNativeWindow);
        mNativeWindow = 0;
    }

    if (mParentWindow)
    {
        DestroyWindow(mParentWindow);
        mParentWindow = 0;
    }

    UnregisterClassA(mParentClassName.c_str(), nullptr);
    UnregisterClassA(mChildClassName.c_str(), nullptr);
}

bool Win32Window::takeScreenshot(uint8_t *pixelData)
{
    if (mIsVisible)
    {
        return false;
    }

    bool error = false;

    // Hack for DWM: There is no way to wait for DWM animations to finish, so we just have to wait
    // for a while before issuing screenshot if window was just made visible.
    {
        static const double WAIT_WINDOW_VISIBLE_MS = 0.5;  // Half a second for the animation
        double timeSinceVisible                    = mSetVisibleTimer.getElapsedTime();

        if (timeSinceVisible < WAIT_WINDOW_VISIBLE_MS)
        {
            Sleep(static_cast<DWORD>((WAIT_WINDOW_VISIBLE_MS - timeSinceVisible) * 1000));
        }
    }

    HDC screenDC      = nullptr;
    HDC windowDC      = nullptr;
    HDC tmpDC         = nullptr;
    HBITMAP tmpBitmap = nullptr;

    if (!error)
    {
        screenDC = GetDC(HWND_DESKTOP);
        error    = screenDC == nullptr;
    }

    if (!error)
    {
        windowDC = GetDC(mNativeWindow);
        error    = windowDC == nullptr;
    }

    if (!error)
    {
        tmpDC = CreateCompatibleDC(screenDC);
        error = tmpDC == nullptr;
    }

    if (!error)
    {
        tmpBitmap = CreateCompatibleBitmap(screenDC, mWidth, mHeight);
        error     = tmpBitmap == nullptr;
    }

    POINT topLeft = {0, 0};
    if (!error)
    {
        error = (MapWindowPoints(mNativeWindow, HWND_DESKTOP, &topLeft, 1) == 0);
    }

    if (!error)
    {
        error = SelectObject(tmpDC, tmpBitmap) == nullptr;
    }

    if (!error)
    {
        error = BitBlt(tmpDC, 0, 0, mWidth, mHeight, screenDC, topLeft.x, topLeft.y, SRCCOPY) == 0;
    }

    if (!error)
    {
        BITMAPINFOHEADER bitmapInfo;
        bitmapInfo.biSize          = sizeof(BITMAPINFOHEADER);
        bitmapInfo.biWidth         = mWidth;
        bitmapInfo.biHeight        = -mHeight;
        bitmapInfo.biPlanes        = 1;
        bitmapInfo.biBitCount      = 32;
        bitmapInfo.biCompression   = BI_RGB;
        bitmapInfo.biSizeImage     = 0;
        bitmapInfo.biXPelsPerMeter = 0;
        bitmapInfo.biYPelsPerMeter = 0;
        bitmapInfo.biClrUsed       = 0;
        bitmapInfo.biClrImportant  = 0;
        int getBitsResult          = GetDIBits(screenDC, tmpBitmap, 0, mHeight, pixelData,
                                      reinterpret_cast<BITMAPINFO *>(&bitmapInfo), DIB_RGB_COLORS);
        error                      = (getBitsResult == 0);
    }

    if (tmpBitmap != nullptr)
    {
        DeleteObject(tmpBitmap);
    }
    if (tmpDC != nullptr)
    {
        DeleteDC(tmpDC);
    }
    if (screenDC != nullptr)
    {
        ReleaseDC(nullptr, screenDC);
    }
    if (windowDC != nullptr)
    {
        ReleaseDC(mNativeWindow, windowDC);
    }

    return !error;
}

void Win32Window::resetNativeWindow() {}

EGLNativeWindowType Win32Window::getNativeWindow() const
{
    return mNativeWindow;
}

EGLNativeDisplayType Win32Window::getNativeDisplay() const
{
    return mNativeDisplay;
}

void Win32Window::messageLoop()
{
    MSG msg;
    while (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

void Win32Window::setMousePosition(int x, int y)
{
    RECT winRect;
    GetClientRect(mNativeWindow, &winRect);

    POINT topLeft;
    topLeft.x = winRect.left;
    topLeft.y = winRect.top;
    ClientToScreen(mNativeWindow, &topLeft);

    SetCursorPos(topLeft.x + x, topLeft.y + y);
}

bool Win32Window::setPosition(int x, int y)
{
    if (mX == x && mY == y)
    {
        return true;
    }

    RECT windowRect;
    if (!GetWindowRect(mParentWindow, &windowRect))
    {
        return false;
    }

    if (!MoveWindow(mParentWindow, x, y, windowRect.right - windowRect.left,
                    windowRect.bottom - windowRect.top, TRUE))
    {
        return false;
    }

    return true;
}

bool Win32Window::resize(int width, int height)
{
    if (width == mWidth && height == mHeight)
    {
        return true;
    }

    RECT windowRect;
    if (!GetWindowRect(mParentWindow, &windowRect))
    {
        return false;
    }

    RECT clientRect;
    if (!GetClientRect(mParentWindow, &clientRect))
    {
        return false;
    }

    LONG diffX = (windowRect.right - windowRect.left) - clientRect.right;
    LONG diffY = (windowRect.bottom - windowRect.top) - clientRect.bottom;
    if (!MoveWindow(mParentWindow, windowRect.left, windowRect.top, width + diffX, height + diffY,
                    TRUE))
    {
        return false;
    }

    if (!MoveWindow(mNativeWindow, 0, 0, width, height, FALSE))
    {
        return false;
    }

    return true;
}

void Win32Window::setVisible(bool isVisible)
{
    int flag = (isVisible ? SW_SHOW : SW_HIDE);

    ShowWindow(mParentWindow, flag);
    ShowWindow(mNativeWindow, flag);

    if (isVisible)
    {
        mSetVisibleTimer.stop();
        mSetVisibleTimer.start();
    }
}

void Win32Window::pushEvent(Event event)
{
    OSWindow::pushEvent(event);

    switch (event.Type)
    {
        case Event::EVENT_RESIZED:
            MoveWindow(mNativeWindow, 0, 0, mWidth, mHeight, FALSE);
            break;
        default:
            break;
    }
}

void Win32Window::signalTestEvent()
{
    PostMessage(mNativeWindow, WM_USER, 0, 0);
}

// static
OSWindow *OSWindow::New()
{
    return new Win32Window();
}
