#include "xmodel.h"

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

}

void XModel::ParseData(QDataStream *aStream) {
    qint32 namePtr, boneNamesPtr;

    *aStream
        >> namePtr;

    mName = Load_XString(aStream);
    if (boneNamesPtr == -1)
    {
        Load_ScriptStringArray(1, numBones);
    }
    if ( parentList )
    {
        if ( parentList == (unsigned __int8 *)-1 )
        {
            v5 = g_streamPos;
            v6 = v1->numBones - v1->numRootBones;
            varbyte = g_streamPos;
            v1->parentList = g_streamPos;
            Load_Stream(1, v5, v6);
            v1 = varXModel;
        }
        else
        {
            v1->parentList = &(*(unsigned __int8 **)((char *)&g_streamBlocks->data
                                                      + (((unsigned int)(v1->parentList - 1) >> 26) & 0x38)))[(int)(v1->parentList - 1) & 0x1FFFFFFF];
        }
    }
    quats = v1->quats;
    if ( quats )
    {
        if ( quats == (__int16 *)-1 )
        {
            v8 = (unsigned __int8 *)((unsigned int)(g_streamPos + 1) & 0xFFFFFFFE);
            v9 = 8 * (v1->numBones - v1->numRootBones);
            g_streamPos = v8;
            v1->quats = (__int16 *)v8;
            varshort = (__int16 *)v8;
            Load_Stream(1, v8, v9);
            v1 = varXModel;
        }
        else
        {
            v1->quats = (__int16 *)&(*(unsigned __int8 **)((char *)&g_streamBlocks->data
                                                             + ((((unsigned int)v1->quats - 1) >> 26) & 0x38)))[((int)v1->quats - 1) & 0x1FFFFFFF];
        }
    }
    trans = v1->trans;
    if ( trans )
    {
        if ( trans == (float *)-1 )
        {
            v11 = (unsigned __int8 *)((unsigned int)(g_streamPos + 3) & 0xFFFFFFFC);
            v12 = 16 * (v1->numBones - v1->numRootBones);
            g_streamPos = v11;
            v1->trans = (float *)v11;
            varfloat = (float *)v11;
            Load_Stream(1, v11, v12);
            v1 = varXModel;
        }
        else
        {
            v1->trans = (float *)&(*(unsigned __int8 **)((char *)&g_streamBlocks->data
                                                           + ((((unsigned int)v1->trans - 1) >> 26) & 0x38)))[((int)v1->trans - 1) & 0x1FFFFFFF];
        }
    }
    partClassification = v1->partClassification;
    if ( partClassification )
    {
        if ( partClassification == (unsigned __int8 *)-1 )
        {
            v14 = g_streamPos;
            v15 = v1->numBones;
            varbyte = g_streamPos;
            v1->partClassification = g_streamPos;
            Load_Stream(1, v14, v15);
            v1 = varXModel;
        }
        else
        {
            v1->partClassification = &(*(unsigned __int8 **)((char *)&g_streamBlocks->data
                                                              + (((unsigned int)(v1->partClassification - 1) >> 26) & 0x38)))[(int)(v1->partClassification - 1) & 0x1FFFFFFF];
        }
    }
    baseMat = v1->baseMat;
    if ( baseMat )
    {
        if ( baseMat == (DObjAnimMat *)-1 )
        {
            v17 = __ROL4__(v1->numBones, 5);
            v18 = (unsigned __int8 *)((unsigned int)(g_streamPos + 3) & 0xFFFFFFFC);
            g_streamPos = v18;
            varDObjAnimMat = (DObjAnimMat *)v18;
            v1->baseMat = (DObjAnimMat *)v18;
            Load_Stream(1, v18, v17);
            v1 = varXModel;
        }
        else
        {
            v1->baseMat = (DObjAnimMat *)&(*(unsigned __int8 **)((char *)&g_streamBlocks->data
                                                                   + ((((unsigned int)&v1->baseMat[-1].transWeight + 3) >> 26) & 0x38)))[((int)&v1->baseMat[-1].transWeight + 3) & 0x1FFFFFFF];
        }
    }
    if ( v1->surfs )
    {
        numsurfs = v1->numsurfs;
        g_streamPos = (unsigned __int8 *)((unsigned int)(g_streamPos + 3) & 0xFFFFFFFC);
        varXSurface = (XSurface *)g_streamPos;
        v1->surfs = (XSurface *)g_streamPos;
        Load_XSurfaceArray(1, numsurfs);
        v1 = varXModel;
    }
    if ( v1->materialHandles )
    {
        v20 = v1->numsurfs;
        g_streamPos = (unsigned __int8 *)((unsigned int)(g_streamPos + 3) & 0xFFFFFFFC);
        varMaterialHandle = (Material **)g_streamPos;
        v1->materialHandles = (Material **)g_streamPos;
        Load_MaterialHandleArray(1, v20);
        v1 = varXModel;
    }
    if ( v1->collSurfs )
    {
        numCollSurfs = v1->numCollSurfs;
        g_streamPos = (unsigned __int8 *)((unsigned int)(g_streamPos + 3) & 0xFFFFFFFC);
        varXModelCollSurf = (XModelCollSurf_s *)g_streamPos;
        v1->collSurfs = (XModelCollSurf_s *)g_streamPos;
        Load_XModelCollSurfArray(1, numCollSurfs);
        v1 = varXModel;
    }
    if ( v1->boneInfo )
    {
        v22 = v1->numBones;
        v23 = (unsigned __int8 *)((unsigned int)(g_streamPos + 3) & 0xFFFFFFFC);
        v1->boneInfo = (XBoneInfo *)v23;
        g_streamPos = v23;
        varXBoneInfo = (XBoneInfo *)v23;
        Load_Stream(1, v23, 8 * (v22 + __ROL4__(v22, 2)));
        v1 = varXModel;
    }
    varXModelStreamInfo = &v1->streamInfo;
    Load_Stream(0, &v1->streamInfo, 4u);
    if ( varXModelStreamInfo->highMipBounds )
    {
        v24 = (XModelHighMipBounds *)((unsigned int)(g_streamPos + 3) & 0xFFFFFFFC);
        varXModelStreamInfo->highMipBounds = v24;
        varXModelHighMipBounds = v24;
        g_streamPos = (unsigned __int8 *)v24;
        Load_Stream(1, v24, 8 * (varXModel->lodInfo[0].numsurfs + __ROL4__(varXModel->lodInfo[0].numsurfs, 1)));
    }
    varPhysPresetPtr = &varXModel->physPreset;
    Load_PhysPresetPtr(0);
    physGeoms = varXModel->physGeoms;
    if ( physGeoms )
    {
        if ( physGeoms == (PhysGeomList *)-1 )
        {
            g_streamPos = (unsigned __int8 *)((unsigned int)(g_streamPos + 3) & 0xFFFFFFFC);
            varPhysGeomList = (PhysGeomList *)g_streamPos;
            varXModel->physGeoms = (PhysGeomList *)g_streamPos;
            Load_PhysGeomList(1);
            DB_PopStreamPos();
            return;
        }
        varXModel->physGeoms = (PhysGeomList *)&(*(unsigned __int8 **)((char *)&g_streamBlocks->data
                                                                         + ((((unsigned int)&varXModel->physGeoms[-1].mass.productsOfInertia[2]
                                                                              + 3) >> 26) & 0x38)))[((int)&varXModel->physGeoms[-1].mass.productsOfInertia[2]
                                                                                       + 3) & 0x1FFFFFFF];
    }
    DB_PopStreamPos();
}
