//
// 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   = {0};
    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   = {0};
    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();
}
