/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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.
*/
#ifndef _GL_CLIENT_STATE_H_
#define _GL_CLIENT_STATE_H_

#define GL_API
#ifndef ANDROID
#define GL_APIENTRY
#define GL_APIENTRYP
#endif

#include <GLES/gl.h>
#include <GLES/glext.h>
#include <GLES2/gl2.h>
#include <GLES2/gl2ext.h>

#include <stdio.h>
#include <stdlib.h>
#include "ErrorLog.h"
#include "codec_defs.h"

class GLClientState {
public:
    typedef enum {
        VERTEX_LOCATION = 0,
        NORMAL_LOCATION = 1,
        COLOR_LOCATION = 2,
        POINTSIZE_LOCATION = 3,
        TEXCOORD0_LOCATION = 4,
        TEXCOORD1_LOCATION = 5,
        TEXCOORD2_LOCATION = 6,
        TEXCOORD3_LOCATION = 7,
        TEXCOORD4_LOCATION = 8,
        TEXCOORD5_LOCATION = 9,
        TEXCOORD6_LOCATION = 10,
        TEXCOORD7_LOCATION = 11,
        MATRIXINDEX_LOCATION = 12,
        WEIGHT_LOCATION = 13,
        LAST_LOCATION = 14
    } StateLocation;

    typedef struct {
        GLint enabled;
        GLint size;
        GLenum type;
        GLsizei stride;
        void *data;
        GLuint bufferObject;
        GLenum glConst;
        unsigned int elementSize;
        bool enableDirty;  // true if any enable state has changed since last draw
        bool normalized;
    } VertexAttribState;

    typedef struct {
        int unpack_alignment;
        int pack_alignment;
    } PixelStoreState;

    enum {
        MAX_TEXTURE_UNITS = 32,
    };

public:
    GLClientState(int nLocations = CODEC_MAX_VERTEX_ATTRIBUTES);
    ~GLClientState();
    int nLocations() { return m_nLocations; }
    const PixelStoreState *pixelStoreState() { return &m_pixelStore; }
    int setPixelStore(GLenum param, GLint value);
    GLuint currentArrayVbo() { return m_currentArrayVbo; }
    GLuint currentIndexVbo() { return m_currentIndexVbo; }
    void enable(int location, int state);
    void setState(int  location, int size, GLenum type, GLboolean normalized, GLsizei stride, const void *data);
    void setBufferObject(int location, GLuint id);
    const VertexAttribState  *getState(int location);
    const VertexAttribState  *getStateAndEnableDirty(int location, bool *enableChanged);
    int getLocation(GLenum loc);
    void setActiveTexture(int texUnit) {m_activeTexture = texUnit; };
    int getActiveTexture() const { return m_activeTexture; }

    int bindBuffer(GLenum target, GLuint id)
    {
        int err = 0;
        switch(target) {
        case GL_ARRAY_BUFFER:
            m_currentArrayVbo = id;
            break;
        case GL_ELEMENT_ARRAY_BUFFER:
            m_currentIndexVbo = id;
            break;
        default:
            err = -1;
        }
        return err;
    }

    int getBuffer(GLenum target)
    {
      int ret=0;
      switch (target) {
      case GL_ARRAY_BUFFER:
          ret = m_currentArrayVbo;
          break;
      case GL_ELEMENT_ARRAY_BUFFER:
          ret = m_currentIndexVbo;
          break;
      default:
          ret = -1;
      }
      return ret;
    }
    size_t pixelDataSize(GLsizei width, GLsizei height, GLenum format, GLenum type, int pack) const;

    void setCurrentProgram(GLint program) { m_currentProgram = program; }
    GLint currentProgram() const { return m_currentProgram; }

    /* OES_EGL_image_external
     *
     * These functions manipulate GL state which interacts with the
     * OES_EGL_image_external extension, to support client-side emulation on
     * top of host implementations that don't have it.
     *
     * Most of these calls should only be used with TEXTURE_2D or
     * TEXTURE_EXTERNAL_OES texture targets; TEXTURE_CUBE_MAP or other extension
     * targets should bypass this. An exception is bindTexture(), which should
     * see all glBindTexture() calls for any target.
     */

    // glActiveTexture(GL_TEXTURE0 + i)
    // Sets the active texture unit. Up to MAX_TEXTURE_UNITS are supported.
    GLenum setActiveTextureUnit(GLenum texture);
    GLenum getActiveTextureUnit() const;

    // glEnable(GL_TEXTURE_(2D|EXTERNAL_OES))
    void enableTextureTarget(GLenum target);

    // glDisable(GL_TEXTURE_(2D|EXTERNAL_OES))
    void disableTextureTarget(GLenum target);

    // Implements the target priority logic:
    // * Return GL_TEXTURE_EXTERNAL_OES if enabled, else
    // * Return GL_TEXTURE_2D if enabled, else
    // * Return the allDisabled value.
    // For some cases passing GL_TEXTURE_2D for allDisabled makes callee code
    // simpler; for other cases passing a recognizable enum like GL_ZERO or
    // GL_INVALID_ENUM is appropriate.
    GLenum getPriorityEnabledTarget(GLenum allDisabled) const;

    // glBindTexture(GL_TEXTURE_*, ...)
    // Set the target binding of the active texture unit to texture. Returns
    // GL_NO_ERROR on success or GL_INVALID_OPERATION if the texture has
    // previously been bound to a different target. If firstUse is not NULL,
    // it is set to indicate whether this is the first use of the texture.
    // For accurate error detection, bindTexture should be called for *all*
    // targets, not just 2D and EXTERNAL_OES.
    GLenum bindTexture(GLenum target, GLuint texture, GLboolean* firstUse);

    // Return the texture currently bound to GL_TEXTURE_(2D|EXTERNAL_OES).
    GLuint getBoundTexture(GLenum target) const;

    // glDeleteTextures(...)
    // Remove references to the to-be-deleted textures.
    void deleteTextures(GLsizei n, const GLuint* textures);

private:
    PixelStoreState m_pixelStore;
    VertexAttribState *m_states;
    int m_nLocations;
    GLuint m_currentArrayVbo;
    GLuint m_currentIndexVbo;
    int m_activeTexture;
    GLint m_currentProgram;

    bool validLocation(int location) { return (location >= 0 && location < m_nLocations); }

    enum TextureTarget {
        TEXTURE_2D = 0,
        TEXTURE_EXTERNAL = 1,
        TEXTURE_TARGET_COUNT
    };
    struct TextureUnit {
        unsigned int enables;
        GLuint texture[TEXTURE_TARGET_COUNT];
    };
    struct TextureRec {
        GLuint id;
        GLenum target;
    };
    struct TextureState {
        TextureUnit unit[MAX_TEXTURE_UNITS];
        TextureUnit* activeUnit;
        TextureRec* textures;
        GLuint numTextures;
        GLuint allocTextures;
    };
    TextureState m_tex;

    static int compareTexId(const void* pid, const void* prec);
    TextureRec* addTextureRec(GLuint id, GLenum target);

public:
    void getClientStatePointer(GLenum pname, GLvoid** params);

    template <class T>
    int getVertexAttribParameter(GLuint index, GLenum param, T *ptr)
    {
        bool handled = true;
        const VertexAttribState *vertexAttrib = getState(index);
        if (vertexAttrib == NULL) {
            ERR("getVeterxAttriParameter for non existant index %d\n", index);
            // set gl error;
            return handled;
        }

        switch(param) {
        case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
            *ptr = (T)(vertexAttrib->bufferObject);
            break;
        case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
            *ptr = (T)(vertexAttrib->enabled);
            break;
        case GL_VERTEX_ATTRIB_ARRAY_SIZE:
            *ptr = (T)(vertexAttrib->size);
            break;
        case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
            *ptr = (T)(vertexAttrib->stride);
            break;
        case GL_VERTEX_ATTRIB_ARRAY_TYPE:
            *ptr = (T)(vertexAttrib->type);
            break;
        case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
            *ptr = (T)(vertexAttrib->normalized);
            break;
        case GL_CURRENT_VERTEX_ATTRIB:
            handled = false;
            break;
        default:
            handled = false;
            ERR("unknown vertex-attrib parameter param %d\n", param);
        }
        return handled;
    }

    template <class T>
    bool getClientStateParameter(GLenum param, T* ptr)
    {
        bool isClientStateParam = false;
        switch (param) {
        case GL_CLIENT_ACTIVE_TEXTURE: {
            GLint tex = getActiveTexture() + GL_TEXTURE0;
            *ptr = tex;
            isClientStateParam = true;
            break;
            }
        case GL_VERTEX_ARRAY_SIZE: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
            *ptr = state->size;
            isClientStateParam = true;
            break;
            }
        case GL_VERTEX_ARRAY_TYPE: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
            *ptr = state->type;
            isClientStateParam = true;
            break;
            }
        case GL_VERTEX_ARRAY_STRIDE: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
            *ptr = state->stride;
            isClientStateParam = true;
            break;
            }
        case GL_COLOR_ARRAY_SIZE: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
            *ptr = state->size;
            isClientStateParam = true;
            break;
            }
        case GL_COLOR_ARRAY_TYPE: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
            *ptr = state->type;
            isClientStateParam = true;
            break;
            }
        case GL_COLOR_ARRAY_STRIDE: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
            *ptr = state->stride;
            isClientStateParam = true;
            break;
            }
        case GL_NORMAL_ARRAY_TYPE: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
            *ptr = state->type;
            isClientStateParam = true;
            break;
            }
        case GL_NORMAL_ARRAY_STRIDE: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
            *ptr = state->stride;
            isClientStateParam = true;
            break;
            }
        case GL_TEXTURE_COORD_ARRAY_SIZE: {
            const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
            *ptr = state->size;
            isClientStateParam = true;
            break;
            }
        case GL_TEXTURE_COORD_ARRAY_TYPE: {
            const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
            *ptr = state->type;
            isClientStateParam = true;
            break;
            }
        case GL_TEXTURE_COORD_ARRAY_STRIDE: {
            const GLClientState::VertexAttribState *state = getState(getActiveTexture() + GLClientState::TEXCOORD0_LOCATION);
            *ptr = state->stride;
            isClientStateParam = true;
            break;
            }
        case GL_POINT_SIZE_ARRAY_TYPE_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
            *ptr = state->type;
            isClientStateParam = true;
            break;
            }
        case GL_POINT_SIZE_ARRAY_STRIDE_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
            *ptr = state->stride;
            isClientStateParam = true;
            break;
            }
        case GL_MATRIX_INDEX_ARRAY_SIZE_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
            *ptr = state->size;
            isClientStateParam = true;
            break;
            }
        case GL_MATRIX_INDEX_ARRAY_TYPE_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
            *ptr = state->type;
            isClientStateParam = true;
            break;
            }
        case GL_MATRIX_INDEX_ARRAY_STRIDE_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
            *ptr = state->stride;
            isClientStateParam = true;
            break;
            }
        case GL_WEIGHT_ARRAY_SIZE_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
            *ptr = state->size;
            isClientStateParam = true;
            break;
            }
        case GL_WEIGHT_ARRAY_TYPE_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
            *ptr = state->type;
            isClientStateParam = true;
            break;
            }
        case GL_WEIGHT_ARRAY_STRIDE_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
            *ptr = state->stride;
            isClientStateParam = true;
            break;
            }
        case GL_VERTEX_ARRAY_BUFFER_BINDING: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::VERTEX_LOCATION);
            *ptr = state->bufferObject;
            isClientStateParam = true;
            break;
            }
        case GL_NORMAL_ARRAY_BUFFER_BINDING: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::NORMAL_LOCATION);
            *ptr = state->bufferObject;
            isClientStateParam = true;
            break;
            }
        case GL_COLOR_ARRAY_BUFFER_BINDING: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::COLOR_LOCATION);
            *ptr = state->bufferObject;
            isClientStateParam = true;
            break;
            }
        case GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING: {
            const GLClientState::VertexAttribState *state = getState(getActiveTexture()+GLClientState::TEXCOORD0_LOCATION);
            *ptr = state->bufferObject;
            isClientStateParam = true;
            break;
            }
        case GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::POINTSIZE_LOCATION);
            *ptr = state->bufferObject;
            isClientStateParam = true;
            break;
            }
        case GL_MATRIX_INDEX_ARRAY_BUFFER_BINDING_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::MATRIXINDEX_LOCATION);
            *ptr = state->bufferObject;
            isClientStateParam = true;
            break;
            }
        case GL_WEIGHT_ARRAY_BUFFER_BINDING_OES: {
            const GLClientState::VertexAttribState *state = getState(GLClientState::WEIGHT_LOCATION);
            *ptr = state->bufferObject;
            isClientStateParam = true;
            break;
            }
        case GL_ARRAY_BUFFER_BINDING: {
            int buffer = getBuffer(GL_ARRAY_BUFFER);
            *ptr = buffer;
            isClientStateParam = true;
            break;
            }
        case GL_ELEMENT_ARRAY_BUFFER_BINDING: {
            int buffer = getBuffer(GL_ELEMENT_ARRAY_BUFFER);
            *ptr = buffer;
            isClientStateParam = true;
            break;
            }
        }
        return isClientStateParam;
    }

};
#endif
