//
// Copyright 2016 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.
//

// NativeWindow11WinRT.cpp: NativeWindow base class for managing IInspectable native window types.

#include "libANGLE/renderer/d3d/d3d11/winrt/NativeWindow11WinRT.h"

#include "libANGLE/renderer/d3d/d3d11/renderer11_utils.h"
#include "libANGLE/renderer/d3d/d3d11/winrt/CoreWindowNativeWindow.h"
#include "libANGLE/renderer/d3d/d3d11/winrt/InspectableNativeWindow.h"
#include "libANGLE/renderer/d3d/d3d11/winrt/SwapChainPanelNativeWindow.h"

using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;

namespace rx
{
NativeWindow11WinRT::NativeWindow11WinRT(EGLNativeWindowType window, bool hasAlpha)
    : NativeWindow11(window), mHasAlpha(hasAlpha)
{}

bool NativeWindow11WinRT::initialize()
{
    EGLNativeWindowType window = getNativeWindow();

    // If the native window type is a IPropertySet, extract the
    // EGLNativeWindowType (IInspectable) and initialize the
    // proper host with this IPropertySet.
    ComPtr<ABI::Windows::Foundation::Collections::IPropertySet> propertySet;
    ComPtr<IInspectable> eglNativeWindow;
    if (IsEGLConfiguredPropertySet(window, &propertySet, &eglNativeWindow))
    {
        // A property set was found and the EGLNativeWindowType was
        // retrieved. The mWindow member of the host to must be updated
        // to use the EGLNativeWindowType specified in the property set.
        // mWindow is treated as a raw pointer not an AddRef'd interface, so
        // the old mWindow does not need a Release() before this assignment.
        window = eglNativeWindow.Get();
    }

    ComPtr<ABI::Windows::UI::Core::ICoreWindow> coreWindow;
    ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> swapChainPanel;
    if (IsCoreWindow(window, &coreWindow))
    {
        mImpl = std::make_shared<CoreWindowNativeWindow>();
        if (mImpl)
        {
            return mImpl->initialize(window, propertySet.Get());
        }
    }
    else if (IsSwapChainPanel(window, &swapChainPanel))
    {
        mImpl = std::make_shared<SwapChainPanelNativeWindow>();
        if (mImpl)
        {
            return mImpl->initialize(window, propertySet.Get());
        }
    }
    else
    {
        ERR() << "Invalid IInspectable EGLNativeWindowType detected. Valid IInspectables include "
                 "ICoreWindow, ISwapChainPanel and IPropertySet";
    }

    return false;
}

bool NativeWindow11WinRT::getClientRect(LPRECT rect) const
{
    if (mImpl)
    {
        return mImpl->getClientRect(rect);
    }

    return false;
}

bool NativeWindow11WinRT::isIconic() const
{
    return false;
}

HRESULT NativeWindow11WinRT::createSwapChain(ID3D11Device *device,
                                             IDXGIFactory *factory,
                                             DXGI_FORMAT format,
                                             UINT width,
                                             UINT height,
                                             IDXGISwapChain **swapChain)
{
    if (mImpl)
    {
        IDXGIFactory2 *factory2     = d3d11::DynamicCastComObject<IDXGIFactory2>(factory);
        IDXGISwapChain1 *swapChain1 = nullptr;
        HRESULT result =
            mImpl->createSwapChain(device, factory2, format, width, height, mHasAlpha, &swapChain1);
        SafeRelease(factory2);
        *swapChain = static_cast<IDXGISwapChain *>(swapChain1);
        return result;
    }

    return E_UNEXPECTED;
}

void NativeWindow11WinRT::commitChange() {}

// static
bool NativeWindow11WinRT::IsValidNativeWindow(EGLNativeWindowType window)
{
    // A Valid EGLNativeWindowType IInspectable can only be:
    //
    // ICoreWindow
    // ISwapChainPanel
    // IPropertySet
    //
    // Anything else will be rejected as an invalid IInspectable.
    return IsCoreWindow(window) || IsSwapChainPanel(window) || IsEGLConfiguredPropertySet(window);
}

}  // namespace rx
