//
// Copyright 2018 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.
//

// GLES1State.cpp: Implements the GLES1State class, tracking state
// for GLES1 contexts.

#include "libANGLE/GLES1State.h"
#include "common/unsafe_buffers.h"

#include "libANGLE/Context.h"
#include "libANGLE/GLES1Renderer.h"

namespace gl
{

TextureCoordF::TextureCoordF() = default;

TextureCoordF::TextureCoordF(float _s, float _t, float _r, float _q) : s(_s), t(_t), r(_r), q(_q) {}

bool TextureCoordF::operator==(const TextureCoordF &other) const
{
    return s == other.s && t == other.t && r == other.r && q == other.q;
}

MaterialParameters::MaterialParameters() = default;

LightModelParameters::LightModelParameters() = default;

LightParameters::LightParameters() = default;

LightParameters::LightParameters(const LightParameters &other) = default;

FogParameters::FogParameters() = default;

AlphaTestParameters::AlphaTestParameters() = default;

bool AlphaTestParameters::operator!=(const AlphaTestParameters &other) const
{
    return func != other.func || ref != other.ref;
}

TextureEnvironmentParameters::TextureEnvironmentParameters() = default;

TextureEnvironmentParameters::TextureEnvironmentParameters(
    const TextureEnvironmentParameters &other) = default;

PointParameters::PointParameters() = default;

PointParameters::PointParameters(const PointParameters &other) = default;

ClipPlaneParameters::ClipPlaneParameters() = default;

ClipPlaneParameters::ClipPlaneParameters(bool enabled, const angle::Vector4 &equation)
    : enabled(enabled), equation(equation)
{}

ClipPlaneParameters::ClipPlaneParameters(const ClipPlaneParameters &other) = default;

ClipPlaneParameters &ClipPlaneParameters::operator=(const ClipPlaneParameters &other) = default;

GLES1State::GLES1State()
    : mGLState(nullptr),
      mVertexArrayEnabled(false),
      mNormalArrayEnabled(false),
      mColorArrayEnabled(false),
      mPointSizeArrayEnabled(false),
      mLineSmoothEnabled(false),
      mPointSmoothEnabled(false),
      mPointSpriteEnabled(false),
      mAlphaTestEnabled(false),
      mLogicOpEnabled(false),
      mLightingEnabled(false),
      mFogEnabled(false),
      mRescaleNormalEnabled(false),
      mNormalizeEnabled(false),
      mColorMaterialEnabled(false),
      mReflectionMapEnabled(false),
      mCurrentColor({0.0f, 0.0f, 0.0f, 0.0f}),
      mCurrentNormal({0.0f, 0.0f, 0.0f}),
      mClientActiveTexture(0),
      mMatrixMode(MatrixType::Modelview),
      mShadeModel(ShadingModel::Smooth),
      mLogicOp(LogicalOperation::Copy),
      mLineSmoothHint(HintSetting::DontCare),
      mPointSmoothHint(HintSetting::DontCare),
      mPerspectiveCorrectionHint(HintSetting::DontCare),
      mFogHint(HintSetting::DontCare)
{}

GLES1State::~GLES1State() = default;

// Taken from the GLES 1.x spec which specifies all initial state values.
void GLES1State::initialize(const Context *context, const PrivateState *state)
{
    mGLState = state;

    const Caps &caps = context->getCaps();

    mTexUnitEnables.resize(caps.maxMultitextureUnits);
    for (auto &enables : mTexUnitEnables)
    {
        enables.reset();
    }

    mVertexArrayEnabled    = false;
    mNormalArrayEnabled    = false;
    mColorArrayEnabled     = false;
    mPointSizeArrayEnabled = false;
    mTexCoordArrayEnabled.resize(caps.maxMultitextureUnits, false);

    mLineSmoothEnabled    = false;
    mPointSmoothEnabled   = false;
    mPointSpriteEnabled   = false;
    mLogicOpEnabled       = false;
    mAlphaTestEnabled     = false;
    mLightingEnabled      = false;
    mFogEnabled           = false;
    mRescaleNormalEnabled = false;
    mNormalizeEnabled     = false;
    mColorMaterialEnabled = false;
    mReflectionMapEnabled = false;

    mMatrixMode = MatrixType::Modelview;

    mCurrentColor  = {1.0f, 1.0f, 1.0f, 1.0f};
    mCurrentNormal = {0.0f, 0.0f, 1.0f};
    mCurrentTextureCoords.resize(caps.maxMultitextureUnits);
    mClientActiveTexture = 0;

    mTextureEnvironments.resize(caps.maxMultitextureUnits);

    mModelviewMatrices.push_back(angle::Mat4());
    mProjectionMatrices.push_back(angle::Mat4());
    mTextureMatrices.resize(caps.maxMultitextureUnits);
    for (auto &stack : mTextureMatrices)
    {
        stack.push_back(angle::Mat4());
    }

    mMaterial.ambient  = {0.2f, 0.2f, 0.2f, 1.0f};
    mMaterial.diffuse  = {0.8f, 0.8f, 0.8f, 1.0f};
    mMaterial.specular = {0.0f, 0.0f, 0.0f, 1.0f};
    mMaterial.emissive = {0.0f, 0.0f, 0.0f, 1.0f};

    mMaterial.specularExponent = 0.0f;

    mLightModel.color    = {0.2f, 0.2f, 0.2f, 1.0f};
    mLightModel.twoSided = false;

    mLights.resize(caps.maxLights);

    // GL_LIGHT0 is special and has default state that avoids all-black renderings.
    mLights[0].diffuse  = {1.0f, 1.0f, 1.0f, 1.0f};
    mLights[0].specular = {1.0f, 1.0f, 1.0f, 1.0f};

    mFog.mode    = FogMode::Exp;
    mFog.density = 1.0f;
    mFog.start   = 0.0f;
    mFog.end     = 1.0f;

    mFog.color = {0.0f, 0.0f, 0.0f, 0.0f};

    mShadeModel = ShadingModel::Smooth;

    mAlphaTestParameters.func = AlphaTestFunc::AlwaysPass;
    mAlphaTestParameters.ref  = 0.0f;

    mLogicOp = LogicalOperation::Copy;

    mClipPlanes.resize(caps.maxClipPlanes,
                       ClipPlaneParameters(false, angle::Vector4(0.0f, 0.0f, 0.0f, 0.0f)));

    mLineSmoothHint            = HintSetting::DontCare;
    mPointSmoothHint           = HintSetting::DontCare;
    mPerspectiveCorrectionHint = HintSetting::DontCare;
    mFogHint                   = HintSetting::DontCare;

    // The user-specified point size, GL_POINT_SIZE_MAX,
    // is initially equal to the implementation maximum.
    mPointParameters.pointSizeMax = caps.maxAliasedPointSize;

    mDirtyBits.set();
}

void GLES1State::setAlphaTestParameters(AlphaTestFunc func, GLfloat ref)
{
    setDirty(DIRTY_GLES1_ALPHA_TEST);
    mAlphaTestParameters.func = func;
    mAlphaTestParameters.ref  = ref;
}

void GLES1State::setClientTextureUnit(unsigned int unit)
{
    setDirty(DIRTY_GLES1_CLIENT_ACTIVE_TEXTURE);
    mClientActiveTexture = unit;
}

unsigned int GLES1State::getClientTextureUnit() const
{
    return mClientActiveTexture;
}

void GLES1State::setCurrentColor(const ColorF &color)
{
    setDirty(DIRTY_GLES1_CURRENT_VECTOR);
    mCurrentColor = color;

    // > When enabled, both the ambient (acm) and diffuse (dcm) properties of both the front and
    // > back material are immediately set to the value of the current color, and will track changes
    // > to the current color resulting from either the Color commands or drawing vertex arrays with
    // > the color array enabled.
    // > The replacements made to material properties are permanent; the replaced values remain
    // > until changed by either sending a new color or by setting a new material value when
    // > COLOR_MATERIAL is not currently enabled, to override that particular value.
    if (isColorMaterialEnabled())
    {
        mMaterial.ambient = color;
        mMaterial.diffuse = color;
    }
}

const ColorF &GLES1State::getCurrentColor() const
{
    return mCurrentColor;
}

void GLES1State::setCurrentNormal(const angle::Vector3 &normal)
{
    setDirty(DIRTY_GLES1_CURRENT_VECTOR);
    mCurrentNormal = normal;
}

const angle::Vector3 &GLES1State::getCurrentNormal() const
{
    return mCurrentNormal;
}

bool GLES1State::shouldHandleDirtyProgram()
{
    bool ret = isDirty(DIRTY_GLES1_PROGRAM);
    clearDirtyBits(DIRTY_GLES1_PROGRAM);
    return ret;
}

void GLES1State::setCurrentTextureCoords(unsigned int unit, const TextureCoordF &coords)
{
    setDirty(DIRTY_GLES1_CURRENT_VECTOR);
    mCurrentTextureCoords[unit] = coords;
}

const TextureCoordF &GLES1State::getCurrentTextureCoords(unsigned int unit) const
{
    return mCurrentTextureCoords[unit];
}

void GLES1State::setMatrixMode(MatrixType mode)
{
    setDirty(DIRTY_GLES1_MATRICES);
    mMatrixMode = mode;
}

MatrixType GLES1State::getMatrixMode() const
{
    return mMatrixMode;
}

GLint GLES1State::getCurrentMatrixStackDepth(GLenum queryType) const
{
    switch (queryType)
    {
        case GL_MODELVIEW_STACK_DEPTH:
            return clampCast<GLint>(mModelviewMatrices.size());
        case GL_PROJECTION_STACK_DEPTH:
            return clampCast<GLint>(mProjectionMatrices.size());
        case GL_TEXTURE_STACK_DEPTH:
            return clampCast<GLint>(mTextureMatrices[mGLState->getActiveSampler()].size());
        default:
            UNREACHABLE();
            return 0;
    }
}

void GLES1State::pushMatrix()
{
    setDirty(DIRTY_GLES1_MATRICES);
    auto &stack = currentMatrixStack();
    stack.push_back(stack.back());
}

void GLES1State::popMatrix()
{
    setDirty(DIRTY_GLES1_MATRICES);
    auto &stack = currentMatrixStack();
    stack.pop_back();
}

GLES1State::MatrixStack &GLES1State::currentMatrixStack()
{
    setDirty(DIRTY_GLES1_MATRICES);
    switch (mMatrixMode)
    {
        case MatrixType::Modelview:
            return mModelviewMatrices;
        case MatrixType::Projection:
            return mProjectionMatrices;
        case MatrixType::Texture:
            return mTextureMatrices[mGLState->getActiveSampler()];
        default:
            UNREACHABLE();
            return mModelviewMatrices;
    }
}

const angle::Mat4 &GLES1State::getModelviewMatrix() const
{
    return mModelviewMatrices.back();
}

const GLES1State::MatrixStack &GLES1State::getMatrixStack(MatrixType mode) const
{
    switch (mode)
    {
        case MatrixType::Modelview:
            return mModelviewMatrices;
        case MatrixType::Projection:
            return mProjectionMatrices;
        case MatrixType::Texture:
            return mTextureMatrices[mGLState->getActiveSampler()];
        default:
            UNREACHABLE();
            return mModelviewMatrices;
    }
}

const GLES1State::MatrixStack &GLES1State::currentMatrixStack() const
{
    return getMatrixStack(mMatrixMode);
}

void GLES1State::loadMatrix(const angle::Mat4 &m)
{
    setDirty(DIRTY_GLES1_MATRICES);
    currentMatrixStack().back() = m;
}

void GLES1State::multMatrix(const angle::Mat4 &m)
{
    setDirty(DIRTY_GLES1_MATRICES);
    angle::Mat4 currentMatrix   = currentMatrixStack().back();
    currentMatrixStack().back() = currentMatrix.product(m);
}

void GLES1State::setTextureEnabled(GLint activeSampler, TextureType type, bool enabled)
{
    setDirty(DIRTY_GLES1_TEXTURE_UNIT_ENABLE);
    mTexUnitEnables[activeSampler].set(type, enabled);
}

void GLES1State::setLogicOpEnabled(bool enabled)
{
    setDirty(DIRTY_GLES1_LOGIC_OP);
    mLogicOpEnabled = enabled;
}

void GLES1State::setLogicOp(LogicalOperation opcodePacked)
{
    setDirty(DIRTY_GLES1_LOGIC_OP);
    mLogicOp = opcodePacked;
}

void GLES1State::setClientStateEnabled(ClientVertexArrayType clientState, bool enable)
{
    setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
    switch (clientState)
    {
        case ClientVertexArrayType::Vertex:
            mVertexArrayEnabled = enable;
            break;
        case ClientVertexArrayType::Normal:
            mNormalArrayEnabled = enable;
            break;
        case ClientVertexArrayType::Color:
            mColorArrayEnabled = enable;
            break;
        case ClientVertexArrayType::PointSize:
            mPointSizeArrayEnabled = enable;
            break;
        case ClientVertexArrayType::TextureCoord:
            mTexCoordArrayEnabled[mClientActiveTexture] = enable;
            break;
        default:
            UNREACHABLE();
            break;
    }
}

void GLES1State::setTexCoordArrayEnabled(unsigned int unit, bool enable)
{
    setDirty(DIRTY_GLES1_CLIENT_STATE_ENABLE);
    mTexCoordArrayEnabled[unit] = enable;
}

bool GLES1State::isClientStateEnabled(ClientVertexArrayType clientState) const
{
    switch (clientState)
    {
        case ClientVertexArrayType::Vertex:
            return mVertexArrayEnabled;
        case ClientVertexArrayType::Normal:
            return mNormalArrayEnabled;
        case ClientVertexArrayType::Color:
            return mColorArrayEnabled;
        case ClientVertexArrayType::PointSize:
            return mPointSizeArrayEnabled;
        case ClientVertexArrayType::TextureCoord:
            return mTexCoordArrayEnabled[mClientActiveTexture];
        default:
            UNREACHABLE();
            return false;
    }
}

bool GLES1State::isTexCoordArrayEnabled(unsigned int unit) const
{
    ASSERT(unit < mTexCoordArrayEnabled.size());
    return mTexCoordArrayEnabled[unit];
}

bool GLES1State::isTextureTargetEnabled(unsigned int unit, const TextureType type) const
{
    if (mTexUnitEnables.empty())
    {
        return false;
    }
    return mTexUnitEnables[unit].test(type);
}

LightModelParameters &GLES1State::lightModelParameters()
{
    setDirty(DIRTY_GLES1_LIGHTS);
    return mLightModel;
}

const LightModelParameters &GLES1State::lightModelParameters() const
{
    return mLightModel;
}

LightParameters &GLES1State::lightParameters(unsigned int light)
{
    setDirty(DIRTY_GLES1_LIGHTS);
    return mLights[light];
}

const LightParameters &GLES1State::lightParameters(unsigned int light) const
{
    return mLights[light];
}

MaterialParameters &GLES1State::materialParameters()
{
    setDirty(DIRTY_GLES1_MATERIAL);
    return mMaterial;
}

const MaterialParameters &GLES1State::materialParameters() const
{
    return mMaterial;
}

bool GLES1State::isColorMaterialEnabled() const
{
    return mColorMaterialEnabled;
}

void GLES1State::setShadeModel(ShadingModel model)
{
    setDirty(DIRTY_GLES1_SHADE_MODEL);
    mShadeModel = model;
}

void GLES1State::setClipPlane(unsigned int plane, const GLfloat *equation)
{
    setDirty(DIRTY_GLES1_CLIP_PLANES);
    assert(plane < mClipPlanes.size());
    mClipPlanes[plane].equation[0] = equation[0];
    mClipPlanes[plane].equation[1] = ANGLE_UNSAFE_TODO(equation[1]);
    mClipPlanes[plane].equation[2] = ANGLE_UNSAFE_TODO(equation[2]);
    mClipPlanes[plane].equation[3] = ANGLE_UNSAFE_TODO(equation[3]);
}

void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
{
    assert(plane < mClipPlanes.size());
    equation[0] = mClipPlanes[plane].equation[0];
    ANGLE_UNSAFE_TODO(equation[1]) = mClipPlanes[plane].equation[1];
    ANGLE_UNSAFE_TODO(equation[2]) = mClipPlanes[plane].equation[2];
    ANGLE_UNSAFE_TODO(equation[3]) = mClipPlanes[plane].equation[3];
}

FogParameters &GLES1State::fogParameters()
{
    setDirty(DIRTY_GLES1_FOG);
    return mFog;
}

const FogParameters &GLES1State::fogParameters() const
{
    return mFog;
}

TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit)
{
    setDirty(DIRTY_GLES1_TEXTURE_ENVIRONMENT);
    assert(unit < mTextureEnvironments.size());
    return mTextureEnvironments[unit];
}

const TextureEnvironmentParameters &GLES1State::textureEnvironment(unsigned int unit) const
{
    assert(unit < mTextureEnvironments.size());
    return mTextureEnvironments[unit];
}

bool operator==(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b)
{
    return a.tie() == b.tie();
}

bool operator!=(const TextureEnvironmentParameters &a, const TextureEnvironmentParameters &b)
{
    return !(a == b);
}

PointParameters &GLES1State::pointParameters()
{
    setDirty(DIRTY_GLES1_POINT_PARAMETERS);
    return mPointParameters;
}

const PointParameters &GLES1State::pointParameters() const
{
    return mPointParameters;
}

const AlphaTestParameters &GLES1State::getAlphaTestParameters() const
{
    return mAlphaTestParameters;
}

AttributesMask GLES1State::getVertexArraysAttributeMask() const
{
    AttributesMask attribsMask;

    ClientVertexArrayType nonTexcoordArrays[] = {
        ClientVertexArrayType::Vertex,
        ClientVertexArrayType::Normal,
        ClientVertexArrayType::Color,
        ClientVertexArrayType::PointSize,
    };

    for (const ClientVertexArrayType attrib : nonTexcoordArrays)
    {
        attribsMask.set(GLES1Renderer::VertexArrayIndex(attrib, *this),
                        isClientStateEnabled(attrib));
    }

    for (unsigned int i = 0; i < kTexUnitCount; i++)
    {
        attribsMask.set(GLES1Renderer::TexCoordArrayIndex(i), isTexCoordArrayEnabled(i));
    }

    return attribsMask;
}

AttributesMask GLES1State::getActiveAttributesMask() const
{
    // The program always has 8 attributes enabled.
    return AttributesMask(0xFF);
}

void GLES1State::setHint(GLenum target, GLenum mode)
{
    setDirty(DIRTY_GLES1_HINT_SETTING);
    HintSetting setting = FromGLenum<HintSetting>(mode);
    switch (target)
    {
        case GL_PERSPECTIVE_CORRECTION_HINT:
            mPerspectiveCorrectionHint = setting;
            break;
        case GL_POINT_SMOOTH_HINT:
            mPointSmoothHint = setting;
            break;
        case GL_LINE_SMOOTH_HINT:
            mLineSmoothHint = setting;
            break;
        case GL_FOG_HINT:
            mFogHint = setting;
            break;
        default:
            UNREACHABLE();
    }
}

GLenum GLES1State::getHint(GLenum target) const
{
    switch (target)
    {
        case GL_PERSPECTIVE_CORRECTION_HINT:
            return ToGLenum(mPerspectiveCorrectionHint);
        case GL_POINT_SMOOTH_HINT:
            return ToGLenum(mPointSmoothHint);
        case GL_LINE_SMOOTH_HINT:
            return ToGLenum(mLineSmoothHint);
        case GL_FOG_HINT:
            return ToGLenum(mFogHint);
        default:
            UNREACHABLE();
            return 0;
    }
}

}  // namespace gl
