// Copyright 2017 The NXT 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.

#include "Framebuffer.h"

#include "Buffer.h"
#include "Device.h"
#include "RenderPass.h"
#include "Texture.h"

namespace backend {

    // Framebuffer

    FramebufferBase::FramebufferBase(FramebufferBuilder* builder)
        : renderPass(std::move(builder->renderPass)), width(builder->width), height(builder->height), textureViews(std::move(builder->textureViews)) {
    }

    RenderPassBase* FramebufferBase::GetRenderPass() {
        return renderPass.Get();
    }

    TextureViewBase* FramebufferBase::GetTextureView(uint32_t index) {
        ASSERT(index < textureViews.size());
        return textureViews[index].Get();
    }

    // FramebufferBuilder

    enum FramebufferSetProperties {
        FRAMEBUFFER_PROPERTY_RENDER_PASS = 0x1,
        FRAMEBUFFER_PROPERTY_DIMENSIONS = 0x2,
    };

    FramebufferBuilder::FramebufferBuilder(DeviceBase* device)
        : Builder(device) {
    }

    FramebufferBase* FramebufferBuilder::GetResultImpl() {
        constexpr int requiredProperties = FRAMEBUFFER_PROPERTY_RENDER_PASS | FRAMEBUFFER_PROPERTY_DIMENSIONS;
        if ((propertiesSet & requiredProperties) != requiredProperties) {
            HandleError("Framebuffer missing properties");
            return nullptr;
        }

        // TODO(kainino@chromium.org): Remove this flag when the
        // null=backbuffer hack is removed. Then, using null texture views can
        // be completely disallowed.
        bool usingBackbufferHack = false;
        for (auto& textureView : textureViews) {
            if (!textureView) {
                if (usingBackbufferHack) {
                    // TODO(kainino@chromium.org) update this too
                    HandleError("Framebuffer has more than one null attachment");
                    return nullptr;
                }
                usingBackbufferHack = true;
            }
        }

        return device->CreateFramebuffer(this);
    }

    void FramebufferBuilder::SetRenderPass(RenderPassBase* renderPass) {
        if ((propertiesSet & FRAMEBUFFER_PROPERTY_RENDER_PASS) != 0) {
            HandleError("Framebuffer render pass property set multiple times");
            return;
        }

        this->renderPass = renderPass;
        this->textureViews.resize(renderPass->GetAttachmentCount());
        propertiesSet |= FRAMEBUFFER_PROPERTY_RENDER_PASS;
    }

    void FramebufferBuilder::SetDimensions(uint32_t width, uint32_t height) {
        if ((propertiesSet & FRAMEBUFFER_PROPERTY_DIMENSIONS) != 0) {
            HandleError("Framebuffer dimensions property set multiple times");
            return;
        }

        this->width = width;
        this->height = height;
        propertiesSet |= FRAMEBUFFER_PROPERTY_DIMENSIONS;
    }

    void FramebufferBuilder::SetAttachment(uint32_t attachmentSlot, TextureViewBase* textureView) {
        if ((propertiesSet & FRAMEBUFFER_PROPERTY_RENDER_PASS) == 0) {
            HandleError("Render pass must be set before framebuffer attachments");
            return;
        }
        if (attachmentSlot >= textureViews.size()) {
            HandleError("Attachment slot out of bounds");
            return;
        }
        if (textureViews[attachmentSlot]) {
            HandleError("Framebuffer attachment[i] set multiple times");
            return;
        }
        const auto& attachmentInfo = renderPass->GetAttachmentInfo(attachmentSlot);
        const auto* texture = textureView->GetTexture();
        if (attachmentInfo.format != texture->GetFormat()) {
            HandleError("Texture format does not match attachment format");
            return;
        }
        // TODO(kainino@chromium.org): also check attachment samples, etc.

        textureViews[attachmentSlot] = textureView;
    }
}
