
/*
 * Copyright (C) 2009 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 "rsContext.h"


#include <utils/String8.h>
#include "rsFileA3D.h"

#include "rsMesh.h"

using namespace android;
using namespace android::renderscript;



FileA3D::FileA3D()
{
    mRsc = NULL;
}

FileA3D::~FileA3D()
{
}

bool FileA3D::load(Context *rsc, FILE *f)
{
    char magicString[12];
    size_t len;

    LOGE("file open 1");
    len = fread(magicString, 1, 12, f);
    if ((len != 12) ||
        memcmp(magicString, "Android3D_ff", 12)) {
        return false;
    }

    LOGE("file open 2");
    len = fread(&mMajorVersion, 1, sizeof(mMajorVersion), f);
    if (len != sizeof(mMajorVersion)) {
        return false;
    }

    LOGE("file open 3");
    len = fread(&mMinorVersion, 1, sizeof(mMinorVersion), f);
    if (len != sizeof(mMinorVersion)) {
        return false;
    }

    LOGE("file open 4");
    uint32_t flags;
    len = fread(&flags, 1, sizeof(flags), f);
    if (len != sizeof(flags)) {
        return false;
    }
    mUse64BitOffsets = (flags & 1) != 0;

    LOGE("file open 64bit = %i", mUse64BitOffsets);

    if (mUse64BitOffsets) {
        len = fread(&mDataSize, 1, sizeof(mDataSize), f);
        if (len != sizeof(mDataSize)) {
            return false;
        }
    } else {
        uint32_t tmp;
        len = fread(&tmp, 1, sizeof(tmp), f);
        if (len != sizeof(tmp)) {
            return false;
        }
        mDataSize = tmp;
    }

    LOGE("file open size = %lli", mDataSize);

    // We should know enough to read the file in at this point.
    fseek(f, SEEK_SET, 0);
    mAlloc= malloc(mDataSize);
    if (!mAlloc) {
        return false;
    }
    mData = (uint8_t *)mAlloc;
    len = fread(mAlloc, 1, mDataSize, f);
    if (len != mDataSize) {
        return false;
    }

    LOGE("file start processing");
    return process(rsc);
}

bool FileA3D::processIndex(Context *rsc, A3DIndexEntry *ie)
{
    bool ret = false;
    IO io(mData + ie->mOffset, mUse64BitOffsets);

    LOGE("process index, type %i", ie->mType);

    switch(ie->mType) {
    case CHUNK_ELEMENT:
        processChunk_Element(rsc, &io, ie);
        break;
    case CHUNK_ELEMENT_SOURCE:
        processChunk_ElementSource(rsc, &io, ie);
        break;
    case CHUNK_VERTICIES:
        processChunk_Verticies(rsc, &io, ie);
        break;
    case CHUNK_MESH:
        processChunk_Mesh(rsc, &io, ie);
        break;
    case CHUNK_PRIMITIVE:
        processChunk_Primitive(rsc, &io, ie);
        break;
    default:
        LOGE("FileA3D Unknown chunk type");
        break;
    }
    return (ie->mRsObj != NULL);
}

bool FileA3D::process(Context *rsc)
{
    LOGE("process");
    IO io(mData + 12, mUse64BitOffsets);
    bool ret = true;

    // Build the index first
    LOGE("process 1");
    io.loadU32(); // major version, already loaded
    io.loadU32(); // minor version, already loaded
    LOGE("process 2");

    io.loadU32();  // flags
    io.loadOffset(); // filesize, already loaded.
    LOGE("process 4");
    uint64_t mIndexOffset = io.loadOffset();
    uint64_t mStringOffset = io.loadOffset();

    LOGE("process mIndexOffset= 0x%016llx", mIndexOffset);
    LOGE("process mStringOffset= 0x%016llx", mStringOffset);

    IO index(mData + mIndexOffset, mUse64BitOffsets);
    IO stringTable(mData + mStringOffset, mUse64BitOffsets);

    uint32_t stringEntryCount = stringTable.loadU32();
    LOGE("stringEntryCount %i", stringEntryCount);
    mStrings.setCapacity(stringEntryCount);
    mStringIndexValues.setCapacity(stringEntryCount);
    if (stringEntryCount) {
        uint32_t stringType = stringTable.loadU32();
        LOGE("stringType %i", stringType);
        rsAssert(stringType==0);
        for (uint32_t ct = 0; ct < stringEntryCount; ct++) {
            uint64_t offset = stringTable.loadOffset();
            LOGE("string offset 0x%016llx", offset);
            IO tmp(mData + offset, mUse64BitOffsets);
            String8 s;
            tmp.loadString(&s);
            LOGE("string %s", s.string());
            mStrings.push(s);
        }
    }

    LOGE("strings done");
    uint32_t indexEntryCount = index.loadU32();
    LOGE("index count %i", indexEntryCount);
    mIndex.setCapacity(indexEntryCount);
    for (uint32_t ct = 0; ct < indexEntryCount; ct++) {
        A3DIndexEntry e;
        uint32_t stringIndex = index.loadU32();
        LOGE("index %i", ct);
        LOGE("  string index %i", stringIndex);
        e.mType = (A3DChunkType)index.loadU32();
        LOGE("  type %i", e.mType);
        e.mOffset = index.loadOffset();
        LOGE("  offset 0x%016llx", e.mOffset);

        if (stringIndex && (stringIndex < mStrings.size())) {
            e.mID = mStrings[stringIndex];
            mStringIndexValues.editItemAt(stringIndex) = ct;
            LOGE("  id %s", e.mID.string());
        }

        mIndex.push(e);
    }
    LOGE("index done");

    // At this point the index should be fully populated.
    // We can now walk though it and load all the objects.
    for (uint32_t ct = 0; ct < indexEntryCount; ct++) {
        LOGE("processing index entry %i", ct);
        processIndex(rsc, &mIndex.editItemAt(ct));
    }

    return ret;
}


FileA3D::IO::IO(const uint8_t *buf, bool use64)
{
    mData = buf;
    mPos = 0;
    mUse64 = use64;
}

uint64_t FileA3D::IO::loadOffset()
{
    uint64_t tmp;
    if (mUse64) {
        mPos = (mPos + 7) & (~7);
        tmp = reinterpret_cast<const uint64_t *>(&mData[mPos])[0];
        mPos += sizeof(uint64_t);
        return tmp;
    }
    return loadU32();
}

void FileA3D::IO::loadString(String8 *s)
{
    LOGE("loadString");
    uint32_t len = loadU32();
    LOGE("loadString len %i", len);
    s->setTo((const char *)&mData[mPos], len);
    mPos += len;
}


void FileA3D::processChunk_Mesh(Context *rsc, IO *io, A3DIndexEntry *ie)
{
    Mesh * m = new Mesh;

    m->mPrimitivesCount = io->loadU32();
    m->mPrimitives = new Mesh::Primitive_t *[m->mPrimitivesCount];

    for (uint32_t ct = 0; ct < m->mPrimitivesCount; ct++) {
        uint32_t index = io->loadU32();

        m->mPrimitives[ct] = (Mesh::Primitive_t *)mIndex[index].mRsObj;
    }
    ie->mRsObj = m;
}

void FileA3D::processChunk_Primitive(Context *rsc, IO *io, A3DIndexEntry *ie)
{
    Mesh::Primitive_t * p = new Mesh::Primitive_t;

    p->mIndexCount = io->loadU32();
    uint32_t vertIdx = io->loadU32();
    p->mRestartCounts = io->loadU16();
    uint32_t bits = io->loadU8();
    p->mType = (RsPrimitive)io->loadU8();

    LOGE("processChunk_Primitive count %i, bits %i", p->mIndexCount, bits);

    p->mVerticies = (Mesh::Verticies_t *)mIndex[vertIdx].mRsObj;

    p->mIndicies = new uint16_t[p->mIndexCount];
    for (uint32_t ct = 0; ct < p->mIndexCount; ct++) {
        switch(bits) {
        case 8:
            p->mIndicies[ct] = io->loadU8();
            break;
        case 16:
            p->mIndicies[ct] = io->loadU16();
            break;
        case 32:
            p->mIndicies[ct] = io->loadU32();
            break;
        }
        LOGE("  idx %i", p->mIndicies[ct]);
    }

    if (p->mRestartCounts) {
        p->mRestarts = new uint16_t[p->mRestartCounts];
        for (uint32_t ct = 0; ct < p->mRestartCounts; ct++) {
            switch(bits) {
            case 8:
                p->mRestarts[ct] = io->loadU8();
                break;
            case 16:
                p->mRestarts[ct] = io->loadU16();
                break;
            case 32:
                p->mRestarts[ct] = io->loadU32();
                break;
            }
            LOGE("  idx %i", p->mRestarts[ct]);
        }
    } else {
        p->mRestarts = NULL;
    }

    ie->mRsObj = p;
}

void FileA3D::processChunk_Verticies(Context *rsc, IO *io, A3DIndexEntry *ie)
{
    Mesh::Verticies_t *cv = new Mesh::Verticies_t;
    cv->mAllocationCount = io->loadU32();
    cv->mAllocations = new Allocation *[cv->mAllocationCount];
    LOGE("processChunk_Verticies count %i", cv->mAllocationCount);
    for (uint32_t ct = 0; ct < cv->mAllocationCount; ct++) {
        uint32_t i = io->loadU32();
        cv->mAllocations[ct] = (Allocation *)mIndex[i].mRsObj;
        LOGE("  idx %i", i);
    }
    ie->mRsObj = cv;
}

void FileA3D::processChunk_Element(Context *rsc, IO *io, A3DIndexEntry *ie)
{
    rsi_ElementBegin(rsc);

    uint32_t count = io->loadU32();
    LOGE("processChunk_Element count %i", count);
    while (count--) {
        RsDataKind dk = (RsDataKind)io->loadU8();
        RsDataType dt = (RsDataType)io->loadU8();
        uint32_t bits = io->loadU8();
        bool isNorm = io->loadU8() != 0;
        LOGE("  %i %i %i %i", dk, dt, bits, isNorm);
        rsi_ElementAdd(rsc, dk, dt, isNorm, bits);
    }
    LOGE("processChunk_Element create");
    ie->mRsObj = rsi_ElementCreate(rsc);
}

void FileA3D::processChunk_ElementSource(Context *rsc, IO *io, A3DIndexEntry *ie)
{
    uint32_t index = io->loadU32();
    uint32_t count = io->loadU32();

    LOGE("processChunk_ElementSource count %i, index %i", count, index);

    RsElement e = (RsElement)mIndex[index].mRsObj;

    RsAllocation a = rsi_AllocationCreateSized(rsc, e, count);
    Allocation * alloc = static_cast<Allocation *>(a);

    float * data = (float *)alloc->getPtr();
    while(count--) {
        *data = io->loadF();
        LOGE("  %f", *data);
        data++;
    }
    ie->mRsObj = alloc;
}

namespace android {
namespace renderscript {


RsFile rsi_FileOpen(Context *rsc, char const *path, unsigned int len)
{
    FileA3D *fa3d = new FileA3D;

    FILE *f = fopen("/sdcard/test.a3d", "rb");
    if (f) {
        fa3d->load(rsc, f);
        fclose(f);
        return fa3d;
    }
    delete fa3d;
    return NULL;
}


}
}
