/*
 * 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_STRUCTURED_ELEMENT_H
#define ANDROID_STRUCTURED_ELEMENT_H

#include "rsComponent.h"
#include "rsUtils.h"
#include "rsObjectBase.h"

// ---------------------------------------------------------------------------
namespace android {
namespace renderscript {


// An element is a group of Components that occupies one cell in a structure.
class Element : public ObjectBase
{
public:
    ~Element();

    uint32_t getGLType() const;
    uint32_t getGLFormat() const;

    size_t getSizeBits() const;
    size_t getSizeBytes() const {
        return (getSizeBits() + 7) >> 3;
    }

    size_t getFieldOffsetBits(uint32_t componentNumber) const {
        return mFields[componentNumber].offsetBits;
    }
    size_t getFieldOffsetBytes(uint32_t componentNumber) const {
        return mFields[componentNumber].offsetBits >> 3;
    }

    uint32_t getFieldCount() const {return mFieldCount;}
    const Element * getField(uint32_t idx) const {return mFields[idx].e.get();}
    const char * getFieldName(uint32_t idx) const {return mFields[idx].name.string();}

    const Component & getComponent() const {return mComponent;}
    RsDataType getType() const {return mComponent.getType();}
    RsDataKind getKind() const {return mComponent.getKind();}
    uint32_t getBits() const {return mBits;}

    String8 getGLSLType(uint32_t indent=0) const;

    void dumpLOGV(const char *prefix) const;
    virtual void serialize(OStream *stream) const;
    virtual RsA3DClassID getClassId() const { return RS_A3D_CLASS_ID_ELEMENT; }
    static Element *createFromStream(Context *rsc, IStream *stream);

    static const Element * create(Context *rsc, RsDataType dt, RsDataKind dk,
                            bool isNorm, uint32_t vecSize);
    static const Element * create(Context *rsc, size_t count, const Element **,
                            const char **, const size_t * lengths, const uint32_t *asin);

    void incRefs(const void *) const;
    void decRefs(const void *) const;
    bool getHasReferences() const {return mHasReference;}

protected:
    // deallocate any components that are part of this element.
    void clear();

    typedef struct {
        String8 name;
        ObjectBaseRef<const Element> e;
        uint32_t offsetBits;
        uint32_t arraySize;
    } ElementField_t;
    ElementField_t *mFields;
    size_t mFieldCount;
    bool mHasReference;


    Element(Context *);

    Component mComponent;
    uint32_t mBits;
};


class ElementState {
public:
    ElementState();
    ~ElementState();

    void elementBuilderBegin();
    void elementBuilderAdd(const Element *e, const char *nameStr, uint32_t arraySize);
    const Element *elementBuilderCreate(Context *rsc);

    // Cache of all existing elements.
    Vector<Element *> mElements;
private:
    Vector<const Element *> mBuilderElements;
    Vector<const char*> mBuilderNameStrings;
    Vector<size_t> mBuilderNameLengths;
    Vector<uint32_t> mBuilderArrays;
};


}
}
#endif //ANDROID_STRUCTURED_ELEMENT_H
