#include "xfxelemdef.h"

XFxElemDef::XFxElemDef()
    : XAsset()
    , mFlags(0)
    , mSpawn()
    , mSpawnRange()
    , mFadeInRange()
    , mFadeOutRange()
    , mSpawnFrustumCullRadius(0)
    , mSpawnDelayMsec()
    , mLifeSpanMsec()
    , mSpawnOrigin(3)
    , mSpawnOffsetRadius()
    , mSpawnOffsetHeight()
    , mSpawnAngles(3)
    , mAngularVelocity(3)
    , mInitialRotation()
    , mGravity()
    , mReflectionFactor()
    , mAtlas()
    , mElemType(0)
    , mVisualCount(0)
    , mVelIntervalCount(0)
    , mVisStateIntervalCount(0)
    , mVelSamplesPtr(0)
    , mVelSamples()
    , mVisSamplesPtr(0)
    , mVisSamples()
    , mVisuals()
    , mCollMins()
    , mCollMaxs()
    , mEffectOnImpact()
    , mEffectOnDeath()
    , mEffectEmitted()
    , mEmitDist()
    , mEmitDistVariance()
    , mTrailDef()
    , mSortOrder(0)
    , mLightingFrac(0)
    , mUseItemClip(0)
{
    SetName("Element Definition");
}

XFxElemDef::~XFxElemDef()
{
    
}

void XFxElemDef::Clear()
{
    mFlags = 0;
    mSpawn.Clear();
    mSpawnRange.Clear();
    mFadeInRange.Clear();
    mFadeOutRange.Clear();
    mSpawnFrustumCullRadius = 0;
    mSpawnDelayMsec.Clear();
    mLifeSpanMsec.Clear();
    mSpawnOrigin.clear();
    mSpawnOffsetRadius.Clear();
    mSpawnOffsetHeight.Clear();
    mSpawnAngles.clear();
    mAngularVelocity.clear();
    mInitialRotation.Clear();
    mGravity.Clear();
    mReflectionFactor.Clear();
    mAtlas.Clear();
    mElemType = 0;
    mVisualCount = 0;
    mVelIntervalCount = 0;
    mVisStateIntervalCount = 0;
    mVelSamplesPtr = 0;
    mVelSamples.clear();
    mVisSamplesPtr = 0;
    mVisSamples.clear();
    mVisuals.Clear();
    mCollMins = QVector3D();
    mCollMaxs = QVector3D();
    mEffectOnImpact.Clear();
    mEffectOnDeath.Clear();
    mEffectEmitted.Clear();
    mEmitDist.Clear();
    mEmitDistVariance.Clear();
    mTrailDef.Clear();
    mSortOrder = 0;
    mLightingFrac = 0;
    mUseItemClip = 0;
}

void XFxElemDef::ParseData(XDataStream *aStream)
{
    mFlags = aStream->ParseInt32(QString("%1 flags").arg(GetName()));

    mSpawn.ParseData(aStream);
    mSpawnRange.ParseData(aStream);
    mFadeInRange.ParseData(aStream);
    mFadeOutRange.ParseData(aStream);

    mSpawnFrustumCullRadius = aStream->ParseSingle(QString("%1 spawn frustum cull radius").arg(GetName()));

    mSpawnDelayMsec.ParseData(aStream);
    mLifeSpanMsec.ParseData(aStream);

    for (int i = 0; i < 3; i++)
        mSpawnOrigin[i].ParseData(aStream);

    mSpawnOffsetRadius.ParseData(aStream);
    mSpawnOffsetHeight.ParseData(aStream);

    for (int i = 0; i < 3; i++)
        mSpawnAngles[i].ParseData(aStream);

    for (int i = 0; i < 3; i++)
        mAngularVelocity[i].ParseData(aStream);

    mInitialRotation.ParseData(aStream);
    mGravity.ParseData(aStream);
    mReflectionFactor.ParseData(aStream);
    mAtlas.ParseData(aStream);

    qint32 velSamplesPtr, visSamplesPtr;
    mElemType = aStream->ParseUInt8(QString("%1 elem type").arg(GetName()));
    mVisualCount = aStream->ParseUInt8(QString("%1 visual count").arg(GetName()));
    mVelIntervalCount = aStream->ParseUInt8(QString("%1 vel interval count").arg(GetName()));
    mVisStateIntervalCount = aStream->ParseUInt8(QString("%1 vis state interval count").arg(GetName()));
    velSamplesPtr = aStream->ParseInt32(QString("%1 vel samples ptr").arg(GetName()));
    visSamplesPtr = aStream->ParseInt32(QString("%1 vis samples ptr").arg(GetName()));

    mVisuals.ParseData(aStream);

    mCollMins.setX(aStream->ParseSingle(QString("%1 coll mins x").arg(GetName())));
    mCollMins.setY(aStream->ParseSingle(QString("%1 coll mins y").arg(GetName())));
    mCollMins.setZ(aStream->ParseSingle(QString("%1 coll mins z").arg(GetName())));
    mCollMaxs.setX(aStream->ParseSingle(QString("%1 coll maxs x").arg(GetName())));
    mCollMaxs.setY(aStream->ParseSingle(QString("%1 coll maxs y").arg(GetName())));
    mCollMaxs.setZ(aStream->ParseSingle(QString("%1 coll maxs z").arg(GetName())));

    mEffectOnImpact.ParseData(aStream);
    mEffectOnDeath.ParseData(aStream);
    mEffectEmitted.ParseData(aStream);
    mEmitDist.ParseData(aStream);
    mEmitDistVariance.ParseData(aStream);

    qint32 trailDefPtr;
    trailDefPtr = aStream->ParseInt32(QString("%1 trail def ptr").arg(GetName()));
    mSortOrder = aStream->ParseUInt8(QString("%1 sort order").arg(GetName()));
    mLightingFrac = aStream->ParseUInt8(QString("%1 lighting frac").arg(GetName()));
    mUseItemClip = aStream->ParseUInt8(QString("%1 use item clip").arg(GetName()));

    aStream->skipRawData(1);

    if (velSamplesPtr)
    {
        for (int i = 0; i < mVelIntervalCount + 1; i++)
        {
            XFxElemVelStateSample newVelSample;
            newVelSample.ParseData(aStream);
            mVelSamples.append(newVelSample);
        }
    }

    if (visSamplesPtr)
    {
        for (int i = 0; i < mVisStateIntervalCount + 1; i++)
        {
            XFxElemVisStateSample newVisSample;
            newVisSample.ParseData(aStream);
            mVisSamples.append(newVisSample);
        }
    }

    // TODO: Finish this ugh
}
