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

#ifndef ANDROID_RS_BUILD_FOR_HOST
#include "rsContext.h"
#else
#include "rsContextHostStub.h"
#endif

#include "rsFileA3D.h"

#include "rsMesh.h"
#include "rsAnimation.h"

using namespace android;
using namespace android::renderscript;

FileA3D::FileA3D(Context *rsc) : ObjectBase(rsc)
{
    mAlloc = NULL;
    mData = NULL;
    mWriteStream = NULL;
    mReadStream = NULL;

    mMajorVersion = 0;
    mMinorVersion = 1;
    mDataSize = 0;
}

FileA3D::~FileA3D()
{
    for(size_t i = 0; i < mIndex.size(); i ++) {
        delete mIndex[i];
    }
    for(size_t i = 0; i < mWriteIndex.size(); i ++) {
        delete mWriteIndex[i];
    }
    if(mWriteStream) {
        delete mWriteStream;
    }
    if(mReadStream) {
        delete mWriteStream;
    }
    if(mAlloc) {
        free(mAlloc);
    }
}

void FileA3D::parseHeader(IStream *headerStream)
{
    mMajorVersion = headerStream->loadU32();
    mMinorVersion = headerStream->loadU32();
    uint32_t flags = headerStream->loadU32();
    mUse64BitOffsets = (flags & 1) != 0;

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

    uint32_t numIndexEntries = headerStream->loadU32();
    for(uint32_t i = 0; i < numIndexEntries; i ++) {
        A3DIndexEntry *entry = new A3DIndexEntry();
        headerStream->loadString(&entry->mObjectName);
        LOGE("Header data, entry name = %s", entry->mObjectName.string());
        entry->mType = (RsA3DClassID)headerStream->loadU32();
        if(mUse64BitOffsets){
            entry->mOffset = headerStream->loadOffset();
            entry->mLength = headerStream->loadOffset();
        }
        else {
            entry->mOffset = headerStream->loadU32();
            entry->mLength = headerStream->loadU32();
        }
        entry->mRsObj = NULL;
        mIndex.push(entry);
    }
}

bool FileA3D::load(const void *data, size_t length)
{
    LOGE("Loading data. Size: %u", length);
    const uint8_t *localData = (const uint8_t *)data;

    size_t lengthRemaining = length;
    size_t magicStrLen = 12;
    if ((length < magicStrLen) ||
        memcmp(data, "Android3D_ff", magicStrLen)) {
        return false;
    }

    localData += magicStrLen;
    lengthRemaining -= magicStrLen;

    // Next we get our header size
    uint64_t headerSize = 0;
    if(lengthRemaining < sizeof(headerSize)) {
        return false;
    }

    memcpy(&headerSize, localData, sizeof(headerSize));
    localData += sizeof(headerSize);
    lengthRemaining -= sizeof(headerSize);

    LOGE("Loading data, headerSize = %lli", headerSize);

    if(lengthRemaining < headerSize) {
        return false;
    }

    uint8_t *headerData = (uint8_t *)malloc(headerSize);
    if(!headerData) {
        return false;
    }

    memcpy(headerData, localData, headerSize);

    // Now open the stream to parse the header
    IStream headerStream(headerData, false);
    parseHeader(&headerStream);

    free(headerData);

    localData += headerSize;
    lengthRemaining -= headerSize;

    if(lengthRemaining < sizeof(mDataSize)) {
        return false;
    }

    // Read the size of the data
    memcpy(&mDataSize, localData, sizeof(mDataSize));
    localData += sizeof(mDataSize);
    lengthRemaining -= sizeof(mDataSize);

    LOGE("Loading data, mDataSize = %lli", mDataSize);

    if(lengthRemaining < mDataSize) {
        return false;
    }

    // We should know enough to read the file in at this point.
    mAlloc = malloc(mDataSize);
    if (!mAlloc) {
        return false;
    }
    mData = (uint8_t *)mAlloc;
    memcpy(mAlloc, localData, mDataSize);

    mReadStream = new IStream(mData, mUse64BitOffsets);

    return true;
}

bool FileA3D::load(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;
    }

    // Next thing is the size of the header
    uint64_t headerSize = 0;
    len = fread(&headerSize, 1, sizeof(headerSize), f);
    if (len != sizeof(headerSize) || headerSize == 0) {
        return false;
    }

    uint8_t *headerData = (uint8_t *)malloc(headerSize);
    if(!headerData) {
        return false;
    }

    len = fread(headerData, 1, headerSize, f);
    if (len != headerSize) {
        return false;
    }

    // Now open the stream to parse the header
    IStream headerStream(headerData, false);
    parseHeader(&headerStream);

    free(headerData);

    // Next thing is the size of the header
    len = fread(&mDataSize, 1, sizeof(mDataSize), f);
    if (len != sizeof(mDataSize) || mDataSize == 0) {
        return false;
    }

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

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

    mReadStream = new IStream(mData, mUse64BitOffsets);

    LOGE("Header is read an stream initialized");
    return true;
}

size_t FileA3D::getNumIndexEntries() const {
    return mIndex.size();
}

const FileA3D::A3DIndexEntry *FileA3D::getIndexEntry(size_t index) const {
    if(index < mIndex.size()) {
        return mIndex[index];
    }
    return NULL;
}

ObjectBase *FileA3D::initializeFromEntry(size_t index) {
    if(index >= mIndex.size()) {
        return NULL;
    }

    FileA3D::A3DIndexEntry *entry = mIndex[index];
    if(!entry) {
        return NULL;
    }

    if(entry->mRsObj) {
        entry->mRsObj->incUserRef();
        return entry->mRsObj;
    }

    // Seek to the beginning of object
    mReadStream->reset(entry->mOffset);
    switch (entry->mType) {
        case RS_A3D_CLASS_ID_UNKNOWN:
            return NULL;
        case RS_A3D_CLASS_ID_MESH:
            entry->mRsObj = Mesh::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_SIMPLE_MESH:
            entry->mRsObj = SimpleMesh::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_TYPE:
            entry->mRsObj = Type::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_ELEMENT:
            entry->mRsObj = Element::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_ALLOCATION:
            entry->mRsObj = Allocation::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_PROGRAM_VERTEX:
            entry->mRsObj = ProgramVertex::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_PROGRAM_RASTER:
            entry->mRsObj = ProgramRaster::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_PROGRAM_FRAGMENT:
            entry->mRsObj = ProgramFragment::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_PROGRAM_STORE:
            entry->mRsObj = ProgramStore::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_SAMPLER:
            entry->mRsObj = Sampler::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_ANIMATION:
            entry->mRsObj = Animation::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_LIGHT:
            entry->mRsObj = Light::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_ADAPTER_1D:
            entry->mRsObj = Adapter1D::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_ADAPTER_2D:
            entry->mRsObj = Adapter2D::createFromStream(mRSC, mReadStream);
            break;
        case RS_A3D_CLASS_ID_SCRIPT_C:
            return NULL;
    }
    if(entry->mRsObj) {
        entry->mRsObj->incUserRef();
    }
    return entry->mRsObj;
}

bool FileA3D::writeFile(const char *filename)
{
    if(!mWriteStream) {
        LOGE("No objects to write\n");
        return false;
    }
    if(mWriteStream->getPos() == 0) {
        LOGE("No objects to write\n");
        return false;
    }

    FILE *writeHandle = fopen(filename, "wb");
    if(!writeHandle) {
        LOGE("Couldn't open the file for writing\n");
        return false;
    }

    // Open a new stream to make writing the header easier
    OStream headerStream(5*1024, false);
    headerStream.addU32(mMajorVersion);
    headerStream.addU32(mMinorVersion);
    uint32_t is64Bit = 0;
    headerStream.addU32(is64Bit);

    uint32_t writeIndexSize = mWriteIndex.size();
    headerStream.addU32(writeIndexSize);
    for(uint32_t i = 0; i < writeIndexSize; i ++) {
        headerStream.addString(&mWriteIndex[i]->mObjectName);
        headerStream.addU32((uint32_t)mWriteIndex[i]->mType);
        if(mUse64BitOffsets){
            headerStream.addOffset(mWriteIndex[i]->mOffset);
            headerStream.addOffset(mWriteIndex[i]->mLength);
        }
        else {
            uint32_t offset = (uint32_t)mWriteIndex[i]->mOffset;
            headerStream.addU32(offset);
            offset = (uint32_t)mWriteIndex[i]->mLength;
            headerStream.addU32(offset);
        }
    }

    // Write our magic string so we know we are reading the right file
    String8 magicString(A3D_MAGIC_KEY);
    fwrite(magicString.string(), sizeof(char), magicString.size(), writeHandle);

    // Store the size of the header to make it easier to parse when we read it
    uint64_t headerSize = headerStream.getPos();
    fwrite(&headerSize, sizeof(headerSize), 1, writeHandle);

    // Now write our header
    fwrite(headerStream.getPtr(), sizeof(uint8_t), headerStream.getPos(), writeHandle);

    // Now write the size of the data part of the file for easier parsing later
    uint64_t fileDataSize = mWriteStream->getPos();
    fwrite(&fileDataSize, sizeof(fileDataSize), 1, writeHandle);

    fwrite(mWriteStream->getPtr(), sizeof(uint8_t), mWriteStream->getPos(), writeHandle);

    int status = fclose(writeHandle);

    if(status != 0) {
        LOGE("Couldn't close file\n");
        return false;
    }

    return true;
}

void FileA3D::appendToFile(ObjectBase *obj) {
    if(!obj) {
        return;
    }
    if(!mWriteStream) {
        const uint64_t initialStreamSize = 256*1024;
        mWriteStream = new OStream(initialStreamSize, false);
    }
    A3DIndexEntry *indexEntry = new A3DIndexEntry();
    indexEntry->mObjectName.setTo(obj->getName());
    indexEntry->mType = obj->getClassId();
    indexEntry->mOffset = mWriteStream->getPos();
    indexEntry->mRsObj = obj;
    mWriteIndex.push(indexEntry);
    obj->serialize(mWriteStream);
    indexEntry->mLength = mWriteStream->getPos() - indexEntry->mOffset;
    mWriteStream->align(4);
}

namespace android {
namespace renderscript {

void rsi_FileA3DGetNumIndexEntries(Context *rsc, int32_t *numEntries, RsFile file)
{
    FileA3D *fa3d = static_cast<FileA3D *>(file);

    if(fa3d) {
        *numEntries = fa3d->getNumIndexEntries();
    }
    else {
        *numEntries = 0;
    }
}

void rsi_FileA3DGetIndexEntries(Context *rsc, RsFileIndexEntry *fileEntries, uint32_t numEntries, RsFile file)
{
    FileA3D *fa3d = static_cast<FileA3D *>(file);

    if(!fa3d) {
        LOGE("Can't load index entries. No valid file");
        return;
    }

    uint32_t numFileEntries = fa3d->getNumIndexEntries();
    if(numFileEntries != numEntries || numEntries == 0 || fileEntries == NULL) {
        LOGE("Can't load index entries. Invalid number requested");
        return;
    }

    for(uint32_t i = 0; i < numFileEntries; i ++) {
        const FileA3D::A3DIndexEntry *entry = fa3d->getIndexEntry(i);
        fileEntries[i].classID = entry->getType();
        fileEntries[i].objectName = entry->getObjectName().string();
    }

}

RsObjectBase rsi_FileA3DGetEntryByIndex(Context *rsc, uint32_t index, RsFile file)
{
    FileA3D *fa3d = static_cast<FileA3D *>(file);
    if(!fa3d) {
        LOGE("Can't load entry. No valid file");
        return NULL;
    }

    ObjectBase *obj = fa3d->initializeFromEntry(index);
    LOGE("Returning object with name %s", obj->getName());

    return obj;
}

RsFile rsi_FileA3DCreateFromAssetStream(Context *rsc, const void *data, uint32_t len)
{
    if (data == NULL) {
        LOGE("File load failed. Asset stream is NULL");
        return NULL;
    }

    FileA3D *fa3d = new FileA3D(rsc);

    fa3d->load(data, len);
    fa3d->incUserRef();

    return fa3d;
}


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

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


}
}
