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

// GLES1Renderer.h: Defines GLES1 emulation rendering operations on top of a GLES3
// context. Used by Context.h.

#ifndef LIBANGLE_GLES1_RENDERER_H_
#define LIBANGLE_GLES1_RENDERER_H_

#include "GLES1State.h"
#include "angle_gl.h"
#include "common/angleutils.h"
#include "libANGLE/angletypes.h"

#include <memory>
#include <string>
#include <unordered_map>

namespace gl
{
class Context;
class GLES1State;
class Program;
class State;
class Shader;
class ShaderProgramManager;

enum class GLES1StateEnables : uint64_t
{
    Lighting           = 0,
    Fog                = 1,
    ClipPlanes         = 2,
    DrawTexture        = 3,
    PointRasterization = 4,
    PointSprite        = 5,
    RescaleNormal      = 6,
    Normalize          = 7,
    AlphaTest          = 8,
    ShadeModelFlat     = 9,
    ColorMaterial      = 10,
    LightModelTwoSided = 11,

    InvalidEnum = 12,
    EnumCount   = 12,
};

constexpr int kClipPlaneCount = 6;
constexpr int kTexUnitCount   = 4;
constexpr int kLightCount     = 8;

using GLES1StateEnabledBitSet = angle::PackedEnumBitSet<GLES1StateEnables, uint64_t>;

struct GLES1ShaderState
{
    GLES1ShaderState();
    ~GLES1ShaderState();
    GLES1ShaderState(const GLES1ShaderState &other);

    size_t hash() const;

    GLES1StateEnabledBitSet mGLES1StateEnabled;

    using BoolLightArray     = bool[kLightCount];
    using BoolTexArray       = bool[kTexUnitCount];
    using BoolClipPlaneArray = bool[kClipPlaneCount];
    using IntTexArray        = int[kTexUnitCount];

    BoolTexArray tex2DEnables   = {false, false, false, false};
    BoolTexArray texCubeEnables = {false, false, false, false};

    IntTexArray tex2DFormats = {GL_RGBA, GL_RGBA, GL_RGBA, GL_RGBA};

    IntTexArray texEnvModes          = {};
    IntTexArray texCombineRgbs       = {};
    IntTexArray texCombineAlphas     = {};
    IntTexArray texCombineSrc0Rgbs   = {};
    IntTexArray texCombineSrc0Alphas = {};
    IntTexArray texCombineSrc1Rgbs   = {};
    IntTexArray texCombineSrc1Alphas = {};
    IntTexArray texCombineSrc2Rgbs   = {};
    IntTexArray texCombineSrc2Alphas = {};
    IntTexArray texCombineOp0Rgbs    = {};
    IntTexArray texCombineOp0Alphas  = {};
    IntTexArray texCombineOp1Rgbs    = {};
    IntTexArray texCombineOp1Alphas  = {};
    IntTexArray texCombineOp2Rgbs    = {};
    IntTexArray texCombineOp2Alphas  = {};

    BoolTexArray pointSpriteCoordReplaces = {};

    BoolLightArray lightEnables = {};

    BoolClipPlaneArray clipPlaneEnables = {};

    AlphaTestFunc alphaTestFunc = {};

    FogMode fogMode = {};
};

bool operator==(const GLES1ShaderState &a, const GLES1ShaderState &b);
bool operator!=(const GLES1ShaderState &a, const GLES1ShaderState &b);

}  // namespace gl

namespace std
{
template <>
struct hash<gl::GLES1ShaderState>
{
    size_t operator()(const gl::GLES1ShaderState &key) const { return key.hash(); }
};
}  // namespace std

namespace gl
{

class GLES1Renderer final : angle::NonCopyable
{
  public:
    GLES1Renderer();
    ~GLES1Renderer();

    void onDestroy(Context *context, State *state);

    angle::Result prepareForDraw(PrimitiveMode mode, Context *context, State *glState);

    static int VertexArrayIndex(ClientVertexArrayType type, const GLES1State &gles1);
    static ClientVertexArrayType VertexArrayType(int attribIndex);
    static int TexCoordArrayIndex(unsigned int unit);

    void drawTexture(Context *context,
                     State *glState,
                     float x,
                     float y,
                     float z,
                     float width,
                     float height);

  private:
    using Mat4Uniform = float[16];
    using Vec4Uniform = float[4];
    using Vec3Uniform = float[3];

    Shader *getShader(ShaderProgramID handle) const;
    Program *getProgram(ShaderProgramID handle) const;

    angle::Result compileShader(Context *context,
                                ShaderType shaderType,
                                const char *src,
                                ShaderProgramID *shaderOut);
    angle::Result linkProgram(Context *context,
                              State *glState,
                              ShaderProgramID vshader,
                              ShaderProgramID fshader,
                              const angle::HashMap<GLint, std::string> &attribLocs,
                              ShaderProgramID *programOut);
    angle::Result initializeRendererProgram(Context *context, State *glState);

    void setUniform1i(Context *context,
                      Program *programObject,
                      UniformLocation location,
                      GLint value);
    void setUniform1iv(Context *context,
                       Program *programObject,
                       UniformLocation location,
                       GLint count,
                       const GLint *value);
    void setUniformMatrix4fv(Program *programObject,
                             UniformLocation location,
                             GLint count,
                             GLboolean transpose,
                             const GLfloat *value);
    void setUniform4fv(Program *programObject,
                       UniformLocation location,
                       GLint count,
                       const GLfloat *value);
    void setUniform3fv(Program *programObject,
                       UniformLocation location,
                       GLint count,
                       const GLfloat *value);
    void setUniform2fv(Program *programObject,
                       UniformLocation location,
                       GLint count,
                       const GLfloat *value);
    void setUniform1f(Program *programObject, UniformLocation location, GLfloat value);
    void setUniform1fv(Program *programObject,
                       UniformLocation location,
                       GLint count,
                       const GLfloat *value);

    void setAttributesEnabled(Context *context, State *glState, AttributesMask mask);

    static constexpr int kVertexAttribIndex           = 0;
    static constexpr int kNormalAttribIndex           = 1;
    static constexpr int kColorAttribIndex            = 2;
    static constexpr int kPointSizeAttribIndex        = 3;
    static constexpr int kTextureCoordAttribIndexBase = 4;

    bool mRendererProgramInitialized;
    ShaderProgramManager *mShaderPrograms;

    GLES1ShaderState mShaderState = {};

    const char *getShaderBool(GLES1StateEnables state);
    void addShaderDefine(std::stringstream &outStream,
                         GLES1StateEnables state,
                         const char *enableString);
    void addShaderInt(std::stringstream &outStream, const char *name, int value);
    void addShaderIntTexArray(std::stringstream &outStream,
                              const char *texString,
                              GLES1ShaderState::IntTexArray &texState);
    void addShaderBoolTexArray(std::stringstream &outStream,
                               const char *texString,
                               GLES1ShaderState::BoolTexArray &texState);
    void addShaderBoolLightArray(std::stringstream &outStream,
                                 const char *name,
                                 GLES1ShaderState::BoolLightArray &value);
    void addShaderBoolClipPlaneArray(std::stringstream &outStream,
                                     const char *name,
                                     GLES1ShaderState::BoolClipPlaneArray &value);
    void addVertexShaderDefs(std::stringstream &outStream);
    void addFragmentShaderDefs(std::stringstream &outStream);

    struct GLES1ProgramState
    {
        ShaderProgramID program;

        UniformLocation projMatrixLoc;
        UniformLocation modelviewMatrixLoc;
        UniformLocation textureMatrixLoc;
        UniformLocation modelviewInvTrLoc;

        // Texturing
        std::array<UniformLocation, kTexUnitCount> tex2DSamplerLocs;
        std::array<UniformLocation, kTexUnitCount> texCubeSamplerLocs;

        UniformLocation textureEnvColorLoc;
        UniformLocation rgbScaleLoc;
        UniformLocation alphaScaleLoc;

        // Alpha test
        UniformLocation alphaTestRefLoc;

        // Shading, materials, and lighting
        UniformLocation materialAmbientLoc;
        UniformLocation materialDiffuseLoc;
        UniformLocation materialSpecularLoc;
        UniformLocation materialEmissiveLoc;
        UniformLocation materialSpecularExponentLoc;

        UniformLocation lightModelSceneAmbientLoc;

        UniformLocation lightAmbientsLoc;
        UniformLocation lightDiffusesLoc;
        UniformLocation lightSpecularsLoc;
        UniformLocation lightPositionsLoc;
        UniformLocation lightDirectionsLoc;
        UniformLocation lightSpotlightExponentsLoc;
        UniformLocation lightSpotlightCutoffAnglesLoc;
        UniformLocation lightAttenuationConstsLoc;
        UniformLocation lightAttenuationLinearsLoc;
        UniformLocation lightAttenuationQuadraticsLoc;

        // Fog
        UniformLocation fogDensityLoc;
        UniformLocation fogStartLoc;
        UniformLocation fogEndLoc;
        UniformLocation fogColorLoc;

        // Clip planes
        UniformLocation clipPlanesLoc;

        // Point rasterization
        UniformLocation pointSizeMinLoc;
        UniformLocation pointSizeMaxLoc;
        UniformLocation pointDistanceAttenuationLoc;

        // Draw texture
        UniformLocation drawTextureCoordsLoc;
        UniformLocation drawTextureDimsLoc;
        UniformLocation drawTextureNormalizedCropRectLoc;
    };

    struct GLES1UniformBuffers
    {
        std::array<Mat4Uniform, kTexUnitCount> textureMatrices;

        std::array<Vec4Uniform, kTexUnitCount> texEnvColors;
        std::array<GLfloat, kTexUnitCount> texEnvRgbScales;
        std::array<GLfloat, kTexUnitCount> texEnvAlphaScales;

        // Lighting
        std::array<Vec4Uniform, kLightCount> lightAmbients;
        std::array<Vec4Uniform, kLightCount> lightDiffuses;
        std::array<Vec4Uniform, kLightCount> lightSpeculars;
        std::array<Vec4Uniform, kLightCount> lightPositions;
        std::array<Vec3Uniform, kLightCount> lightDirections;
        std::array<GLfloat, kLightCount> spotlightExponents;
        std::array<GLfloat, kLightCount> spotlightCutoffAngles;
        std::array<GLfloat, kLightCount> attenuationConsts;
        std::array<GLfloat, kLightCount> attenuationLinears;
        std::array<GLfloat, kLightCount> attenuationQuadratics;

        // Clip planes
        std::array<Vec4Uniform, kClipPlaneCount> clipPlanes;

        // Texture crop rectangles
        std::array<Vec4Uniform, kTexUnitCount> texCropRects;
    };

    struct GLES1UberShaderState
    {
        GLES1UniformBuffers uniformBuffers;
        GLES1ProgramState programState;
    };

    GLES1UberShaderState &getUberShaderState()
    {
        ASSERT(mUberShaderState.find(mShaderState) != mUberShaderState.end());
        return mUberShaderState[mShaderState];
    }

    angle::HashMap<GLES1ShaderState, GLES1UberShaderState> mUberShaderState;

    bool mDrawTextureEnabled      = false;
    GLfloat mDrawTextureCoords[4] = {0.0f, 0.0f, 0.0f, 0.0f};
    GLfloat mDrawTextureDims[2]   = {0.0f, 0.0f};
};

}  // namespace gl

#endif  // LIBANGLE_GLES1_RENDERER_H_
