#include "xclipmap.h"

XClipMap::XClipMap()
    : XAsset()
    , mName()
    , mIsInUse(false)
    , mPlaneCount(0)
    , mPlanes()
    , mNumStaticModels(0)
    , mStaticModelList()
    , mNumMaterials(0)
    , mMaterials()
    , mNumBrushSides(0)
    , mBrushsides()
    , mNumBrushEdges(0)
    , mBrushEdges()
    , mNumNodes(0)
    , mNodes()
    , mNumLeafs(0)
    , mLeafs()
    , mLeafBrushNodesCount(0)
    , mLeafBrushNodes()
    , mNumLeafBrushes(0)
    , mLeafBrushes()
    , mNumLeafSurfaces(0)
    , mLeafSurfaces()
    , mVertCount(0)
    , mVerts()
    , mTriCount(0)
    , mTriIndices()
    , mTriEdgeIsWalkable()
    , mBorderCount(0)
    , mBorders()
    , mPartitionCount(0)
    , mPartitions()
    , mAabbTreeCount(0)
    , mAabbTrees()
    , mNumSubModels(0)
    , mCModels()
    , mNumBrushes(0)
    , mBrushes()
    , mNumClusters(0)
    , mClusterBytes(0)
    , mVisibility()
    , mVised(0)
    , mMapEnts()
    , mBoxBrush()
    , mBoxModel()
    , mDynEntCounts(0)
    , mDynEntDefList(2)
    , mDynEntPoseList(2)
    , mDynEntClientList(2)
    , mDynEntCollList(2)
    , mChecksum(0)
{
    SetType(ASSET_TYPE_CLIPMAP);
    SetName("ClipMap");
}

XClipMap::~XClipMap()
{

}

void XClipMap::ParseData(QDataStream *aStream)
{
    if (GetPtr() == -1)
    {
        mName.ParsePtr(aStream, false);

        qint32 planePtr, staticModelPtr, materialsPtr, brushSidesPtr,
            brushEdgesPtr, nodesPtr, leafsPtr, leafsBrushNodesPtr,
            leafBrushesPtr, leafSurfacesPtr, vertPtr,
            triIndicesPtr, triEdgeWalkablePtr, bordersPtr, partitionsPtr, aabbTreesPtr,
            cModelsPtr;
        *aStream
            >> mIsInUse
            >> mPlaneCount
            >> planePtr
            >> mNumStaticModels
            >> staticModelPtr
            >> mNumMaterials
            >> materialsPtr
            >> mNumBrushSides
            >> brushSidesPtr
            >> mNumBrushEdges
            >> brushEdgesPtr
            >> mNumNodes
            >> nodesPtr
            >> mNumLeafs
            >> leafsPtr
            >> mLeafBrushNodesCount
            >> leafsBrushNodesPtr
            >> mNumLeafBrushes
            >> leafBrushesPtr
            >> mNumLeafSurfaces
            >> leafSurfacesPtr
            >> mVertCount
            >> vertPtr
            >> mTriCount
            >> triIndicesPtr
            >> triEdgeWalkablePtr
            >> mBorderCount
            >> bordersPtr
            >> mPartitionCount
            >> partitionsPtr
            >> mAabbTreeCount
            >> aabbTreesPtr
            >> mNumSubModels
            >> cModelsPtr
            >> mNumBrushes;

        aStream->skipRawData(2);

        qint32 brushesPtr, visibilityPtr, mapEntsPtr;
        *aStream
            >> brushesPtr
            >> mNumClusters
            >> mClusterBytes
            >> visibilityPtr
            >> mVised
            >> mapEntsPtr;

        mMapEnts.ParsePtr(aStream, false);
        mBoxBrush.ParsePtr(aStream, false);

        mBoxModel.ParseData(aStream);

        quint16 dynEntCount;
        *aStream >> dynEntCount;
        mDynEntCounts.append(dynEntCount);
        *aStream >> dynEntCount;
        mDynEntCounts.append(dynEntCount);

        mDynEntDefList[0].ParsePtr(aStream, false);
        mDynEntDefList[0].ParsePtr(aStream, false);

        mDynEntPoseList[0].ParsePtr(aStream, false);
        mDynEntPoseList[0].ParsePtr(aStream, false);

        mDynEntClientList[0].ParsePtr(aStream, false);
        mDynEntClientList[0].ParsePtr(aStream, false);

        mDynEntCollList[0].ParsePtr(aStream, false);
        mDynEntCollList[0].ParsePtr(aStream, false);

        *aStream >> mChecksum;

        if (planePtr)
        {
            for (int i = 0; i < mPlaneCount; i++)
            {
                XCPlane newCPlane;
                newCPlane.ParseData(aStream);
                mPlanes.append(newCPlane);
            }
        }

        if (staticModelPtr)
        {
            for (int i = 0; i < mNumStaticModels; i++)
            {
                XCStaticModel newModel;
                newModel.ParseData(aStream);
                mStaticModelList.append(newModel);
            }
        }

        if (materialsPtr)
        {
            for (int i = 0; i < mNumMaterials; i++)
            {
                XDMaterial newDMaterial;
                newDMaterial.ParseData(aStream);
                mMaterials.append(newDMaterial);
            }
        }

        if (brushSidesPtr)
        {
            for (int i = 0; i < mNumBrushSides; i++)
            {
                XCBrushSide newBrushSide;
                newBrushSide.ParseData(aStream);
                mBrushsides.append(newBrushSide);
            }
        }

        if (brushEdgesPtr)
        {
            for (int i = 0; i < mNumBrushEdges; i++)
            {
                quint8 newBrushEdge;
                *aStream >> newBrushEdge;
                mBrushEdges.append(newBrushEdge);
            }
        }

        if (nodesPtr)
        {
            for (int i = 0; i < mNumNodes; i++)
            {
                XCNode newNode;
                newNode.ParseData(aStream);
                mNodes.append(newNode);
            }
        }

        if (leafsPtr)
        {
            for (int i = 0; i < mNumLeafs; i++)
            {
                XCLeaf newLeaf;
                newLeaf.ParseData(aStream);
                mLeafs.append(newLeaf);
            }
        }

        if (leafBrushesPtr)
        {
            for (int i = 0; i < mNumLeafBrushes; i++)
            {
                quint32 newBrush;
                *aStream >> newBrush;
                mLeafBrushes.append(newBrush);
            }
        }

        if (leafsBrushNodesPtr)
        {
            for (int i = 0; i < mNumLeafBrushes; i++)
            {
                XCLeafBrushNode newBrushNode;
                newBrushNode.ParseData(aStream);
                mLeafBrushNodes.append(newBrushNode);
            }
        }

        if (leafSurfacesPtr)
        {
            for (int i = 0; i < mNumLeafBrushes; i++)
            {
                quint32 newBrush;
                *aStream >> newBrush;
                mLeafSurfaces.append(newBrush);
            }
        }

        if (vertPtr)
        {
            for (int i = 0; i < mVertCount; i++)
            {
                QVector3D newVert;
                *aStream
                    >> newVert[0]
                    >> newVert[1]
                    >> newVert[2];
                mVerts.append(newVert);
            }
        }

        if (triIndicesPtr)
        {
            for (int i = 0; i < mTriCount; i++)
            {
                quint32 newTri;
                *aStream >> newTri;
                mTriIndices.append(newTri);
            }
        }

        if (triEdgeWalkablePtr)
        {
            aStream->readRawData(mTriEdgeIsWalkable.data(), ((3 * mTriCount + 31) >> 3) & 0xFFFFFFFC);
        }

        if (bordersPtr)
        {
            for (int i = 0; i < mBorderCount; i++)
            {
                XCollisionBorder newBorder;
                newBorder.ParseData(aStream);
                mBorders.append(newBorder);
            }
        }

        if (partitionsPtr)
        {
            for (int i = 0; i < mPartitionCount; i++)
            {
                XCollisionPartition newPartition;
                newPartition.ParseData(aStream);
                mPartitions.append(newPartition);
            }
        }

        if (aabbTreesPtr)
        {
            for (int i = 0; i < mAabbTreeCount; i++)
            {
                XCollisionAabbTree newTree;
                newTree.ParseData(aStream);
                mAabbTrees.append(newTree);
            }
        }

        if (cModelsPtr)
        {
            for (int i = 0; i < mNumSubModels; i++)
            {
                XCModel newCModel;
                newCModel.ParseData(aStream);
                mCModels.append(newCModel);
            }
        }

        if (brushesPtr)
        {
            for (int i = 0; i < mNumBrushes; i++)
            {
                XCBrush newCBrush;
                newCBrush.ParseData(aStream);
                mBrushes.append(newCBrush);
            }
        }

        if (visibilityPtr)
        {
            aStream->readRawData(mVisibility.data(), mClusterBytes * mNumClusters);
        }

        if (mapEntsPtr)
        {
            mMapEnts.ParseData(aStream);
        }

        mBoxBrush.ParseData(aStream);

        mDynEntDefList[0].ParseData(aStream);
        mDynEntDefList[0].ParseData(aStream);

        mDynEntPoseList[0].ParseData(aStream);
        mDynEntPoseList[0].ParseData(aStream);

        mDynEntClientList[0].ParseData(aStream);
        mDynEntClientList[0].ParseData(aStream);

        mDynEntCollList[0].ParseData(aStream);
        mDynEntCollList[0].ParseData(aStream);
    }
}

void XClipMap::Clear()
{

}
