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

#include <rs_hal.h>
#include <rsContext.h>

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

#include "rsdGL.h"
#include "rsdCore.h"
#include "rsdVertexArray.h"
#include "rsdShaderCache.h"

using namespace android;
using namespace android::renderscript;

RsdVertexArray::RsdVertexArray(const Attrib *attribs, uint32_t numAttribs) {
    mAttribs = attribs;
    mCount = numAttribs;
}

RsdVertexArray::~RsdVertexArray() {
}

RsdVertexArray::Attrib::Attrib() {
    clear();
}

void RsdVertexArray::Attrib::clear() {
    buffer = 0;
    offset = 0;
    type = 0;
    size = 0;
    stride = 0;
    ptr = NULL;
    normalized = false;
    name.setTo("");
}

void RsdVertexArray::Attrib::set(uint32_t type, uint32_t size, uint32_t stride,
                              bool normalized, uint32_t offset,
                              const char *name) {
    clear();
    this->type = type;
    this->size = size;
    this->offset = offset;
    this->normalized = normalized;
    this->stride = stride;
    this->name.setTo(name);
}

void RsdVertexArray::logAttrib(uint32_t idx, uint32_t slot) const {
    if (idx == 0) {
        LOGV("Starting vertex attribute binding");
    }
    LOGV("va %i: slot=%i name=%s buf=%i ptr=%p size=%i  type=0x%x  stride=0x%x  norm=%i  offset=0x%x",
         idx, slot,
         mAttribs[idx].name.string(),
         mAttribs[idx].buffer,
         mAttribs[idx].ptr,
         mAttribs[idx].size,
         mAttribs[idx].type,
         mAttribs[idx].stride,
         mAttribs[idx].normalized,
         mAttribs[idx].offset);
}

void RsdVertexArray::setup(const Context *rsc) const {

    RsdHal *dc = (RsdHal *)rsc->mHal.drv;
    RsdVertexArrayState *state = dc->gl.vertexArrayState;
    RsdShaderCache *sc = dc->gl.shaderCache;

    rsdGLCheckError(rsc, "RsdVertexArray::setup start");
    uint32_t maxAttrs = state->mAttrsEnabledSize;

    for (uint32_t ct=1; ct < maxAttrs; ct++) {
        if(state->mAttrsEnabled[ct]) {
            glDisableVertexAttribArray(ct);
            state->mAttrsEnabled[ct] = false;
        }
    }

    rsdGLCheckError(rsc, "RsdVertexArray::setup disabled");
    for (uint32_t ct=0; ct < mCount; ct++) {
        int32_t slot = sc->vtxAttribSlot(mAttribs[ct].name);
        if (rsc->props.mLogShadersAttr) {
            logAttrib(ct, slot);
        }
        if (slot < 0 || slot >= (int32_t)maxAttrs) {
            continue;
        }
        glEnableVertexAttribArray(slot);
        state->mAttrsEnabled[slot] = true;
        glBindBuffer(GL_ARRAY_BUFFER, mAttribs[ct].buffer);
        glVertexAttribPointer(slot,
                              mAttribs[ct].size,
                              mAttribs[ct].type,
                              mAttribs[ct].normalized,
                              mAttribs[ct].stride,
                              mAttribs[ct].ptr + mAttribs[ct].offset);
    }
    rsdGLCheckError(rsc, "RsdVertexArray::setup done");
}
////////////////////////////////////////////
RsdVertexArrayState::RsdVertexArrayState() {
    mAttrsEnabled = NULL;
    mAttrsEnabledSize = 0;
}

RsdVertexArrayState::~RsdVertexArrayState() {
    if (mAttrsEnabled) {
        delete[] mAttrsEnabled;
        mAttrsEnabled = NULL;
    }
}
void RsdVertexArrayState::init(uint32_t maxAttrs) {
    mAttrsEnabledSize = maxAttrs;
    mAttrsEnabled = new bool[mAttrsEnabledSize];
    for (uint32_t ct = 0; ct < mAttrsEnabledSize; ct++) {
        mAttrsEnabled[ct] = false;
    }
}

