//
// Copyright 2018 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.
//
// WGLWindow:
//   Implements initializing a WGL rendering context.
//

#include "util/windows/WGLWindow.h"

#include "common/string_utils.h"
#include "common/system_utils.h"
#include "util/OSWindow.h"

#include <iostream>

namespace
{
constexpr int kColorBits   = 24;
constexpr int kAlphaBits   = 8;
constexpr int kDepthBits   = 24;
constexpr int kStencilBits = 8;

PIXELFORMATDESCRIPTOR GetDefaultPixelFormatDescriptor()
{
    PIXELFORMATDESCRIPTOR pixelFormatDescriptor = {};
    pixelFormatDescriptor.nSize                 = sizeof(pixelFormatDescriptor);
    pixelFormatDescriptor.nVersion              = 1;
    pixelFormatDescriptor.dwFlags =
        PFD_DRAW_TO_WINDOW | PFD_GENERIC_ACCELERATED | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
    pixelFormatDescriptor.iPixelType   = PFD_TYPE_RGBA;
    pixelFormatDescriptor.cColorBits   = kColorBits;
    pixelFormatDescriptor.cAlphaBits   = kAlphaBits;
    pixelFormatDescriptor.cDepthBits   = kDepthBits;
    pixelFormatDescriptor.cStencilBits = kStencilBits;
    pixelFormatDescriptor.iLayerType   = PFD_MAIN_PLANE;

    return pixelFormatDescriptor;
}

PFNWGLGETPROCADDRESSPROC gCurrentWGLGetProcAddress = nullptr;
HMODULE gCurrentModule                             = nullptr;

angle::GenericProc WINAPI GetProcAddressWithFallback(const char *name)
{
    angle::GenericProc proc = reinterpret_cast<angle::GenericProc>(gCurrentWGLGetProcAddress(name));
    if (proc)
    {
        return proc;
    }

    return reinterpret_cast<angle::GenericProc>(GetProcAddress(gCurrentModule, name));
}

bool HasExtension(const std::vector<std::string> &extensions, const char *ext)
{
    return std::find(extensions.begin(), extensions.end(), ext) != extensions.end();
}

void DumpLastWindowsError()
{
    std::cerr << "Last Windows error code: 0x" << std::hex << GetLastError() << std::endl;
}

// Based on GetDefaultPixelFormatAttributes from wgl_utils.cpp
std::vector<int> GetPixelFormatAttributes(const ConfigParameters &configParams)
{
    std::vector<int> attribs;
    attribs.push_back(WGL_DRAW_TO_WINDOW_ARB);
    attribs.push_back(TRUE);

    attribs.push_back(WGL_ACCELERATION_ARB);
    attribs.push_back(WGL_FULL_ACCELERATION_ARB);

    attribs.push_back(WGL_SUPPORT_OPENGL_ARB);
    attribs.push_back(TRUE);

    attribs.push_back(WGL_DOUBLE_BUFFER_ARB);
    attribs.push_back(TRUE);

    attribs.push_back(WGL_PIXEL_TYPE_ARB);
    attribs.push_back(WGL_TYPE_RGBA_ARB);

    attribs.push_back(WGL_COLOR_BITS_ARB);
    attribs.push_back(kColorBits);

    attribs.push_back(WGL_ALPHA_BITS_ARB);
    attribs.push_back(kAlphaBits);

    attribs.push_back(WGL_DEPTH_BITS_ARB);
    attribs.push_back(kDepthBits);

    attribs.push_back(WGL_STENCIL_BITS_ARB);
    attribs.push_back(kStencilBits);

    attribs.push_back(WGL_SWAP_METHOD_ARB);
    attribs.push_back(WGL_SWAP_UNDEFINED_ARB);

    attribs.push_back(WGL_COLORSPACE_EXT);
    if (configParams.colorSpace == EGL_COLORSPACE_sRGB)
    {
        attribs.push_back(WGL_COLORSPACE_SRGB_EXT);
    }
    else
    {
        attribs.push_back(WGL_COLORSPACE_LINEAR_EXT);
    }

    attribs.push_back(0);

    return attribs;
}

}  // namespace

WGLWindow::WGLWindow(int glesMajorVersion, int glesMinorVersion)
    : GLWindowBase(glesMajorVersion, glesMinorVersion),
      mDeviceContext(nullptr),
      mWGLContext(nullptr),
      mWindow(nullptr)
{}

WGLWindow::~WGLWindow() {}

// Internally initializes GL resources.
GLWindowResult WGLWindow::initializeGLWithResult(OSWindow *osWindow,
                                                 angle::Library *glWindowingLibrary,
                                                 angle::GLESDriverType driverType,
                                                 const EGLPlatformParameters &platformParams,
                                                 const ConfigParameters &configParams)
{
    if (driverType != angle::GLESDriverType::SystemWGL)
    {
        std::cerr << "WGLWindow requires angle::GLESDriverType::SystemWGL.\n";
        return GLWindowResult::Error;
    }

    glWindowingLibrary->getAs("wglGetProcAddress", &gCurrentWGLGetProcAddress);

    if (!gCurrentWGLGetProcAddress)
    {
        std::cerr << "Error loading wglGetProcAddress." << std::endl;
        return GLWindowResult::Error;
    }

    gCurrentModule = reinterpret_cast<HMODULE>(glWindowingLibrary->getNative());
    angle::LoadWGL(GetProcAddressWithFallback);

    mWindow                                           = osWindow->getNativeWindow();
    mDeviceContext                                    = GetDC(mWindow);
    const PIXELFORMATDESCRIPTOR pixelFormatDescriptor = GetDefaultPixelFormatDescriptor();

    int pixelFormat = 0;

    if (!_wglChoosePixelFormatARB)
    {
        std::cout << "Driver does not expose wglChoosePixelFormatARB." << std::endl;
    }
    else
    {
        std::vector<int> pixelFormatAttribs = GetPixelFormatAttributes(configParams);

        UINT matchingFormats = 0;
        _wglChoosePixelFormatARB(mDeviceContext, &pixelFormatAttribs[0], nullptr, 1u, &pixelFormat,
                                 &matchingFormats);
    }

    if (pixelFormat == 0 && configParams.colorSpace != EGL_COLORSPACE_LINEAR)
    {
        std::cerr << "Could not find a compatible pixel format for a non-linear color space."
                  << std::endl;
        return GLWindowResult::NoColorspaceSupport;
    }

    if (pixelFormat == 0)
    {
        pixelFormat = ChoosePixelFormat(mDeviceContext, &pixelFormatDescriptor);
    }

    if (pixelFormat == 0)
    {
        std::cerr << "Could not find a compatible pixel format." << std::endl;
        DumpLastWindowsError();
        return GLWindowResult::Error;
    }

    // According to the Windows docs, it is an error to set a pixel format twice.
    int currentPixelFormat = GetPixelFormat(mDeviceContext);
    if (currentPixelFormat != pixelFormat)
    {
        if (SetPixelFormat(mDeviceContext, pixelFormat, &pixelFormatDescriptor) != TRUE)
        {
            std::cerr << "Failed to set the pixel format." << std::endl;
            DumpLastWindowsError();
            return GLWindowResult::Error;
        }
    }

    mWGLContext = createContext(configParams, nullptr);
    if (mWGLContext == nullptr)
    {
        return GLWindowResult::Error;
    }

    if (!makeCurrent())
    {
        return GLWindowResult::Error;
    }

    mPlatform     = platformParams;
    mConfigParams = configParams;

    angle::LoadGLES(GetProcAddressWithFallback);
    return GLWindowResult::NoError;
}

bool WGLWindow::initializeGL(OSWindow *osWindow,
                             angle::Library *glWindowingLibrary,
                             angle::GLESDriverType driverType,
                             const EGLPlatformParameters &platformParams,
                             const ConfigParameters &configParams)
{
    return initializeGLWithResult(osWindow, glWindowingLibrary, driverType, platformParams,
                                  configParams) == GLWindowResult::NoError;
}

HGLRC WGLWindow::createContext(const ConfigParameters &configParams, HGLRC shareContext)
{
    HGLRC context = _wglCreateContext(mDeviceContext);
    if (!context)
    {
        std::cerr << "Failed to create a WGL context." << std::endl;
        return context;
    }

    if (!makeCurrent(context))
    {
        std::cerr << "Failed to make WGL context current." << std::endl;
        return context;
    }

    // Reload entry points to capture extensions.
    angle::LoadWGL(GetProcAddressWithFallback);

    if (!_wglGetExtensionsStringARB)
    {
        std::cerr << "Driver does not expose wglGetExtensionsStringARB." << std::endl;
        return context;
    }

    const char *extensionsString = _wglGetExtensionsStringARB(mDeviceContext);

    std::vector<std::string> extensions;
    angle::SplitStringAlongWhitespace(extensionsString, &extensions);

    if (!HasExtension(extensions, "WGL_EXT_create_context_es2_profile"))
    {
        std::cerr << "Driver does not expose WGL_EXT_create_context_es2_profile." << std::endl;
        return context;
    }

    if (mConfigParams.webGLCompatibility.valid() || mConfigParams.robustResourceInit.valid())
    {
        std::cerr << "WGLWindow does not support the requested feature set." << std::endl;
        return context;
    }

    // Tear down the context and create another with ES2 compatibility.
    _wglDeleteContext(context);

    // This could be extended to cover ES1 compatiblity.
    int kCreateAttribs[] = {WGL_CONTEXT_MAJOR_VERSION_ARB,
                            mClientMajorVersion,
                            WGL_CONTEXT_MINOR_VERSION_ARB,
                            mClientMinorVersion,
                            WGL_CONTEXT_PROFILE_MASK_ARB,
                            WGL_CONTEXT_ES2_PROFILE_BIT_EXT,
                            0,
                            0};

    context = _wglCreateContextAttribsARB(mDeviceContext, shareContext, kCreateAttribs);
    if (!context)
    {
        std::cerr << "Failed to create an ES2 compatible WGL context." << std::endl;
        return context;
    }

    return context;
}

void WGLWindow::destroyGL()
{
    if (mWGLContext)
    {
        _wglDeleteContext(mWGLContext);
        mWGLContext = nullptr;
    }

    if (mDeviceContext)
    {
        ReleaseDC(mWindow, mDeviceContext);
        mDeviceContext = nullptr;
    }
}

bool WGLWindow::isGLInitialized() const
{
    return mWGLContext != nullptr;
}

GLWindowContext WGLWindow::getCurrentContextGeneric()
{
    return reinterpret_cast<GLWindowContext>(mWGLContext);
}

GLWindowContext WGLWindow::createContextGeneric(GLWindowContext share)
{
    HGLRC shareContext = reinterpret_cast<HGLRC>(share);
    HGLRC newContext   = createContext(mConfigParams, shareContext);

    // createContext() calls makeCurrent(newContext), so we need to restore the current context.
    if (!makeCurrent())
    {
        return nullptr;
    }

    return reinterpret_cast<GLWindowContext>(newContext);
}

bool WGLWindow::makeCurrent()
{
    return makeCurrent(mWGLContext);
}

bool WGLWindow::makeCurrentGeneric(GLWindowContext context)
{
    HGLRC wglContext = reinterpret_cast<HGLRC>(context);
    return makeCurrent(wglContext);
}

bool WGLWindow::makeCurrent(HGLRC context)
{
    if (_wglMakeCurrent(mDeviceContext, context) == FALSE)
    {
        std::cerr << "Error during wglMakeCurrent.\n";
        return false;
    }

    return true;
}

bool WGLWindow::setSwapInterval(EGLint swapInterval)
{
    if (!_wglSwapIntervalEXT || _wglSwapIntervalEXT(swapInterval) == FALSE)
    {
        std::cerr << "Error during wglSwapIntervalEXT.\n";
        return false;
    }
    return true;
}

void WGLWindow::swap()
{
    if (SwapBuffers(mDeviceContext) == FALSE)
    {
        std::cerr << "Error during SwapBuffers.\n";
    }
}

bool WGLWindow::hasError() const
{
    return GetLastError() != S_OK;
}

angle::GenericProc WGLWindow::getProcAddress(const char *name)
{
    return GetProcAddressWithFallback(name);
}

// static
WGLWindow *WGLWindow::New(int glesMajorVersion, int glesMinorVersion)
{
    return new WGLWindow(glesMajorVersion, glesMinorVersion);
}

// static
void WGLWindow::Delete(WGLWindow **window)
{
    delete *window;
    *window = nullptr;
}
