//
// Copyright (c) 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.
//

// InspectableNativeWindow.h: Host specific implementation interface for
// managing IInspectable native window types.

#ifndef LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_
#define LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_

#include "common/debug.h"
#include "common/platform.h"

#include "angle_windowsstore.h"

#include <EGL/eglplatform.h>

#include <windows.applicationmodel.core.h>
#include <windows.ui.xaml.h>
#include <windows.ui.xaml.media.dxinterop.h>
#include <wrl.h>
#include <wrl/wrappers/corewrappers.h>

using namespace Microsoft::WRL;
using namespace Microsoft::WRL::Wrappers;
using namespace ABI::Windows::Foundation;
using namespace ABI::Windows::Foundation::Collections;

namespace rx
{
class InspectableNativeWindow
{
  public:
    InspectableNativeWindow() :
        mSupportsSwapChainResize(true),
        mSwapChainSizeSpecified(false),
        mSwapChainScaleSpecified(false),
        mSwapChainScale(1.0f),
        mClientRectChanged(false),
        mClientRect({0,0,0,0}),
        mNewClientRect({0,0,0,0})
    {
        mSizeChangedEventToken.value = 0;
    }
    virtual ~InspectableNativeWindow(){}

    virtual bool initialize(EGLNativeWindowType window, IPropertySet *propertySet) = 0;
    virtual HRESULT createSwapChain(ID3D11Device *device,
                                    IDXGIFactory2 *factory,
                                    DXGI_FORMAT format,
                                    unsigned int width,
                                    unsigned int height,
                                    bool containsAlpha,
                                    IDXGISwapChain1 **swapChain) = 0;

    bool getClientRect(RECT *rect)
    {
        if (mClientRectChanged)
        {
            mClientRect = mNewClientRect;
        }

        *rect = mClientRect;

        return true;
    }

    // setNewClientSize is used by the WinRT size change handler. It isn't used by the rest of ANGLE.
    void setNewClientSize(const Size &newWindowSize)
    {
        // If the client doesn't support swapchain resizing then we should have already unregistered from size change handler
        ASSERT(mSupportsSwapChainResize);

        if (mSupportsSwapChainResize)
        {
            // If the swapchain size was specified then we should ignore this call too
            if (!mSwapChainSizeSpecified)
            {
                mNewClientRect     = clientRect(newWindowSize);
                mClientRectChanged = true;

                // If a scale was specified, then now is the time to apply the scale matrix for the new swapchain size and window size
                if (mSwapChainScaleSpecified)
                {
                    scaleSwapChain(newWindowSize, mNewClientRect);
                }
            }

            // Even if the swapchain size was fixed, the window might have changed size.
            // In this case, we should recalculate the scale matrix to account for the new window size
            if (mSwapChainSizeSpecified)
            {
                scaleSwapChain(newWindowSize, mClientRect);
            }
        }
    }

  protected:
    virtual HRESULT scaleSwapChain(const Size &windowSize, const RECT &clientRect) = 0;
    RECT clientRect(const Size &size);

    bool mSupportsSwapChainResize; // Support for IDXGISwapChain::ResizeBuffers method
    bool mSwapChainSizeSpecified;  // If an EGLRenderSurfaceSizeProperty was specified
    bool mSwapChainScaleSpecified; // If an EGLRenderResolutionScaleProperty was specified
    float mSwapChainScale;         // The scale value specified by the EGLRenderResolutionScaleProperty property
    RECT mClientRect;
    RECT mNewClientRect;
    bool mClientRectChanged;

    EventRegistrationToken mSizeChangedEventToken;
};

bool IsCoreWindow(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Core::ICoreWindow> *coreWindow = nullptr);
bool IsSwapChainPanel(EGLNativeWindowType window, ComPtr<ABI::Windows::UI::Xaml::Controls::ISwapChainPanel> *swapChainPanel = nullptr);
bool IsEGLConfiguredPropertySet(EGLNativeWindowType window, ABI::Windows::Foundation::Collections::IPropertySet **propertySet = nullptr, IInspectable **inspectable = nullptr);

HRESULT GetOptionalPropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
                                 const wchar_t *propertyName,
                                 boolean *hasKey,
                                 ComPtr<ABI::Windows::Foundation::IPropertyValue> &propertyValue);

HRESULT GetOptionalSizePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
                                     const wchar_t *propertyName, SIZE *value, bool *valueExists);

HRESULT GetOptionalSinglePropertyValue(const ComPtr<ABI::Windows::Foundation::Collections::IMap<HSTRING, IInspectable*>> &propertyMap,
                                       const wchar_t *propertyName, float *value, bool *valueExists);
}

#endif // LIBANGLE_RENDERER_D3D_D3D11_WINRT_INSPECTABLENATIVEWINDOW_H_
