//
// 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 "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] = equation[1];
    mClipPlanes[plane].equation[2] = equation[2];
    mClipPlanes[plane].equation[3] = equation[3];
}

void GLES1State::getClipPlane(unsigned int plane, GLfloat *equation) const
{
    assert(plane < mClipPlanes.size());
    equation[0] = mClipPlanes[plane].equation[0];
    equation[1] = mClipPlanes[plane].equation[1];
    equation[2] = mClipPlanes[plane].equation[2];
    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
