// Copyright 2019 The SwiftShader Authors. All Rights Reserved.
//
// 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.

#include "MetalSurface.hpp"
#include "Vulkan/VkDeviceMemory.hpp"
#include "Vulkan/VkImage.hpp"

#include <Metal/Metal.h>
#include <QuartzCore/CAMetalLayer.h>
#include <AppKit/NSView.h>

namespace vk {

class MetalLayer
{
public:
    void initWithLayer(const void* pLayer) API_AVAILABLE(macosx(10.11))
    {
        view = nullptr;
        layer = nullptr;

        id<NSObject> obj = (id<NSObject>)pLayer;

        if(!NSThread.isMainThread)
        {
            UNREACHABLE("MetalLayer::init(): not called from main thread");
        }
        if([obj isKindOfClass: [CAMetalLayer class]])
        {
            layer = (CAMetalLayer*)[obj retain];
            layer.framebufferOnly = false;
            layer.device = MTLCreateSystemDefaultDevice();
        }
        else
        {
            UNREACHABLE("MetalLayer::init(): view doesn't have metal backed layer");
        }
    }

    void initWithView(const void* pView) API_AVAILABLE(macosx(10.11))
    {
        view = nullptr;
        layer = nullptr;

        id<NSObject> obj = (id<NSObject>)pView;

        if([obj isKindOfClass: [NSView class]])
        {
            NSView* objView = (NSView*)[obj retain];

            initWithLayer(objView.layer);

            view = objView;
        }
    }

    void release() API_AVAILABLE(macosx(10.11))
    {
        if(layer)
        {
            [layer.device release];
            [layer release];
        }
        if(view)
        {
            [view release];
        }
    }

    VkExtent2D getExtent() const API_AVAILABLE(macosx(10.11))
    {
        if(layer)
        {
            CGSize drawSize = layer.bounds.size;
            CGFloat scaleFactor = layer.contentsScale;
            drawSize.width = trunc(drawSize.width * scaleFactor);
            drawSize.height = trunc(drawSize.height * scaleFactor);
            return { static_cast<uint32_t>(drawSize.width), static_cast<uint32_t>(drawSize.height) };
        }
        else
        {
            return { 0, 0 };
        }
    }

    id<CAMetalDrawable> getNextDrawable() const API_AVAILABLE(macosx(10.11))
    {
        if(layer)
        {
            return [layer nextDrawable];
        }

        return nil;
    }

private:
    NSView* view;
    CAMetalLayer* layer API_AVAILABLE(macosx(10.11));
};

MetalSurface::MetalSurface(const void *pCreateInfo, void *mem) : metalLayer(reinterpret_cast<MetalLayer*>(mem))
{

}

void MetalSurface::destroySurface(const VkAllocationCallbacks *pAllocator) API_AVAILABLE(macosx(10.11))
{
    if(metalLayer)
    {
        metalLayer->release();
    }

    vk::deallocate(metalLayer, pAllocator);
}

size_t MetalSurface::ComputeRequiredAllocationSize(const void *pCreateInfo) API_AVAILABLE(macosx(10.11))
{
    return sizeof(MetalLayer);
}

void MetalSurface::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const API_AVAILABLE(macosx(10.11))
{
    SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);

    VkExtent2D extent = metalLayer->getExtent();
    pSurfaceCapabilities->currentExtent = extent;
    pSurfaceCapabilities->minImageExtent = extent;
    pSurfaceCapabilities->maxImageExtent = extent;
}

VkResult MetalSurface::present(PresentImage* image) API_AVAILABLE(macosx(10.11))
{
    @autoreleasepool
    {
        auto drawable = metalLayer->getNextDrawable();
        if(drawable)
        {
            VkExtent2D windowExtent = metalLayer->getExtent();
            VkExtent3D extent = image->getImage()->getMipLevelExtent(VK_IMAGE_ASPECT_COLOR_BIT, 0);

            if(windowExtent.width != extent.width || windowExtent.height != extent.height)
            {
                return VK_ERROR_OUT_OF_DATE_KHR;
            }

            [drawable.texture replaceRegion:MTLRegionMake2D(0, 0, extent.width, extent.height)
                              mipmapLevel:0
                              withBytes:image->getImageMemory()->getOffsetPointer(0)
                              bytesPerRow:image->getImage()->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0)];
            [drawable present];

        }
    }
    return VK_SUCCESS;
}

#ifdef VK_USE_PLATFORM_METAL_EXT
MetalSurfaceEXT::MetalSurfaceEXT(const VkMetalSurfaceCreateInfoEXT *pCreateInfo, void *mem) API_AVAILABLE(macosx(10.11))
 : MetalSurface(pCreateInfo, mem)
{
    metalLayer->initWithLayer(pCreateInfo->pLayer);
}
#endif

#ifdef VK_USE_PLATFORM_MACOS_MVK
MacOSSurfaceMVK::MacOSSurfaceMVK(const VkMacOSSurfaceCreateInfoMVK *pCreateInfo, void *mem) API_AVAILABLE(macosx(10.11))
 : MetalSurface(pCreateInfo, mem)
{
    metalLayer->initWithView(pCreateInfo->pView);
}
#endif

}
