// 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 "backend/opengl/DepthStencilStateGL.h"

#include "backend/opengl/OpenGLBackend.h"
#include "backend/opengl/PersistentPipelineStateGL.h"
#include "common/Assert.h"

namespace backend {
namespace opengl {

    namespace {
        GLuint OpenGLCompareFunction(nxt::CompareFunction compareFunction) {
            switch (compareFunction) {
                case nxt::CompareFunction::Never:
                    return GL_NEVER;
                case nxt::CompareFunction::Less:
                    return GL_LESS;
                case nxt::CompareFunction::LessEqual:
                    return GL_LEQUAL;
                case nxt::CompareFunction::Greater:
                    return GL_GREATER;
                case nxt::CompareFunction::GreaterEqual:
                    return GL_GEQUAL;
                case nxt::CompareFunction::NotEqual:
                    return GL_NOTEQUAL;
                case nxt::CompareFunction::Equal:
                    return GL_EQUAL;
                case nxt::CompareFunction::Always:
                    return GL_ALWAYS;
                default:
                    UNREACHABLE();
            }
        }

        GLuint OpenGLStencilOperation(nxt::StencilOperation stencilOperation) {
            switch (stencilOperation) {
                case nxt::StencilOperation::Keep:
                    return GL_KEEP;
                case nxt::StencilOperation::Zero:
                    return GL_ZERO;
                case nxt::StencilOperation::Replace:
                    return GL_REPLACE;
                case nxt::StencilOperation::Invert:
                    return GL_INVERT;
                case nxt::StencilOperation::IncrementClamp:
                    return GL_INCR;
                case nxt::StencilOperation::DecrementClamp:
                    return GL_DECR;
                case nxt::StencilOperation::IncrementWrap:
                    return GL_INCR_WRAP;
                case nxt::StencilOperation::DecrementWrap:
                    return GL_DECR_WRAP;
                default:
                    UNREACHABLE();
            }
        }
    }

    DepthStencilState::DepthStencilState(DepthStencilStateBuilder* builder)
        : DepthStencilStateBase(builder) {
    }

    void DepthStencilState::ApplyNow(PersistentPipelineState &persistentPipelineState) const {
        auto& depthInfo = GetDepth();

        // Depth writes only occur if depth is enabled
        if (depthInfo.compareFunction == nxt::CompareFunction::Always && !depthInfo.depthWriteEnabled) {
            glDisable(GL_DEPTH_TEST);
        } else {
            glEnable(GL_DEPTH_TEST);
        }

        if (depthInfo.depthWriteEnabled) {
            glDepthMask(GL_TRUE);
        } else {
            glDepthMask(GL_FALSE);
        }

        glDepthFunc(OpenGLCompareFunction(depthInfo.compareFunction));

        if (StencilTestEnabled()) {
            glEnable(GL_STENCIL_TEST);
        } else {
            glDisable(GL_STENCIL_TEST);
        }

        auto& stencilInfo = GetStencil();

        GLenum backCompareFunction = OpenGLCompareFunction(stencilInfo.back.compareFunction);
        GLenum frontCompareFunction = OpenGLCompareFunction(stencilInfo.front.compareFunction);
        persistentPipelineState.SetStencilFuncsAndMask(backCompareFunction, frontCompareFunction, stencilInfo.readMask);

        glStencilOpSeparate(GL_BACK,
            OpenGLStencilOperation(stencilInfo.back.stencilFail),
            OpenGLStencilOperation(stencilInfo.back.depthFail),
            OpenGLStencilOperation(stencilInfo.back.depthStencilPass)
        );
        glStencilOpSeparate(GL_FRONT,
            OpenGLStencilOperation(stencilInfo.front.stencilFail),
            OpenGLStencilOperation(stencilInfo.front.depthFail),
            OpenGLStencilOperation(stencilInfo.front.depthStencilPass)
        );

        glStencilMask(stencilInfo.writeMask);

    }

}
}
