/*
 * Copyright (C) 2019 Apple Inc.  All rights reserved.
 * Copyright (C) 2010 Igalia S.L.
 * Copyright (C) 2011 ProFUSION embedded systems
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "Direct2DUtilities.h"

#if USE(DIRECT2D)

#include "COMPtr.h"
#include "FloatPoint.h"
#include "FloatSize.h"
#include "GraphicsContext.h"
#include "ImageDecoderDirect2D.h"
#include "IntRect.h"
#include "IntSize.h"
#include <d2d1_1.h>
#include <d3d11_1.h>
#include <shlwapi.h>
#include <wincodec.h>


namespace WebCore {

namespace Direct2D {

constexpr DXGI_FORMAT webkitTextureFormat = DXGI_FORMAT_B8G8R8A8_UNORM;
constexpr D2D1_ALPHA_MODE webkitAlphaMode = D2D1_ALPHA_MODE_PREMULTIPLIED;

IntSize bitmapSize(IWICBitmapSource* bitmapSource)
{
    UINT width, height;
    HRESULT hr = bitmapSource->GetSize(&width, &height);
    if (!SUCCEEDED(hr))
        return { };

    return IntSize(width, height);
}

FloatSize bitmapSize(ID2D1Bitmap* bitmapSource)
{
    return bitmapSource->GetSize();
}

FloatSize bitmapResolution(IWICBitmapSource* bitmapSource)
{
    constexpr double dpiBase = 96;

    double dpiX, dpiY;
    HRESULT hr = bitmapSource->GetResolution(&dpiX, &dpiY);
    if (!SUCCEEDED(hr))
        return { };

    FloatSize result(dpiX, dpiY);
    result.scale(1.0 / dpiBase);
    return result;
}

FloatSize bitmapResolution(ID2D1Bitmap* bitmap)
{
    constexpr double dpiBase = 96;

    float dpiX, dpiY;
    bitmap->GetDpi(&dpiX, &dpiY);

    FloatSize result(dpiX, dpiY);
    result.scale(1.0 / dpiBase);
    return result;

}

FloatSize bitmapResolution(ID2D1RenderTarget* target)
{
    constexpr double dpiBase = 96;

    float dpiX, dpiY;
    target->GetDpi(&dpiX, &dpiY);

    FloatSize result(dpiX, dpiY);
    result.scale(1.0 / dpiBase);
    return result;

}
unsigned bitsPerPixel(GUID bitmapFormat)
{
    COMPtr<IWICComponentInfo> componentInfo;
    HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateComponentInfo(bitmapFormat, &componentInfo);
    if (!SUCCEEDED(hr))
        return 4;

    COMPtr<IWICPixelFormatInfo> pixelFormat;
    pixelFormat.query(componentInfo);
    if (!pixelFormat)
        return 4;

    UINT bpp = 0;
    hr = pixelFormat->GetBitsPerPixel(&bpp);
    if (!SUCCEEDED(hr))
        return 4;

    return bpp;
}

COMPtr<IWICBitmap> createDirect2DImageSurfaceWithData(void* data, const IntSize& size, unsigned stride)
{
    Checked<size_t, RecordOverflow> numBytes = Checked<unsigned, RecordOverflow>(size.height()) * stride;
    if (numBytes.hasOverflowed())
        return nullptr;

    COMPtr<IWICBitmap> surface;
    HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmapFromMemory(size.width(), size.height(), wicBitmapFormat(), stride, static_cast<UINT>(numBytes.unsafeGet()), reinterpret_cast<BYTE*>(data), &surface);
    if (!SUCCEEDED(hr))
        return nullptr;

    return surface;
}

COMPtr<IWICBitmap> createWicBitmap(const IntSize& size)
{
    COMPtr<IWICBitmap> surface;
    HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateBitmap(size.width(), size.height(), wicBitmapFormat(), WICBitmapCacheOnDemand, &surface);
    if (!SUCCEEDED(hr))
        return nullptr;

    return surface;
}

D2D1_PIXEL_FORMAT pixelFormatForSoftwareManipulation()
{
    return D2D1::PixelFormat(DXGI_FORMAT_R8G8B8A8_UNORM, D2D1_ALPHA_MODE_PREMULTIPLIED);
}

D2D1_PIXEL_FORMAT pixelFormat()
{
    // Since we need to interact with HDC from time-to-time, we are forced to use DXGI_FORMAT_B8G8R8A8_UNORM and D2D1_ALPHA_MODE_PREMULTIPLIED
    return D2D1::PixelFormat(webkitTextureFormat, webkitAlphaMode);
}

GUID wicBitmapFormat()
{
    // This is the WIC format compatible with DXGI_FORMAT_B8G8R8A8_UNORM. It is also supposedly the most efficient in-memory
    // representation for WIC images.
    return GUID_WICPixelFormat32bppPBGRA;
}

D2D1_BITMAP_PROPERTIES bitmapProperties()
{
    return D2D1::BitmapProperties(pixelFormat());
}

COMPtr<ID2D1Bitmap> createBitmap(ID2D1RenderTarget* renderTarget, const IntSize& size)
{
    auto bitmapCreateProperties = bitmapProperties();

    COMPtr<ID2D1Bitmap> bitmap;
    D2D1_SIZE_U bitmapSize = size;
    HRESULT hr = renderTarget->CreateBitmap(bitmapSize, bitmapCreateProperties, &bitmap);
    if (!SUCCEEDED(hr))
        return nullptr;

    return bitmap;
}

D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties()
{
    return D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
        pixelFormat(), 0, 0, D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE, D2D1_FEATURE_LEVEL_DEFAULT);
}

COMPtr<ID2D1RenderTarget> createRenderTargetFromWICBitmap(IWICBitmap* bitmapSource)
{
    auto targetProperties = renderTargetProperties();

    COMPtr<ID2D1RenderTarget> bitmapContext;
    HRESULT hr = GraphicsContext::systemFactory()->CreateWicBitmapRenderTarget(bitmapSource, &targetProperties, &bitmapContext);
    if (!bitmapContext || !SUCCEEDED(hr))
        return nullptr;

    return bitmapContext;
}

COMPtr<ID2D1DCRenderTarget> createGDIRenderTarget()
{
    auto targetProperties = renderTargetProperties();

    COMPtr<ID2D1DCRenderTarget> renderTarget;
    HRESULT hr = GraphicsContext::systemFactory()->CreateDCRenderTarget(&targetProperties, &renderTarget);
    if (!renderTarget || !SUCCEEDED(hr))
        return nullptr;

    return renderTarget;
}

COMPtr<ID2D1BitmapRenderTarget> createBitmapRenderTarget(ID2D1RenderTarget* renderTarget)
{
    if (!renderTarget)
        renderTarget = GraphicsContext::defaultRenderTarget();

    COMPtr<ID2D1BitmapRenderTarget> bitmapContext;
    HRESULT hr = renderTarget->CreateCompatibleRenderTarget(nullptr, nullptr, nullptr, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, &bitmapContext);
    if (!SUCCEEDED(hr))
        return nullptr;

    return bitmapContext;
}

COMPtr<ID2D1BitmapRenderTarget> createBitmapRenderTargetOfSize(const IntSize& size, ID2D1RenderTarget* renderTarget, float deviceScaleFactor)
{
    UNUSED_PARAM(deviceScaleFactor);

    if (!renderTarget)
        renderTarget = GraphicsContext::defaultRenderTarget();

    COMPtr<ID2D1BitmapRenderTarget> bitmapContext;
    auto desiredSize = D2D1::SizeF(size.width(), size.height());
    D2D1_SIZE_U pixelSize = D2D1::SizeU(clampTo<unsigned>(deviceScaleFactor * size.width()), clampTo<unsigned>(deviceScaleFactor * size.height()));
    HRESULT hr = renderTarget->CreateCompatibleRenderTarget(&desiredSize, &pixelSize, nullptr, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_GDI_COMPATIBLE, &bitmapContext);
    if (!SUCCEEDED(hr))
        return nullptr;

    return bitmapContext;
}

COMPtr<IDXGISurface1> createDXGISurfaceOfSize(const IntSize& size, ID3D11Device1* directXDevice, bool crossProcess)
{
    if (!directXDevice)
        directXDevice = Direct2D::defaultDirectXDevice();

    // Create the render target texture
    D3D11_TEXTURE2D_DESC desc;
    ZeroMemory(&desc, sizeof(desc));
    desc.Width = size.width();
    desc.Height = size.height();
    desc.MipLevels = 1;
    desc.ArraySize = 1;
    desc.Format = webkitTextureFormat;
    desc.SampleDesc.Count = 1;
    desc.Usage = D3D11_USAGE_DEFAULT;
    desc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE;
    desc.CPUAccessFlags = 0;
    desc.MiscFlags = D3D11_RESOURCE_MISC_GDI_COMPATIBLE;
    if (crossProcess)
        desc.MiscFlags |= D3D11_RESOURCE_MISC_SHARED_NTHANDLE | D3D11_RESOURCE_MISC_SHARED_KEYEDMUTEX;

    COMPtr<ID3D11Texture2D> texture;
    HRESULT hr = directXDevice->CreateTexture2D(&desc, nullptr, &texture);
    RELEASE_ASSERT(SUCCEEDED(hr));

    COMPtr<IDXGISurface1> surface;
    hr = texture->QueryInterface(&surface);
    RELEASE_ASSERT(SUCCEEDED(hr));

    return surface;
}

COMPtr<ID2D1RenderTarget> createSurfaceRenderTarget(IDXGISurface1* surface)
{
    auto pixelFormat = D2D1::PixelFormat(webkitTextureFormat, webkitAlphaMode);

    auto properties = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT,
        pixelFormat, 0, 0, D2D1_RENDER_TARGET_USAGE_GDI_COMPATIBLE, D2D1_FEATURE_LEVEL_10);

    COMPtr<ID2D1RenderTarget> renderTarget;
    HRESULT hr = GraphicsContext::systemFactory()->CreateDxgiSurfaceRenderTarget(surface, properties, &renderTarget);
    if (!SUCCEEDED(hr))
        return nullptr;

    return renderTarget;
}

void copyRectFromOneSurfaceToAnother(ID2D1Bitmap* from, ID2D1Bitmap* to, const IntSize& sourceOffset, const IntRect& rect, const IntSize& destOffset)
{
    IntSize sourceBitmapSize = from->GetPixelSize();
    if (sourceBitmapSize.isZero())
        return;

    IntSize targetBitmapSize = to->GetPixelSize();
    if (targetBitmapSize.isZero())
        return;

    IntRect sourceRect(sourceOffset.width(), sourceOffset.height(), rect.width(), rect.height());
    IntRect targetRect(destOffset.width(), destOffset.height(), rect.width(), rect.height());

    IntRect sourceBitmapRect(IntPoint(), sourceBitmapSize);
    IntRect targetBitmapRect(IntPoint(), targetBitmapSize);

    sourceRect.intersect(sourceBitmapRect);
    targetRect.intersect(targetBitmapRect);

    D2D1_RECT_U d2dSourceRect = D2D1::RectU(sourceRect.x(), sourceRect.y(), sourceRect.x() + targetRect.width(), sourceRect.y() + targetRect.height());
    auto offset = D2D1::Point2U(destOffset.width(), destOffset.height());

    HRESULT hr = to->CopyFromBitmap(&offset, from, &d2dSourceRect);
    ASSERT(SUCCEEDED(hr));
}

void writeDiagnosticPNGToPath(ID2D1RenderTarget* renderTarget, ID2D1Bitmap* bitmap, LPCWSTR fileName)
{
    COMPtr<IWICBitmapEncoder> wicBitmapEncoder;
    HRESULT hr = ImageDecoderDirect2D::systemImagingFactory()->CreateEncoder(GUID_ContainerFormatPng, nullptr, &wicBitmapEncoder);
    ASSERT(SUCCEEDED(hr));

    DWORD mode = STGM_CREATE | STGM_READWRITE | STGM_SHARE_DENY_WRITE;
    COMPtr<IStream> stream;
    hr = ::SHCreateStreamOnFileEx(fileName, mode, FILE_ATTRIBUTE_NORMAL, TRUE, nullptr, &stream);
    ASSERT(SUCCEEDED(hr));

    hr = wicBitmapEncoder->Initialize(stream.get(), WICBitmapEncoderNoCache);
    ASSERT(SUCCEEDED(hr));

    COMPtr<IWICBitmapFrameEncode> wicFrameEncode;
    hr = wicBitmapEncoder->CreateNewFrame(&wicFrameEncode, nullptr);
    ASSERT(SUCCEEDED(hr));

    hr = wicFrameEncode->Initialize(nullptr);
    ASSERT(SUCCEEDED(hr));

    COMPtr<ID2D1DeviceContext> d2dDeviceContext;
    hr = renderTarget->QueryInterface(__uuidof(ID2D1DeviceContext), reinterpret_cast<void**>(&d2dDeviceContext));
    ASSERT(SUCCEEDED(hr));

    COMPtr<ID2D1Device> d2dDevice;
    d2dDeviceContext->GetDevice(&d2dDevice);

    COMPtr<IWICImageEncoder> imageEncoder;
    hr = ImageDecoderDirect2D::systemImagingFactory()->CreateImageEncoder(d2dDevice.get(), &imageEncoder);
    ASSERT(SUCCEEDED(hr));

    hr = imageEncoder->WriteFrame(bitmap, wicFrameEncode.get(), nullptr);
    ASSERT(SUCCEEDED(hr));

    hr = wicFrameEncode->Commit();
    ASSERT(SUCCEEDED(hr));

    hr = wicBitmapEncoder->Commit();
    ASSERT(SUCCEEDED(hr));

    hr = stream->Commit(STGC_DEFAULT);
    ASSERT(SUCCEEDED(hr));
}

static ID3D11DeviceContext1* immediateContext = nullptr;

ID3D11DeviceContext1* dxgiImmediateContext()
{
    if (!immediateContext)
        defaultDirectXDevice();

    RELEASE_ASSERT(immediateContext);
    return immediateContext;
}

ID3D11Device1* defaultDirectXDevice()
{
    static ID3D11Device1* defaultDevice1 = nullptr;

    if (!defaultDevice1) {
        int deviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifndef NDEBUG
        deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

        ID3D11Device* defaultDevice = nullptr;
        D3D_FEATURE_LEVEL featureLevel = { };
        ID3D11DeviceContext* immediateDeviceContext = nullptr;
        HRESULT hr = D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, deviceFlags, nullptr, 0, D3D11_SDK_VERSION, &defaultDevice, &featureLevel, &immediateDeviceContext);
        RELEASE_ASSERT(SUCCEEDED(hr));

        hr = defaultDevice->QueryInterface(&defaultDevice1);
        RELEASE_ASSERT(SUCCEEDED(hr));
        defaultDevice1->AddRef();

        hr = immediateDeviceContext->QueryInterface(__uuidof(ID3D11DeviceContext1), reinterpret_cast<void**>(&immediateContext));
        RELEASE_ASSERT(SUCCEEDED(hr));
        immediateContext->AddRef();
    }

    return defaultDevice1;
}

bool createDeviceAndContext(COMPtr<ID3D11Device1>& d3dDevice, COMPtr<ID3D11DeviceContext1>& immediateContext)
{
    int deviceFlags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
#ifndef NDEBUG
    deviceFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

    D3D_FEATURE_LEVEL featureLevel = { };
    ID3D11Device* defaultDevice = nullptr;
    ID3D11DeviceContext* immediateDeviceContext = nullptr;
    HRESULT hr = ::D3D11CreateDevice(nullptr, D3D_DRIVER_TYPE_HARDWARE, nullptr, deviceFlags, nullptr, 0, D3D11_SDK_VERSION, &defaultDevice, &featureLevel, &immediateDeviceContext);
    RELEASE_ASSERT(SUCCEEDED(hr));

    hr = defaultDevice->QueryInterface(&d3dDevice);
    RELEASE_ASSERT(SUCCEEDED(hr));
    defaultDevice->Release();

    hr = immediateDeviceContext->QueryInterface(&immediateContext);
    RELEASE_ASSERT(SUCCEEDED(hr));
    immediateContext->Release();
    return true;
}

COMPtr<IDXGIDevice1> toDXGIDevice(const COMPtr<ID3D11Device1>& d3dDevice)
{
    if (!d3dDevice)
        return nullptr;

    COMPtr<IDXGIDevice1> dxgiDevice;
    HRESULT hr = d3dDevice->QueryInterface(__uuidof(IDXGIDevice1), (void **)&dxgiDevice);
    if (!SUCCEEDED(hr))
        return nullptr;

    return dxgiDevice;
}

COMPtr<IDXGIFactory2> factoryForDXGIDevice(const COMPtr<IDXGIDevice1>& device)
{
    if (!device)
        return nullptr;

    COMPtr<IDXGIAdapter> adaptor;
    HRESULT hr = device->GetParent(__uuidof(IDXGIAdapter), reinterpret_cast<void**>(&adaptor));
    RELEASE_ASSERT(SUCCEEDED(hr));

    COMPtr<IDXGIFactory> factory;
    hr = adaptor->GetParent(__uuidof(IDXGIFactory), reinterpret_cast<void**>(&factory));
    RELEASE_ASSERT(SUCCEEDED(hr));

    COMPtr<IDXGIFactory2> factory2;
    hr = factory->QueryInterface(&factory2); 
    RELEASE_ASSERT(SUCCEEDED(hr));
    
    return factory2;
}

COMPtr<IDXGISwapChain> swapChainOfSizeForWindowAndDevice(const WebCore::IntSize& size, HWND window, const COMPtr<ID3D11Device1>& device)
{
    if (!device)
        return nullptr;

    DXGI_SWAP_CHAIN_DESC1 swapChainDescription;
    ::ZeroMemory(&swapChainDescription, sizeof(swapChainDescription));
    swapChainDescription.Width = size.width();
    swapChainDescription.Height = size.height();
    swapChainDescription.Format = webkitTextureFormat;
    swapChainDescription.SampleDesc.Count = 1;
    swapChainDescription.SampleDesc.Quality = 0;
    swapChainDescription.BufferUsage = DXGI_USAGE_SHADER_INPUT | DXGI_USAGE_RENDER_TARGET_OUTPUT;
    swapChainDescription.BufferCount = 1;
    swapChainDescription.Flags = DXGI_SWAP_CHAIN_FLAG_GDI_COMPATIBLE;

    auto factory = Direct2D::factoryForDXGIDevice(Direct2D::toDXGIDevice(device));

    COMPtr<IDXGISwapChain1> swapChain1;
    HRESULT hr = factory->CreateSwapChainForHwnd(device.get(), window, &swapChainDescription, nullptr, nullptr, &swapChain1);
    if (!SUCCEEDED(hr))
        return nullptr;

    COMPtr<IDXGISwapChain> swapChain(Query, swapChain1);
    return swapChain;
}

COMPtr<ID2D1Bitmap> createBitmapCopyFromContext(ID2D1BitmapRenderTarget* bitmapTarget)
{
    COMPtr<ID2D1Bitmap> currentCanvas;
    HRESULT hr = bitmapTarget->GetBitmap(&currentCanvas);
    if (!SUCCEEDED(hr))
        return nullptr;

    auto bitmapCreateProperties = bitmapProperties();

    COMPtr<ID2D1Bitmap> bitmap;
    D2D1_SIZE_U bitmapSize = currentCanvas->GetPixelSize();
    hr = bitmapTarget->CreateBitmap(bitmapSize, bitmapCreateProperties, &bitmap);
    if (!SUCCEEDED(hr))
        return nullptr;

    auto targetPos = D2D1::Point2U();
    D2D1_RECT_U dataRect = D2D1::RectU(0, 0, bitmapSize.width, bitmapSize.height);
    hr = bitmap->CopyFromBitmap(&targetPos, currentCanvas.get(), &dataRect);
    if (!SUCCEEDED(hr))
        return false;

    return bitmap;
}

} // namespace Direct2D

} // namespace WebCore

#endif // USE(DIRECT2D)
