#include "xmodel.h"
#include "xstring.h"

XModel::XModel()
    : XAsset()
    , mName()
    , mNumBones(0)
    , mNumRootBones(0)
    , mNumSurfs(0)
    , mLodRampType(0)
    , mBoneNames()
    , mParentList()
    , mQuats()
    , mTrans(0)
    , mPartClassification()
    , mBaseMat()
    , mSurfs()
    , mMaterialHandles()
    , mLodInfo()
    , mCollSurfs()
    , mNumCollSurfs(0)
    , mContents(0)
    , mBoneInfo()
    , mRadius(0)
    , mMins()
    , mMaxs()
    , mNumLods(0)
    , mCollLod(0)
    , mStreamInfo()
    , mMemUsage(0)
    , mFlags(0)
    , mPhysPreset()
    , mPhysGeoms()
{
    SetType(ASSET_TYPE_XMODEL);
}

XModel::~XModel()
{

}

void XModel::ParseData(QDataStream *aStream) {

    mName.ParsePtr(aStream, false);

    *aStream
        >> mNumBones
        >> mNumRootBones
        >> mNumSurfs
        >> mLodRampType;

    qint32 boneNamesPtr, parentListPtr, quatsPtr, transPtr, partClassPtr;

    *aStream
        >> boneNamesPtr
        >> parentListPtr
        >> quatsPtr
        >> transPtr
        >> partClassPtr;

    mBaseMat.ParsePtr(aStream, false);

    qint32 surfsPtr, matHandlesPtr, lodInfoPtr, collSurfsPtr;

    *aStream
        >> surfsPtr
        >> matHandlesPtr
        >> lodInfoPtr
        >> collSurfsPtr
        >> mNumCollSurfs
        >> mContents;

    mBoneInfo.ParsePtr(aStream, false);

    *aStream
        >> mRadius
        >> mMins
        >> mMaxs
        >> mNumLods
        >> mCollLod;

    mStreamInfo.ParseData(aStream);

    *aStream
        >> mMemUsage
        >> mFlags;
    aStream->skipRawData(3);

    mPhysPreset.ParsePtr(aStream, false);
    mPhysGeoms.ParsePtr(aStream, false);

    mName.ParseData(aStream);

    if (boneNamesPtr == -1)
    {
        for (int i = 0; i < mNumBones; i++)
        {
            quint16 bone;
            *aStream >> bone;
            mBoneNames.append(bone);
        }
    }

    if (parentListPtr == -1)
    {
        for (int i = 0; i < mNumBones - mNumRootBones; i++)
        {
            quint8 parent;
            *aStream >> parent;
            mParentList.append(parent);
        }
    }

    if (quatsPtr == -1)
    {
        for (int i = 0; i < 8 * (mNumBones - mNumRootBones); i++)
        {
            quint8 quat;
            *aStream >> quat;
            mQuats.append(quat);
        }
    }

    if (transPtr == -1)
    {
        for (int i = 0; i < 16 * (mNumBones - mNumRootBones); i++)
        {
            quint8 trans;
            *aStream >> trans;
            mTrans.append(trans);
        }
    }

    if (partClassPtr == -1)
    {
        for (int i = 0; i < mNumBones; i++)
        {
            quint8 partClass;
            *aStream >> partClass;
            mPartClassification.append(partClass);
        }
    }

    mBaseMat.ParseData(aStream);

    if (surfsPtr == -1)
    {
        for (int i = 0; i < mNumSurfs; i++)
        {
            XSurface newSurf;
            newSurf.ParseData(aStream);
            mSurfs.append(newSurf);
        }
    }

    if (matHandlesPtr == -1)
    {
        for (int i = 0; i < mNumSurfs; i++)
        {
            XMaterial newMaterial;
            newMaterial.ParseData(aStream);
            mMaterialHandles.append(newMaterial);
        }
    }

    if (collSurfsPtr == -1)
    {
        for (int i = 0; i < mNumCollSurfs; i++)
        {
            XModelCollSurf newCollSurf;
            newCollSurf.ParseData(aStream);
            mCollSurfs.append(newCollSurf);
        }
    }

    mBoneInfo.ParseData(aStream);

    // TODO: Fill out rest of this
}

void XModel::Clear()
{

}
