#include "xasset.h"
#include "xanimparts.h"
#include "xclipmap.h"
#include "xcomworld.h"
#include "xfont.h"
#include "xfximpacttable.h"
#include "xgameworldmp.h"
#include "xgameworldsp.h"
#include "xgfxlightdef.h"
#include "xgfxworld.h"
#include "xloadedsound.h"
#include "xlocalizeentry.h"
#include "xmaterialpixelshader.h"
#include "xmenulist.h"
#include "xmodelpieces.h"
#include "xrawfile.h"
#include "xsoundaliaslist.h"
#include "xsounddriverglobals.h"
#include "xstringtable.h"
#include "xweapondef.h"

XAsset::

XAsset::XAsset()
    : mPtr(0)
    , mType(ASSET_TYPE_NONE)
    , mName("Unknown Asset")
{

}

XAsset::~XAsset()
{

}

void XAsset::SetPtr(qint32 aPtr) {
    mPtr = aPtr;
}

qint32 XAsset::GetPtr() const
{
    return mPtr;
}

void XAsset::SetType(XAssetType aType)
{
    mType = aType;
}

XAssetType XAsset::GetType() const
{
    return mType;
}

void XAsset::SetName(QString aName)
{
    mName = aName;
}

QString XAsset::GetName() const
{
    return mName;
}

void XAsset::SetDebug(bool aDebug)
{
    XAsset::mDebug = aDebug;
}

bool XAsset::IsDebug() const
{
    return mDebug;
}

void XAsset::Clear()
{
    if (mDebug)
    {
        qDebug() << QString("Clearing XAsset of type %1").arg(GetName());
    }
    mPtr = 0;
    mType = ASSET_TYPE_NONE;
}

void XAsset::ParsePtr(QDataStream *aStream, bool aDataFlag) {
    *aStream >> mPtr;
    if (mDebug)
    {
        // Always treat as unsigned when displaying in hex
        quint64 raw = static_cast<quint64>(static_cast<quint32>(mPtr));

        QString hexPtr = QString("0x%1")
                             .arg(raw, 8, 16, QLatin1Char('0'))
                             .toUpper();

        qDebug() << QString("[%1] Parsed %2 ptr %3 (%4)").arg(aStream->device()->pos(), 10, 10, QChar('0')).arg(GetName()).arg(mPtr).arg(hexPtr);
    }

    if (aDataFlag && mPtr == -1)
    {
        ParseData(aStream);
    }
}

XAsset* XAsset::Create(XAssetType aAssetType)
{
    if (mDebug)
    {
        qDebug() << QString("Creating XAsset with type %1").arg(XAssetTypeToString(aAssetType));
    }
    switch (aAssetType)
    {
    case ASSET_TYPE_XANIMPARTS:
        return new XAnimParts();
    case ASSET_TYPE_XMODEL:
        return new XModel();
    case ASSET_TYPE_MATERIAL:
        return new XMaterial();
    case ASSET_TYPE_PIXELSHADER:
        return new XMaterialPixelShader();
    case ASSET_TYPE_TECHNIQUE_SET:
        return new XMaterialTechniqueSet();
    case ASSET_TYPE_IMAGE:
        return new XGfxImage();
    case ASSET_TYPE_SOUND:
        return new XSoundAliasList();
    case ASSET_TYPE_SOUND_CURVE:
        return new XSoundCurve();
    case ASSET_TYPE_LOADED_SOUND:
        return new XLoadedSound();
    case ASSET_TYPE_CLIPMAP:
    case ASSET_TYPE_CLIPMAP_PVS:
        return new XClipMap();
    case ASSET_TYPE_COMWORLD:
        return new XComWorld();
    case ASSET_TYPE_GAMEWORLD_SP:
        return new XGameWorldSp();
    case ASSET_TYPE_GAMEWORLD_MP:
        return new XGameWorldMp();
    case ASSET_TYPE_MAP_ENTS:
        return new XMapEnts();
    case ASSET_TYPE_GFXWORLD:
        return new XGfxWorld();
    case ASSET_TYPE_LIGHT_DEF:
        return new XGfxLightDef();
    case ASSET_TYPE_FONT:
        return new XFont();
    case ASSET_TYPE_MENULIST:
        return new XMenuList();
    case ASSET_TYPE_MENU:
        return new XMenuDef();
    case ASSET_TYPE_LOCALIZE_ENTRY:
        return new XLocalizeEntry();
    case ASSET_TYPE_WEAPON:
        return new XWeaponDef();
    case ASSET_TYPE_SNDDRIVER_GLOBALS:
        return new XSoundDriverGlobals();
    case ASSET_TYPE_FX:
        return new XFxEffectDef();
    case ASSET_TYPE_IMPACT_FX:
        return new XFxImpactTable();
    case ASSET_TYPE_RAWFILE:
        return new XRawFile();
    case ASSET_TYPE_STRINGTABLE:
        return new XStringTable();
    case ASSET_TYPE_XMODELPIECES:
        return new XModelPieces();
    case ASSET_TYPE_PHYSPRESET:
        return new XPhysPreset();
    // case ASSET_TYPE_UI_MAP:
    // case ASSET_TYPE_AITYPE:
    // case ASSET_TYPE_MPTYPE:
    // case ASSET_TYPE_CHARACTER:
    // case ASSET_TYPE_XMODELALIAS:
    // case ASSET_TYPE_COUNT:
    // case ASSET_TYPE_STRING:
    // case ASSET_TYPE_ASSETLIST:
    default:
        break;
    }

    return nullptr;
}

QString XAsset::XAssetTypeToString(XAssetType type) {
    switch (type) {
    case ASSET_TYPE_XMODELPIECES:
        return "ModelPieces";
    case ASSET_TYPE_PHYSPRESET:
        return "PhysPreset";
    case ASSET_TYPE_XANIMPARTS:
        return "AnimParts";
    case ASSET_TYPE_XMODEL:
        return "Model";
    case ASSET_TYPE_MATERIAL:
        return "Material";
    case ASSET_TYPE_PIXELSHADER:
        return "PixelShader";
    case ASSET_TYPE_TECHNIQUE_SET:
        return "TechniqueSet";
    case ASSET_TYPE_IMAGE:
        return "Image";
    case ASSET_TYPE_SOUND:
        return "Sound";
    case ASSET_TYPE_SOUND_CURVE:
        return "SoundCurve";
    case ASSET_TYPE_LOADED_SOUND:
        return "LoadedSound";
    case ASSET_TYPE_CLIPMAP:
        return "ClipMap";
    case ASSET_TYPE_CLIPMAP_PVS:
        return "ClipMapPvs";
    case ASSET_TYPE_COMWORLD:
        return "ComWorld";
    case ASSET_TYPE_GAMEWORLD_SP:
        return "GameWorldSp";
    case ASSET_TYPE_GAMEWORLD_MP:
        return "GameWorldMp";
    case ASSET_TYPE_MAP_ENTS:
        return "MapEnts";
    case ASSET_TYPE_GFXWORLD:
        return "GfxWorld";
    case ASSET_TYPE_LIGHT_DEF:
        return "LightDef";
    case ASSET_TYPE_UI_MAP:
        return "UiMap";
    case ASSET_TYPE_FONT:
        return "Font";
    case ASSET_TYPE_MENULIST:
        return "MenuList";
    case ASSET_TYPE_MENU:
        return "Menu";
    case ASSET_TYPE_LOCALIZE_ENTRY:
        return "LocalizeEntry";
    case ASSET_TYPE_WEAPON:
        return "Weapon";
    case ASSET_TYPE_SNDDRIVER_GLOBALS:
        return "SndDriverGlobals";
    case ASSET_TYPE_FX:
        return "Fx";
    case ASSET_TYPE_IMPACT_FX:
        return "ImpactFx";
    case ASSET_TYPE_AITYPE:
        return "AiType";
    case ASSET_TYPE_MPTYPE:
        return "MpType";
    case ASSET_TYPE_CHARACTER:
        return "Character";
    case ASSET_TYPE_XMODELALIAS:
        return "ModelAlias";
    case ASSET_TYPE_RAWFILE:
        return "RawFile";
    case ASSET_TYPE_STRINGTABLE:
        return "StringTable";
    case ASSET_TYPE_COUNT:
        return "Count";
    case ASSET_TYPE_STRING:
        return "String";
    case ASSET_TYPE_ASSETLIST:
        return "AssetList";
    case ASSET_TYPE_COLLISION_MAP:
        return "CollisionMap";
    case ASSET_TYPE_GFX_MAP:
        return "GfxMap";
    case ASSET_TYPE_D3DBSP:
        return "D3dBsp";
    case ASSET_TYPE_GAME_MAP_SP:
        return "GameMapSp";
    case ASSET_TYPE_COL_MAP_SP:
        return "ColMapSp";
    case ASSET_TYPE_DESTRUCTIBLE:
        return "Destructible";
    case ASSET_TYPE_SHOCK_FILE:
        return "ShockFile";
    case ASSET_TYPE_PHYSCOLLMAP:
        return "PhysCollMap";
    case ASSET_TYPE_XMODEL_SURFS:
        return "XModelSurfs";
    case ASSET_TYPE_CLIPMAP_SP:
        return "ClipmapSp";
    case ASSET_TYPE_CLIPMAP_MP:
        return "ClipmapMp";
    case ASSET_TYPE_FXWORLD:
        return "FxWorld";
    case ASSET_TYPE_LEADERBOARD:
        return "Leaderboard";
    case ASSET_TYPE_STRUCTURED_DATA_DEF:
        return "StructuredDataDef";
    case ASSET_TYPE_TRACER:
        return "Tracer";
    case ASSET_TYPE_VEHICLE:
        return "Vehicle";
    case ASSET_TYPE_ADDON_MAP_ENTS:
        return "AddonMapEnts";
    case ASSET_TYPE_PHYSCONSTRAINTS:
        return "PhysConstraints";
    case ASSET_TYPE_DESTRUCTIBLEDEF:
        return "DestructibleDef";
    case ASSET_TYPE_SOUND_PATCH:
        return "SoundPatch";
    case ASSET_TYPE_WEAPONDEF:
        return "WeaponDef";
    case ASSET_TYPE_WEAPON_VARIANT:
        return "WeaponVariant";
    case ASSET_TYPE_MPBODY:
        return "MpBody";
    case ASSET_TYPE_MPHEAD:
        return "MpHead";
    case ASSET_TYPE_PACK_INDEX:
        return "PackIndex";
    case ASSET_TYPE_XGLOBALS:
        return "Globals";
    case ASSET_TYPE_DDL:
        return "Ddl";
    case ASSET_TYPE_GLASSES:
        return "Glasses";
    case ASSET_TYPE_EMBLEMSET:
        return "EmblemSet";
    case ASSET_TYPE_GLASSWORLD:
        return "GlassWorld";
    case ASSET_TYPE_PATHDATA:
        return "PathData";
    case ASSET_TYPE_VEHICLE_TRACK:
        return "VehicleTrack";
    case ASSET_TYPE_ATTACHMENT:
        return "Attachment";
    case ASSET_TYPE_SURFACE_FX:
        return "SurfaceFx";
    case ASSET_TYPE_SCRIPTFILE:
        return "ScriptFile";
    case ASSET_TYPE_SOUND_SUBMIX:
        return "SoundSubmix";
    case ASSET_TYPE_SOUND_EVENT:
        return "SoundEvent";
    case ASSET_TYPE_LPF_CURVE:
        return "LpfCurve";
    case ASSET_TYPE_REVERB_CURVE:
        return "ReverbCurve";
    case ASSET_TYPE_GFXWORLD_TRANSIENT_ZONE:
        return "GfxWorldTransientZone";
    case ASSET_TYPE_ANIMCLASS:
        return "AnimClass";
    case ASSET_TYPE_NET_CONST_STRINGS:
        return "NetConstStrings";
    case ASSET_TYPE_REVERB_PRESET:
        return "ReverbPreset";
    case ASSET_TYPE_LUA_FILE:
        return "LuaFile";
    case ASSET_TYPE_SCRIPTABLE:
        return "Scriptable";
    case ASSET_TYPE_EQUIPMENT_SND_TABLE:
        return "EquipmentSndTable";
    case ASSET_TYPE_DOPPLER_PRESET:
        return "DopplerPreset";
    case ASSET_TYPE_LASER:
        return "Laser";
    case ASSET_TYPE_SKELETON_SCRIPT:
        return "SkeletonScript";
    case ASSET_TYPE_PHYS_CONSTRAINTS:
        return "PhysConstraints";
    case ASSET_TYPE_DESTRUCTIBLE_DEF:
        return "DestructibleDef";
    case ASSET_TYPE_XMODEL_MESH:
        return "ModelMesh";
    case ASSET_TYPE_COMPUTE_SHADER_SET:
        return "ComputeShaderSet";
    case ASSET_TYPE_FONT_ICON:
        return "FontIcon";
    case ASSET_TYPE_PLAYER_SOUNDS_TABLE:
        return "PlayerSoundsTable";
    case ASSET_TYPE_PLAYER_FX_TABLE:
        return "PlayerFxTable";
    case ASSET_TYPE_SHARED_WEAPON_SOUNDS:
        return "SharedWeaponSounds";
    case ASSET_TYPE_ATTACHMENT_UNIQUE:
        return "AttachmentUnique";
    case ASSET_TYPE_WEAPON_CAMO:
        return "WeaponCamo";
    case ASSET_TYPE_CUSTOMIZATION_TABLE:
        return "CustomizationTable";
    case ASSET_TYPE_CUSTOMIZATION_TABLE_FEIMAGES:
        return "CustomizationTableFeimages";
    case ASSET_TYPE_CUSTOMIZATION_TABLE_COLOR:
        return "CustomizationTableColor";
    case ASSET_TYPE_STRUCTURED_TABLE:
        return "StructuredTable";
    case ASSET_TYPE_LEADERBOARD_DEF:
        return "LeaderboardDef";
    case ASSET_TYPE_SCRIPT_PARSE_TREE:
        return "ScriptParseTree";
    case ASSET_TYPE_KEY_VALUE_PAIRS:
        return "KeyValuePairs";
    case ASSET_TYPE_VEHICLE_TRACER:
        return "VehicleTracer";
    case ASSET_TYPE_SURFACE_FX_TABLE:
        return "SurfaceFxTable";
    case ASSET_TYPE_SURFACE_SOUND_DEF:
        return "SurfaceSoundDef";
    case ASSET_TYPE_FOOTSTEP_TABLE:
        return "FootstepTable";
    case ASSET_TYPE_ENTITY_FX_IMPACTS:
        return "EntityFxImpacts";
    case ASSET_TYPE_ENTITY_SOUND_IMPACTS:
        return "EntitySoundImpacts";
    case ASSET_TYPE_VEHICLE_FX_DEF:
        return "VehicleFxDef";
    case ASSET_TYPE_VEHICLE_SOUND_DEF:
        return "VehicleSoundDef";
    case ASSET_TYPE_SCRIPT_BUNDLE:
        return "ScriptBundle";
    case ASSET_TYPE_SCRIPT_BUNDLE_LIST:
        return "ScriptBundleList";
    case ASSET_TYPE_RUMBLE:
        return "Rumble";
    case ASSET_TYPE_AIM_TABLE:
        return "AimTable";
    case ASSET_TYPE_ANIM_SELECTOR_TABLE:
        return "AnimSelectorTable";
    case ASSET_TYPE_ANIM_MAPPING_TABLE:
        return "AnimMappingTable";
    case ASSET_TYPE_ANIM_STATE_MACHINE:
        return "AnimStateMachine";
    case ASSET_TYPE_BEHAVIOR_TREE:
        return "BehaviorTree";
    case ASSET_TYPE_BEHAVIOR_STATE_MACHINE:
        return "BehaviorStateMachine";
    case ASSET_TYPE_S_ANIM:
        return "SAnim";
    case ASSET_TYPE_BIT_FIELD:
        return "BitField";
    case ASSET_TYPE_MAP_TABLE:
        return "MapTable";
    case ASSET_TYPE_MAP_TABLE_LOADING_IMAGES:
        return "MapTableLoadingImages";
    case ASSET_TYPE_MEDAL:
        return "Medal";
    case ASSET_TYPE_MEDAL_TABLE:
        return "MedalTable";
    case ASSET_TYPE_OBJECTIVE:
        return "Objective";
    case ASSET_TYPE_OBJECTIVE_LIST:
        return "ObjectiveList";
    case ASSET_TYPE_BEAM:
        return "Beam";
    case ASSET_TYPE_STREAMER_HINT:
        return "StreamerHint";
    case ASSET_TYPE_CG_MEDIA_TABLE:
        return "CgMediaTable";
    default:
        return "UnknownAsset";
    }
}

bool XAsset::mDebug = true;
