// Copyright 2020 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef SRC_DAWN_NATIVE_SURFACE_H_
#define SRC_DAWN_NATIVE_SURFACE_H_

#include "dawn/common/RefCounted.h"
#include "dawn/native/Error.h"
#include "dawn/native/Forward.h"

#include "dawn/native/dawn_platform.h"

#include "dawn/common/Platform.h"

#if defined(DAWN_PLATFORM_WINDOWS)
#    include "dawn/native/d3d12/d3d12_platform.h"
#endif  // defined(DAWN_PLATFORM_WINDOWS)

// Forward declare IUnknown
// GetCoreWindow needs to return an IUnknown pointer
// non-windows platforms don't have this type
struct IUnknown;

namespace dawn::native {

    MaybeError ValidateSurfaceDescriptor(const InstanceBase* instance,
                                         const SurfaceDescriptor* descriptor);

    // A surface is a sum types of all the kind of windows Dawn supports. The OS-specific types
    // aren't used because they would cause compilation errors on other OSes (or require
    // ObjectiveC).
    // The surface is also used to store the current swapchain so that we can detach it when it is
    // replaced.
    class Surface final : public RefCounted {
      public:
        Surface(InstanceBase* instance, const SurfaceDescriptor* descriptor);

        void SetAttachedSwapChain(NewSwapChainBase* swapChain);
        NewSwapChainBase* GetAttachedSwapChain();

        // These are valid to call on all Surfaces.
        enum class Type {
            AndroidWindow,
            MetalLayer,
            WindowsHWND,
            WindowsCoreWindow,
            WindowsSwapChainPanel,
            XlibWindow,
        };
        Type GetType() const;
        InstanceBase* GetInstance();

        // Valid to call if the type is MetalLayer
        void* GetMetalLayer() const;

        // Valid to call if the type is Android
        void* GetAndroidNativeWindow() const;

        // Valid to call if the type is WindowsHWND
        void* GetHInstance() const;
        void* GetHWND() const;

        // Valid to call if the type is WindowsCoreWindow
        IUnknown* GetCoreWindow() const;

        // Valid to call if the type is WindowsSwapChainPanel
        IUnknown* GetSwapChainPanel() const;

        // Valid to call if the type is WindowsXlib
        void* GetXDisplay() const;
        uint32_t GetXWindow() const;

      private:
        ~Surface() override;

        Ref<InstanceBase> mInstance;
        Type mType;

        // The swapchain will set this to null when it is destroyed.
        Ref<NewSwapChainBase> mSwapChain;

        // MetalLayer
        void* mMetalLayer = nullptr;

        // ANativeWindow
        void* mAndroidNativeWindow = nullptr;

        // WindowsHwnd
        void* mHInstance = nullptr;
        void* mHWND = nullptr;

#if defined(DAWN_PLATFORM_WINDOWS)
        // WindowsCoreWindow
        ComPtr<IUnknown> mCoreWindow;

        // WindowsSwapChainPanel
        ComPtr<IUnknown> mSwapChainPanel;
#endif  // defined(DAWN_PLATFORM_WINDOWS)

        // Xlib
        void* mXDisplay = nullptr;
        uint32_t mXWindow = 0;
    };

    // Not defined in webgpu_absl_format.h/cpp because you can't forward-declare a nested type.
    absl::FormatConvertResult<absl::FormatConversionCharSet::kString> AbslFormatConvert(
        Surface::Type value,
        const absl::FormatConversionSpec& spec,
        absl::FormatSink* s);

}  // namespace dawn::native

#endif  // SRC_DAWN_NATIVE_SURFACE_H_
