#ifndef EFFECTDEF_H
#define EFFECTDEF_H

#include "material.h"
#include "model.h"

struct FxSpawnDefLooping
{
    int intervalMsec;
    int count;
};

struct FxIntRange
{
    int base;
    int amplitude;
};

struct FxSpawnDefOneShot
{
    FxIntRange count;
};

union FxSpawnDef
{
    FxSpawnDefLooping looping;
    FxSpawnDefOneShot oneShot;
};

struct FxFloatRange
{
    float base;
    float amplitude;
};

struct FxElemAtlas
{
    unsigned __int8 behavior;
    unsigned __int8 index;
    unsigned __int8 fps;
    unsigned __int8 loopCount;
    unsigned __int8 colIndexBits;
    unsigned __int8 rowIndexBits;
    __int16 entryCount;
};

struct FxElemVec3Range
{
    float base[3];
    float amplitude[3];
};

struct FxElemVelStateInFrame
{
    FxElemVec3Range velocity;
    FxElemVec3Range totalDelta;
};

struct FxElemVelStateSample
{
    FxElemVelStateInFrame local;
    FxElemVelStateInFrame world;
};

struct FxElemVisualState
{
    unsigned __int8 color[4];
    float rotationDelta;
    float rotationTotal;
    float size[2];
    float scale;
};

struct FxElemVisStateSample
{
    FxElemVisualState base;
    FxElemVisualState amplitude;
};

struct FxElemMarkVisuals
{
    qint32 materialPtrs[2];
    QVector<Material> materials;
};

struct EffectDef;
union EffectDefRef
{
    qint32 handlePtr;
    const EffectDef *handle;

    qint32 namePtr;
    const char *name;
};

union FxElemVisuals
{
    qint32 anonymousPtr;
    const void *anonymous;

    qint32 materialPtr;
    Material *material;

    qint32 modelPtr;
    Model *model;

    EffectDefRef effectDef;

    qint32 soundNamePtr;
    const char *soundName;
};

struct FxElemDefVisuals
{
    qint32 markArrayPtr;
    QVector<FxElemMarkVisuals> markArray;

    qint32 arrayPtr;
    QVector<FxElemVisuals> array;

    FxElemVisuals instance;
};

struct FxTrailVertex
{
    float pos[2];
    float normal[2];
    float texCoord;
};

struct FxTrailDef
{
    int scrollTimeMsec;
    int repeatDist;
    int splitDist;
    int vertCount;
    FxTrailVertex *verts;
    int indCount;
    unsigned __int16 *inds;
};

struct FxElemDef
{
    int flags;
    FxSpawnDef spawn;
    FxFloatRange spawnRange;
    FxFloatRange fadeInRange;
    FxFloatRange fadeOutRange;
    float spawnFrustumCullRadius;
    FxIntRange spawnDelayMsec;
    FxIntRange lifeSpanMsec;
    FxFloatRange spawnOrigin[3];
    FxFloatRange spawnOffsetRadius;
    FxFloatRange spawnOffsetHeight;
    FxFloatRange spawnAngles[3];
    FxFloatRange angularVelocity[3];
    FxFloatRange initialRotation;
    FxFloatRange gravity;
    FxFloatRange reflectionFactor;
    FxElemAtlas atlas;
    unsigned __int8 elemType;
    unsigned __int8 visualCount;
    unsigned __int8 velIntervalCount;
    unsigned __int8 visStateIntervalCount;
    qint32 velSamplesPtr;
    QVector<FxElemVelStateSample> velSamples;
    qint32 visSamplesPtr;
    QVector<FxElemVisStateSample> visSamples;
    FxElemDefVisuals visuals;
    float collMins[3];
    float collMaxs[3];
    EffectDefRef effectOnImpact;
    EffectDefRef effectOnDeath;
    EffectDefRef effectEmitted;
    FxFloatRange emitDist;
    FxFloatRange emitDistVariance;

    qint32 trailDefPtr;
    FxTrailDef *trailDef;

    unsigned __int8 sortOrder;
    unsigned __int8 lightingFrac;
    unsigned __int8 useItemClip;
    unsigned __int8 unused[1];
};

struct EffectDef
{
    qint32 namePtr;
    QString name;

    int flags;
    int totalSize;
    int msecLoopingLife;
    int elemDefCountLooping;
    int elemDefCountOneShot;
    int elemDefCountEmission;

    qint32 elemDefsPtr;
    QVector<FxElemDef> elemDefs;
};

#endif // EFFECTDEF_H
