#include "zonefile_cod6_360.h"

#include <QFile>
#include "xdatastream.h"
#include <QDebug>

ZoneFile_COD6_360::ZoneFile_COD6_360()
    : ZoneFile()
{
    pSetType(0, ASSET_TYPE_PHYSPRESET);
    pSetType(1, ASSET_TYPE_PHYSCOLLMAP);
    pSetType(2, ASSET_TYPE_XANIMPARTS);
    pSetType(3, ASSET_TYPE_XMODEL_SURFS);
    pSetType(4, ASSET_TYPE_XMODEL);
    pSetType(5, ASSET_TYPE_MATERIAL);
    pSetType(6, ASSET_TYPE_PIXELSHADER);
    pSetType(7, ASSET_TYPE_TECHNIQUE_SET);
    pSetType(8, ASSET_TYPE_IMAGE);
    pSetType(9, ASSET_TYPE_SOUND);
    pSetType(10, ASSET_TYPE_SOUND_CURVE);
    pSetType(11, ASSET_TYPE_LOADED_SOUND);
    pSetType(12, ASSET_TYPE_CLIPMAP_SP);
    pSetType(13, ASSET_TYPE_CLIPMAP_MP);
    pSetType(14, ASSET_TYPE_COMWORLD);
    pSetType(15, ASSET_TYPE_GAMEWORLD_SP);
    pSetType(16, ASSET_TYPE_GAMEWORLD_MP);
    pSetType(17, ASSET_TYPE_MAP_ENTS);
    pSetType(18, ASSET_TYPE_FXWORLD);
    pSetType(19, ASSET_TYPE_GFXWORLD);
    pSetType(20, ASSET_TYPE_LIGHT_DEF);
    pSetType(21, ASSET_TYPE_UI_MAP);
    pSetType(22, ASSET_TYPE_FONT);
    pSetType(23, ASSET_TYPE_MENULIST);
    pSetType(24, ASSET_TYPE_MENU);
    pSetType(25, ASSET_TYPE_LOCALIZE_ENTRY);
    pSetType(26, ASSET_TYPE_WEAPON);
    pSetType(27, ASSET_TYPE_SNDDRIVER_GLOBALS);
    pSetType(28, ASSET_TYPE_FX);
    pSetType(29, ASSET_TYPE_IMPACT_FX);
    pSetType(30, ASSET_TYPE_AITYPE);
    pSetType(31, ASSET_TYPE_MPTYPE);
    pSetType(32, ASSET_TYPE_CHARACTER);
    pSetType(33, ASSET_TYPE_XMODELALIAS);
    pSetType(34, ASSET_TYPE_RAWFILE);
    pSetType(35, ASSET_TYPE_STRINGTABLE);
    pSetType(36, ASSET_TYPE_LEADERBOARD);
    pSetType(37, ASSET_TYPE_STRUCTURED_DATA_DEF);
    pSetType(38, ASSET_TYPE_TRACER);
    pSetType(39, ASSET_TYPE_VEHICLE);
    pSetType(40, ASSET_TYPE_ADDON_MAP_ENTS);
    pSetType(41, ASSET_TYPE_COUNT);
    pSetType(42, ASSET_TYPE_STRING);
    pSetType(43, ASSET_TYPE_ASSETLIST);
}

ZoneFile_COD6_360::~ZoneFile_COD6_360() {

}

bool ZoneFile_COD6_360::Load(const QByteArray aFileData) {
    // Open zone file as little endian stream
    // XDataStream zoneFileStream(aFileData);
    // zoneFileStream.setByteOrder(XDataStream::BigEndian);

    // // Parse data from zone file header
    // pParseZoneHeader(&zoneFileStream);
    // qDebug() << zoneFileStream.device()->pos();
    // SetRecords(pParseZoneIndex(&zoneFileStream, GetRecordCount()));
    // qDebug() << zoneFileStream.device()->pos();
    // SetAssetMap(pParseAssets(&zoneFileStream, GetRecords()));
    // qDebug() << zoneFileStream.device()->pos();

    return true;
}

// void ZoneFile_COD6_360::pParseZoneHeader(XDataStream *aZoneFileStream) {
//     SetSize(pParseZoneSize(aZoneFileStream));

//     aZoneFileStream->skipRawData(28);

//     SetTagCount(pParseZoneTagCount(aZoneFileStream));
//     pParseZoneUnknownsB(aZoneFileStream);

//     SetRecordCount(pParseZoneRecordCount(aZoneFileStream));

//     quint32 tagCount = GetTagCount();
//     if (tagCount) {
//         pParseZoneUnknownsC(aZoneFileStream);
//         SetTags(pParseZoneTags(aZoneFileStream, tagCount));
//     } else {
//         aZoneFileStream->skipRawData(4);
//     }
// }

// quint32 ZoneFile_COD6_360::pParseZoneSize(XDataStream *aZoneFileStream) {
//     quint32 zoneFileSize;
//     *aZoneFileStream >> zoneFileSize;
//     if (zoneFileSize <= 0) {
//         qDebug() << "Tried to open empty zone file!";
//         exit(-1);
//     }
//     zoneFileSize += 32;
//     return zoneFileSize;
// }

// /*
//     ParseZoneUnknownsA()

//     Parses the 1st section of unknowns as hex vals and uint32s
// */
// void ZoneFile_COD6_360::pParseZoneUnknownsA(XDataStream *aZoneFileStream) {
//     // Byte 4-7, 8-11, 12-15: unknown
//     QByteArray unknown1(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown1.data(), 4);

//     QByteArray unknown2(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown2.data(), 4);

//     QByteArray unknown3(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown3.data(), 4);

//     // Byte 16-19, 20-23: empty/unknown
//     QByteArray unknown4(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown4.data(), 4);

//     QByteArray unknown5(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown5.data(), 4);

//     // Byte 24-27: somehow related to the filesize, but smaller value
//     QByteArray unknown6(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown6.data(), 4);

//     // Byte 28-31, 32-35: unknown
//     QByteArray unknown7(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown7.data(), 4);

//     QByteArray unknown8(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown8.data(), 4);
// }

// /*
//     ParseZoneTagCount()

//     Parses the number of string tags in the zone index
// */
// quint32 ZoneFile_COD6_360::pParseZoneTagCount(XDataStream *aZoneFileStream) {
//     quint32 tagCount;
//     *aZoneFileStream >> tagCount;
//     return tagCount;
// }

// /*
//     ParseZoneRecordCount()

//     Parses the number of records in the zone index
// */
// quint32 ZoneFile_COD6_360::pParseZoneRecordCount(XDataStream *aZoneFileStream) {
//     quint32 recordCount;
//     *aZoneFileStream >> recordCount;
//     return recordCount;
// }

// /*
//     ParseZoneUnknownsB()

//     Parses the 2nd section of unknowns as hex vals and uint32s
// */
// void ZoneFile_COD6_360::pParseZoneUnknownsB(XDataStream *aZoneFileStream) {
//     // Byte 44-47: Unknown/empty?
//     QByteArray unknown9(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown9.data(), 4);
// }

// /*
//     pParseZoneUnknownsC()

//     Parses the 3rd section of unknowns as hex vals and uint32s
// */
// void ZoneFile_COD6_360::pParseZoneUnknownsC(XDataStream *aZoneFileStream) {
//     // Byte 40-43: Unknown/empty?
//     QByteArray unknown10(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown10.data(), 4);

//     // Byte 44-47: Unknown/empty?
//     QByteArray unknown11(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(unknown11.data(), 4);
// }

// /*
//     ParseZoneTags()

//     Parses the string tags ate the start of zone file
// */
// QStringList ZoneFile_COD6_360::pParseZoneTags(XDataStream *aZoneFileStream, quint32 tagCount) {
//     QStringList tags;

//     // Byte 48-51: Repeated separators? ÿÿÿÿ x i
//     aZoneFileStream->skipRawData(4 * (tagCount - 1));

//     // Parse tags/strings before index
//     QString zoneTag;
//     char zoneTagChar;
//     for (quint32 i = 0; i < tagCount - 1; i++) {
//         *aZoneFileStream >> zoneTagChar;
//         while (zoneTagChar != 0) {
//             zoneTag += zoneTagChar;
//             *aZoneFileStream >> zoneTagChar;
//         }
//         if (!zoneTag.isEmpty()) {
//             tags << zoneTag;
//         }
//         zoneTag.clear();
//     }

//     if (!aZoneFileStream->device()->peek(8).toHex().contains("ffffffff")) {
//         *aZoneFileStream >> zoneTagChar;
//         while (zoneTagChar != 0) {
//             zoneTag += zoneTagChar;
//             *aZoneFileStream >> zoneTagChar;
//         }
//         if (!zoneTag.isEmpty()) {
//             tags << zoneTag;
//         }
//     }

//     return tags;
// }

// /*
//     ParseZoneIndex()

//     Parse the binary zone index data and populate table
// */
// QStringList ZoneFile_COD6_360::pParseZoneIndex(XDataStream *aZoneFileStream, quint32 recordCount) {
//     QStringList result;
//     qDebug() << aZoneFileStream->device()->pos();
//     // Don't parse if no records
//     if (!recordCount) { return result; }

//     // Parse index & map found asset types
//     for (quint32 i = 0; i < recordCount; i++) {
//         // Skip record start
//         QByteArray rawAssetType(4, Qt::Uninitialized);
//         aZoneFileStream->readRawData(rawAssetType.data(), 4);
//         result << rawAssetType.toHex();

//         // Skip separator
//         aZoneFileStream->skipRawData(4);
//     }
//     return result;
// }

// AssetMap ZoneFile_COD6_360::pParseAssets(XDataStream *aZoneFileStream, QStringList assetOrder) {
//     AssetMap result;

//     for (int i = 0; i < assetOrder.size(); i++) {
//         const QString typeHex = assetOrder[i];
//         const XAssetType assetType = ConvertRawType(typeHex);
//         const QString typeStr = XAssetTypeToStr(assetType);

//         if (assetType == ASSET_TYPE_LOCALIZE_ENTRY) { // localized string asset
//             result.localizeEntries << pParseAsset_LocalString(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_RAWFILE) { // gsc
//             auto rawFile = pParseASSET_TYPE_RAWFILE(aZoneFileStream);
//             if (rawFile.length) {
//                 result.rawFiles << rawFile;
//             }
//         } else if (assetType == ASSET_TYPE_PHYSPRESET) { // physpreset
//             pParseASSET_TYPE_PHYSPRESET(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_XMODEL) { // xmodel
//             result.models << pParseASSET_TYPE_XMODEL(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_MATERIAL) { // material
//             result.materials << pParseASSET_TYPE_MATERIAL(aZoneFileStream);
//         } else if (assetType == ASSET_SHADER) { // pixelshader
//             pParseAsset_Shader(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_TECHNIQUE_SET) { // techset include
//             result.techSets << pParseAsset_TechSet(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_IMAGE) { // image
//             result.images << pParseASSET_TYPE_IMAGE(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_SOUND) { // loaded_sound
//             result.sounds << pParseASSET_TYPE_SOUND(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_COLLISION_MAP) { // col_map_mp
//             pParseAsset_ColMapMP(aZoneFileStream);
//         } else if (assetType == ASSET_MP_MAP) { // game_map_sp
//             pParseAsset_GameMapSP(aZoneFileStream);
//         } else if (assetType == ASSET_SP_MAP) { // game_map_mp
//             pParseAsset_GameMapMP(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_LIGHT_DEF) { // lightdef
//             pParseAsset_LightDef(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_UI_MAP) { // ui_map
//             pParseAsset_UIMap(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_SNDDRIVER_GLOBALS) { // SoundDriver
//             pParseASSET_TYPE_SOUNDDriver(aZoneFileStream);
//         } else if (assetType == ASSET_AI_TYPE) { // aitype
//             pParseASSET_TYPE_AITYPE(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_FX) { // aitype
//             pParseASSET_TYPE_FX(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_XANIMPARTS) { // aitype
//             result.animations << pParseASSET_TYPE_XANIMPARTS(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_STRINGTABLE) { // string_table
//             result.stringTables << pParseASSET_TYPE_STRINGTABLE(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_MENU) { // string_table
//             result.menuDefinitions << pParseASSET_TYPE_MENUDef(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_WEAPON) { // string_table
//             pParseASSET_TYPE_WEAPON(aZoneFileStream);
//         } else if (assetType == ASSET_TYPE_D3DBSP) { // string_table
//             pParseASSET_TYPE_D3DBSP(aZoneFileStream);
//         }
//     }
//     return result;
// }

// LocalizeEntry ZoneFile_COD6_360::pParseAsset_LocalString(XDataStream *aZoneFileStream) {
//     LocalizeEntry result;

//     quint32 stringPtr, aliasPtr;
//     *aZoneFileStream >> stringPtr >> aliasPtr;
//     if (stringPtr == 4294967295) {
//         // Parse local string asset contents
//         QString localStr;
//         char localStrChar;
//         *aZoneFileStream >> localStrChar;
//         while (localStrChar != 0) {
//             result.string += localStrChar;
//             *aZoneFileStream >> localStrChar;
//         }
//     } else {
//         result.string = "String Ptr: " + QString::number(stringPtr);
//     }

//     if (aliasPtr == 4294967295) {
//         // Parse rawfile name
//         QString aliasName;
//         char aliasNameChar;
//         *aZoneFileStream >> aliasNameChar;
//         while (aliasNameChar != 0) {
//             result.alias += aliasNameChar;
//             *aZoneFileStream >> aliasNameChar;
//         }
//     } else {
//         result.string = "Alias Ptr: " + QString::number(aliasPtr);
//     }

//     return result;
// }

// RawFile ZoneFile_COD6_360::pParseASSET_TYPE_RAWFILE(XDataStream *aZoneFileStream) {
//     RawFile result;

//     // Skip start separator FF FF FF FF (pointer?)
//     aZoneFileStream->skipRawData(4);

//     *aZoneFileStream >> result.length;

//     // Skip unknown 4 byte data
//     aZoneFileStream->skipRawData(4);

//     // Parse rawfile path
//     char scriptPathChar;
//     *aZoneFileStream >> scriptPathChar;
//     while (scriptPathChar != 0) {
//         result.path += scriptPathChar;
//         *aZoneFileStream >> scriptPathChar;
//     }
//     result.path.replace(",", "");

//     const QStringList pathParts = result.path.split('/');
//     if (pathParts.size() == 0) {
//         qDebug() << "Failed to parse ff path! " << result.path;
//         exit(-1);
//     }
//     if (result.path.contains(".bik")) {
//         QByteArray bikData(result.length, Qt::Uninitialized);
//         aZoneFileStream->readRawData(bikData.data(), result.length);

//         //QFile bikFile(QDir::currentPath() + "/" + rawFilePath.split('/').last());
//         //qDebug() << bikFile.fileName();
//         //if (!bikFile.open(QIODevice::WriteOnly)) {
//         //    qWarning() << "Failed to open .bik file for writing!";
//         //    return;
//         //}
//         //qDebug() << QString("%1: %2").arg(rawFilePath).arg(bikFile.fileName());
//         //bikFile.write(bikData);
//     } else {
//         // Parse gsc contents
//         char rawFileContentsChar;
//         *aZoneFileStream >> rawFileContentsChar;
//         while (rawFileContentsChar != 0 && rawFileContentsChar != -1) {
//             result.contents += rawFileContentsChar;
//             *aZoneFileStream >> rawFileContentsChar;
//         }
//     }
//     return result;
// }

// void ZoneFile_COD6_360::pParseASSET_TYPE_PHYSPRESET(XDataStream *aZoneFileStream) {
//     Q_UNUSED(aZoneFileStream);
// }

// Model ZoneFile_COD6_360::pParseASSET_TYPE_XMODEL(XDataStream *aZoneFileStream) {
//     Model result;

//     *aZoneFileStream >> result.namePtr >> result.tagCount >> result.rootTagCount
//         >> result.surfCount >> result.unknownCount >> result.boneNamePtr
//         >> result.parentListPtr >> result.quatsPtr >> result.transPtr
//         >> result.partClassPtr >> result.baseMatPtr
//         >> result.surfsPtr >> result.materialHandlesPtr;

//     // Parse XModelLodInfo
//     for (int i = 1; i <= 4; i++) {
//         quint32 intDist;
//         *aZoneFileStream >> intDist;

//         std::memcpy(&result.lodInfo[i].dist, &intDist, sizeof(result.lodInfo[i].dist));
//         *aZoneFileStream >> result.lodInfo[i].numsurfs >> result.lodInfo[i].surfIndex;

//         aZoneFileStream->skipRawData(4);

//         *aZoneFileStream >> result.lodInfo[i].partBits[0]
//             >> result.lodInfo[i].partBits[1]
//             >> result.lodInfo[i].partBits[2]
//             >> result.lodInfo[i].partBits[3];
//     }

//     *aZoneFileStream >> result.collSurfsPtr >> result.numCollSurfs >> result.contents >> result.boneInfoPtr;

//     quint32 intRadius, intMins[3], intMaxs[3];
//     *aZoneFileStream >> intRadius >> intMins[0] >> intMins[1]
//         >> intMins[2] >> intMaxs[0] >> intMaxs[1] >> intMaxs[2];

//     std::memcpy(&result.radius, &intRadius, sizeof(result.radius));

//     std::memcpy(&result.mins[0], &intMins[0], sizeof(result.mins[0]));
//     std::memcpy(&result.mins[1], &intMins[1], sizeof(result.mins[1]));
//     std::memcpy(&result.mins[2], &intMins[2], sizeof(result.mins[2]));

//     std::memcpy(&result.maxs[0], &intMaxs[0], sizeof(result.maxs[0]));
//     std::memcpy(&result.maxs[1], &intMaxs[1], sizeof(result.maxs[2]));
//     std::memcpy(&result.maxs[2], &intMaxs[2], sizeof(result.maxs[3]));

//     *aZoneFileStream >> result.numLods >> result.collLod >> result.streamInfoPtr
//         >> result.memUsage >> result.flags >> result.physPresetPtr >> result.physGeomsPtr;

//     // Parse model name
//     char modelNameChar;
//     *aZoneFileStream >> modelNameChar;
//     while (modelNameChar == 0) {
//         *aZoneFileStream >> modelNameChar;
//     }
//     while (modelNameChar != 0) {
//         result.modelName += modelNameChar;
//         *aZoneFileStream >> modelNameChar;
//     }
//     return result;
// }

// Material ZoneFile_COD6_360::pParseASSET_TYPE_MATERIAL(XDataStream *aZoneFileStream) {
//     Material result;

//     *aZoneFileStream >> result.namePtr;

//     //aZoneFileStream->skipRawData(23 * 4);

//     for (int i = 0; i < 23; i++) {
//         qint32 unknownPtr;
//         *aZoneFileStream >> unknownPtr;
//         result.pointers << unknownPtr;
//     }

//     if (result.namePtr == -1) {
//         aZoneFileStream->skipRawData(1);

//         QString materialName;
//         char materialNameChar;
//         *aZoneFileStream >> materialNameChar;
//         while (materialNameChar != 0) {
//             result.name += materialNameChar;
//             *aZoneFileStream >> materialNameChar;
//         }
//     }

//     aZoneFileStream->skipRawData(3 * 4);

//     qint32 compressionPtr, compression, unknownSectionPtr;
//     *aZoneFileStream >> compressionPtr;
//     if (compressionPtr == -1) {
//         *aZoneFileStream >> compression;

//         *aZoneFileStream >> unknownSectionPtr;
//         if (unknownSectionPtr == -2) {
//             aZoneFileStream->skipRawData(6 * 4);
//         }
//     }

//     qint32 imageNamePtr;
//     *aZoneFileStream >> imageNamePtr;
//     if (imageNamePtr == -1) {
//         QString imageName;
//         char imageNameChar;
//         *aZoneFileStream >> imageNameChar;
//         while (imageNameChar != 0) {
//             imageName += imageNameChar;
//             *aZoneFileStream >> imageNameChar;
//         }
//     }

//     QByteArray compressionData(4, Qt::Uninitialized);
//     QString compressionStr;
//     if (compressionPtr == -1) {
//         aZoneFileStream->skipRawData(2 * 4);
//         aZoneFileStream->readRawData(compressionData.data(), 4);
//         aZoneFileStream->skipRawData(4);
//         compressionStr = QString::fromUtf8(compressionData);
//         aZoneFileStream->skipRawData(4);
//     }
//     aZoneFileStream->skipRawData(4);

//     return result;
// }

// Shader ZoneFile_COD6_360::pParseAsset_Shader(XDataStream *aZoneFileStream) {
//     Shader result = Shader();

//     quint8 minorVersion, majorVersion;
//     *aZoneFileStream >> minorVersion >> majorVersion;

//     quint32 magic;
//     *aZoneFileStream >> magic;

//     // Verify .fxc magic
//     if (magic != 65534 && magic != 65535) { return result; }

//     SHADER_TYPE type = SHADER_NONE;
//     quint32 rawShaderType;
//     *aZoneFileStream >> rawShaderType;
//     if (rawShaderType == 65535) { // Pixel shader
//         type = SHADER_PIXEL;
//     } else if (rawShaderType == 65534) { // Vertex shader
//         type = SHADER_VERTEX;
//     }
//     Q_UNUSED(type);

//     while (true) {
//         quint32 instructionToken;
//         *aZoneFileStream >> instructionToken;

//         SHADER_OPCODE opCode = (SHADER_OPCODE)(instructionToken & 0xffff);

//         int size;
//         if (opCode == OPCODE_End) {
//             break;
//         } else if (opCode == OPCODE_Comment) {
//             size = (int)((instructionToken >> 16) & 0x7FFF);
//         } else {
//             size = (int)((instructionToken >> 24) & 0x0f);
//         }
//         Q_UNUSED(size);
//     }


//     return result;
// }

// MaterialTechSet ZoneFile_COD6_360::pParseAsset_TechSet(XDataStream *aZoneFileStream) {
//     MaterialTechSet result;

//     qint32 namePtr;
//     *aZoneFileStream >> namePtr;


//     for (int i = 0; i < 53; i++) {
//         quint32 ptr;
//         *aZoneFileStream >> ptr;

//         //result.pointers << ptr;
//     }

//     //aZoneFileStream->skipRawData(53 * 4);

//     if (namePtr == -1) {
//         aZoneFileStream->skipRawData(1);

//         // Parse techset name
//         char techSetNameChar;
//         *aZoneFileStream >> techSetNameChar;
//         while (techSetNameChar != 0) {
//             result.name += techSetNameChar;
//             *aZoneFileStream >> techSetNameChar;
//         }
//     }

//     //result.name.replace(",", "");
//     return result;
// }

// Image ZoneFile_COD6_360::pParseASSET_TYPE_IMAGE(XDataStream *aZoneFileStream) {
//     Image result;

//     aZoneFileStream->skipRawData(4);
//     *aZoneFileStream >> result.unknowna >> result.unknownb
//         >> result.unknownc >> result.unknownd
//         >> result.unknowne >> result.unknownf
//         >> result.unknowng;

//     aZoneFileStream->skipRawData(15 * 4);
//     *aZoneFileStream >> result.unknownh >> result.unknowni;

//     aZoneFileStream->skipRawData(4);
//     *aZoneFileStream >> result.unknownj;

//     aZoneFileStream->skipRawData(4);

//     char materialNameChar;
//     *aZoneFileStream >> materialNameChar;
//     while (materialNameChar != 0) {
//         result.materialName += materialNameChar;
//         *aZoneFileStream >> materialNameChar;
//     }
//     result.materialName.replace(",", "");

//     if (result.unknowna) {
//         *aZoneFileStream >> result.unknownk;
//         *aZoneFileStream >> result.unknownl;
//         *aZoneFileStream >> result.unknownm;

//         aZoneFileStream->skipRawData(4);

//         *aZoneFileStream >> result.unknown1;

//         aZoneFileStream->skipRawData(4);

//         *aZoneFileStream >> result.unknown2 >> result.unknown3
//             >> result.size1 >> result.size2
//             >> result.unknown4 >> result.unknown5;

//         aZoneFileStream->skipRawData(4);

//         char imageNameChar;
//         *aZoneFileStream >> imageNameChar;
//         while (imageNameChar != 0) {
//             result.name += imageNameChar;
//             *aZoneFileStream >> imageNameChar;
//         }

//         *aZoneFileStream >> result.unknown6 >> result.unknown7;

//         QByteArray compressionData(8, Qt::Uninitialized);
//         aZoneFileStream->readRawData(compressionData.data(), 8);
//         if (compressionData.contains("DXT1")) {
//             result.compression = COMPRESSION_DXT1;
//         } else if (compressionData.contains("DXT3")) {
//             result.compression = COMPRESSION_DXT3;
//         } else if (compressionData.contains("DXT5")) {
//             result.compression = COMPRESSION_DXT5;
//         } else {
//             result.compression = COMPRESSION_NONE;
//         }

//         *aZoneFileStream >> result.unknown8 >> result.unknown9;
//     }

//     return result;
// }

// SoundAliasList ZoneFile_COD6_360::pParseASSET_TYPE_SOUND(XDataStream *aZoneFileStream) {
//     LoadedSound result;
//     return result;

//     QByteArray rootNamePtr(4, Qt::Uninitialized);
//     aZoneFileStream->readRawData(rootNamePtr.data(), 4);

//     aZoneFileStream->skipRawData(4);

//     *aZoneFileStream >> result.count;

//     if (rootNamePtr.toHex() == "ffffffff") {
//         // Read in sound file name
//         char soundNameChar;
//         *aZoneFileStream >> soundNameChar;
//         while (soundNameChar != 0) {
//             result.name += soundNameChar;
//             *aZoneFileStream >> soundNameChar;
//         }
//     }

//     int tagCount = 0;
//     int resultCount = 0;
//     for (quint32 i = 0; i < result.count; i++) {
//         aZoneFileStream->skipRawData(12);

//         QByteArray tagPtr(4, Qt::Uninitialized);
//         aZoneFileStream->readRawData(tagPtr.data(), 4);

//         if (tagPtr.toHex() == "ffffffff") {
//             tagCount++;
//         }
//         aZoneFileStream->skipRawData(4);

//         QByteArray pathPtr(4, Qt::Uninitialized);
//         aZoneFileStream->readRawData(pathPtr.data(), 4);

//         if (pathPtr.toHex() == "ffffffff") {
//             resultCount++;
//         }

//         aZoneFileStream->skipRawData(160);
//     }

//     for (int i = 0; i < tagCount; i++) {
//         // Read in tag?
//         QString tag;
//         char tagChar;
//         *aZoneFileStream >> tagChar;
//         while (tagChar != 0) {
//             tag += tagChar;
//             *aZoneFileStream >> tagChar;
//         }
//     }

//     for (int i = 0; i < resultCount; i++) {
//         Sound sound;

//         if (aZoneFileStream->device()->peek(12).toHex().contains("ffffffff00000000")) {
//             aZoneFileStream->skipRawData(12);
//         }

//         aZoneFileStream->skipRawData(8);

//         QByteArray aliasPtr(4, Qt::Uninitialized);
//         aZoneFileStream->readRawData(aliasPtr.data(), 4);

//         QByteArray namePtr(4, Qt::Uninitialized);
//         aZoneFileStream->readRawData(namePtr.data(), 4);

//         *aZoneFileStream >> sound.dataLength;

//         if (aliasPtr.toHex() == "ffffffff") {
//             // Read in sound alias name
//             char soundAliasChar;
//             *aZoneFileStream >> soundAliasChar;
//             while (soundAliasChar != 0) {
//                 sound.alias += soundAliasChar;
//                 *aZoneFileStream >> soundAliasChar;
//             }
//         }

//         if (aZoneFileStream->device()->peek(4) == "RIFF") {
//             sound.path = sound.alias;
//             sound.alias = "";
//         } else if (namePtr.toHex() == "ffffffff") {
//             // Read in sound file path
//             char soundPathChar;
//             *aZoneFileStream >> soundPathChar;
//             while (soundPathChar != 0) {
//                 sound.path += soundPathChar;
//                 *aZoneFileStream >> soundPathChar;
//             }
//             sound.path.replace(",", "");
//         }

//         if (sound.dataLength) {
//             QByteArray data(sound.dataLength, Qt::Uninitialized);
//             aZoneFileStream->readRawData(data.data(), sound.dataLength);
//             sound.data = data;
//         }
//         result.sounds.append(sound);
//     }

//     return result;
// }

// void ZoneFile_COD6_360::pParseAsset_ColMapMP(XDataStream *aZoneFileStream) {
//     Q_UNUSED(aZoneFileStream);
// }

// void ZoneFile_COD6_360::pParseAsset_GameMapSP(XDataStream *aZoneFileStream) {
//     Q_UNUSED(aZoneFileStream);
// }

// void ZoneFile_COD6_360::pParseAsset_GameMapMP(XDataStream *aZoneFileStream) {
//     Q_UNUSED(aZoneFileStream);
// }

// void ZoneFile_COD6_360::pParseAsset_LightDef(XDataStream *aZoneFileStream) {
//     Q_UNUSED(aZoneFileStream);
// }

// void ZoneFile_COD6_360::pParseAsset_UIMap(XDataStream *aZoneFileStream) {
//     Q_UNUSED(aZoneFileStream);
// }

// void ZoneFile_COD6_360::pParseASSET_TYPE_SOUNDDriver(XDataStream *aZoneFileStream) {
//     Q_UNUSED(aZoneFileStream);
// }

// void ZoneFile_COD6_360::pParseASSET_TYPE_AITYPE(XDataStream *aZoneFileStream) {
//     Q_UNUSED(aZoneFileStream);
// }

// void ZoneFile_COD6_360::pParseASSET_TYPE_FX(XDataStream *aZoneFileStream) {
//     Q_UNUSED(aZoneFileStream);
// }

// Animation ZoneFile_COD6_360::pParseASSET_TYPE_XANIMPARTS(XDataStream *aZoneFileStream) {
//     Animation result;

//     aZoneFileStream->skipRawData(4);

//     *aZoneFileStream
//         >> result.dataByteCount
//         >> result.dataShortCount
//         >> result.dataIntCount
//         >> result.randomDataByteCount
//         >> result.randomDataIntCount
//         >> result.numframes
//         >> result.isLooped
//         >> result.isDelta
//         >> result.noneRotatedBoneCount
//         >> result.twoDRotatedBoneCount
//         >> result.normalRotatedBoneCount
//         >> result.twoDRotatedBoneCount
//         >> result.normalRotatedBoneCount
//         >> result.normalTranslatedBoneCount
//         >> result.preciseTranslatedBoneCount
//         >> result.staticTranslatedBoneCount
//         >> result.noneTranslatedBoneCount
//         >> result.totalBoneCount
//         >> result.otherBoneCount1
//         >> result.otherBoneCount2
//         >> result.notifyCount
//         >> result.assetType
//         >> result.pad
//         >> result.randomDataShortCount
//         >> result.indexCount
//         >> result.frameRate
//         >> result.frequency
//         >> result.boneIDsPtr
//         >> result.dataBytePtr
//         >> result.dataShortPtr
//         >> result.dataIntPtr
//         >> result.randomDataShortPtr
//         >> result.randomDataBytePtr
//         >> result.randomDataIntPtr
//         >> result.longIndiciesPtr
//         >> result.notificationsPtr
//         >> result.deltaPartsPtr;

//     // Read in x_anim file name
//     QString xAnimName;
//     char xAnimNameChar;
//     *aZoneFileStream >> xAnimNameChar;
//     while (xAnimNameChar != 0) {
//         result.name += xAnimNameChar;
//         *aZoneFileStream >> xAnimNameChar;
//     }

//     // Parse x_anim index header
//     QVector<quint8> sectionLengths;
//     for (int i = 0; i < result.numframes; i++) {
//         quint8 sectionlength;
//         *aZoneFileStream >> sectionlength;
//         sectionLengths.push_back(sectionlength);
//         // Skip padding
//         aZoneFileStream->skipRawData(1);
//     }
//     // Skip unknown section
//     aZoneFileStream->skipRawData(2 * 8);

//     return result;
// }

// MenuDef ZoneFile_COD6_360::pParseASSET_TYPE_MENUDef(XDataStream *aZoneFileStream) {
//     //MENU_FILE
//     MenuDef result;

//     aZoneFileStream->skipRawData(4); // Separator

//     // Parse menu def count
//     *aZoneFileStream >> result.menuCount;

//     // Clearly misparsed, never have this much
//     if (result.menuCount > 1000) {
//         qDebug() << "Failure reported when parsing menu file.";
//         return result;
//     }
//     for (quint32 = 0; i < result.menuCount; i++) {
//         Menu menu;

//         aZoneFileStream->skipRawData(4); // Separator

//         // Read in x_anim file name
//         char MenuDefpathChar;
//         *aZoneFileStream >> MenuDefpathChar;
//         while (MenuDefpathChar != 0) {
//             menu.filePath += MenuDefpathChar;
//             *aZoneFileStream >> MenuDefpathChar;
//         }
//         aZoneFileStream->skipRawData(4); // Separator

//         *aZoneFileStream >> menu.menuNamePtr;

//         float menuRectX, menuRectY, menuRectWidth, menuRectHeight;
//         *aZoneFileStream >> menuRectX >> menuRectY >> menuRectWidth >> menuRectHeight;
//         menu.rect = QRectF(menuRectX, menuRectY, menuRectWidth, menuRectHeight);

//         quint32 hAlignInt, vAlignInt;
//         *aZoneFileStream >> hAlignInt >> vAlignInt;
//         menu.hAlign = (MENU_H_ALIGNMENT)hAlignInt;
//         menu.vAlign = (MENU_V_ALIGNMENT)vAlignInt;

//         float rectClientX, rectClientY, rectClientWidth, rectClientHeight;
//         *aZoneFileStream >> rectClientX >> rectClientY >> rectClientWidth >> rectClientHeight;
//         menu.clientRect = QRectF(rectClientX, rectClientY, rectClientWidth, rectClientHeight);

//         quint32 hClientAlignInt, vClientAlignInt, styleInt, borderInt;
//         *aZoneFileStream >> hClientAlignInt >> vClientAlignInt >> menu.groupPtr
//             >> styleInt >> borderInt >> menu.ownerDraw >> menu.ownerDrawFlags
//             >> menu.borderSize >> menu.staticFlags >> menu.dynamicFlags >> menu.nextTime;
//         menu.hClientAlign = (MENU_H_ALIGNMENT)hClientAlignInt;
//         menu.vClientAlign = (MENU_V_ALIGNMENT)vClientAlignInt;
//         menu.style = (MENU_WINDOW_STYLE)styleInt;
//         menu.border = (MENU_WINDOW_BORDER)borderInt;

//         float foregroundColorR, foregroundColorG, foregroundColorB, foregroundColorA,
//             backgroundColorR, backgroundColorG, backgroundColorB, backgroundColorA,
//             borderColorR, borderColorG, borderColorB, borderColorA,
//             outlineColorR, outlineColorG, outlineColorB, outlineColorA;
//         *aZoneFileStream >> foregroundColorR >> foregroundColorG >> foregroundColorB >> foregroundColorA
//             >> backgroundColorR >> backgroundColorG >> backgroundColorB >> backgroundColorA
//             >> borderColorR >> borderColorG >> borderColorB >> borderColorA
//             >> outlineColorR >> outlineColorG >> outlineColorB >> outlineColorA;

//         menu.foregroundColor = QColor(foregroundColorR, foregroundColorG, foregroundColorB, foregroundColorA);
//         menu.backgroundColor = QColor(backgroundColorR, backgroundColorG, backgroundColorB, backgroundColorA);
//         menu.borderColor = QColor(borderColorR, borderColorG, borderColorB, borderColorA);
//         menu.outlineColor = QColor(outlineColorR, outlineColorG, outlineColorB, outlineColorA);

//         *aZoneFileStream >> menu.materialPtr >> menu.fontPtr >> menu.fullScreen >> menu.itemCount
//             >> menu.fontIndex >> menu.cursorItem >> menu.fadeCycle >> menu.fadeClamp
//             >> menu.fadeAmount >> menu.fadeInAmount >> menu.blurRadius >> menu.onOpenPtr
//             >> menu.onFocusPtr >> menu.onClosePtr >> menu.onESCPtr >> menu.onKeyPtr
//             >> menu.visibleExpCount >> menu.expEntryPtr >> menu.allowedBindingPtr
//             >> menu.soundNamePtr >> menu.imageTrack;

//         float focusColorR, focusColorG, focusColorB, focusColorA,
//             disabledColorR, disabledColorG, disabledColorB, disabledColorA;
//         *aZoneFileStream >> focusColorR >> focusColorG >> focusColorB >> focusColorA
//             >> disabledColorR >> disabledColorG >> disabledColorB >> disabledColorA;
//         menu.focusColor = QColor(focusColorR, focusColorG, focusColorB, focusColorA);
//         menu.disabledColor = QColor(disabledColorR, disabledColorG, disabledColorB, disabledColorA);

//         *aZoneFileStream >> menu.rectXExpCount >> menu.rectXExpPtr >> menu.rectYExpCount >> menu.rectYExpPtr;

//         aZoneFileStream->skipRawData(4); // Separator

//         char menuDefNameChar;
//         int menuDefNameLen = 0;
//         *aZoneFileStream >> menuDefNameChar;
//         while (menuDefNameChar != 0 && menuDefNameLen < 30) {
//             menuDefNameLen++;
//             menu.name += menuDefNameChar;
//             *aZoneFileStream >> menuDefNameChar;
//         }

//         char defStringChar;
//         int defStringLen = 0;
//         *aZoneFileStream >> defStringChar;
//         while (defStringChar != 0 && defStringLen < 30) {
//             defStringLen++;
//             menu.definition += defStringChar;
//             *aZoneFileStream >> defStringChar;
//         }
//         aZoneFileStream->skipRawData(4 * 10);

//         *aZoneFileStream >> menu.itemWindowDefNamePtr;

//         float itemRectX, itemRectY, itemRectWidth, itemRectHeight;
//         *aZoneFileStream >> itemRectX >> itemRectY >> itemRectWidth >> itemRectHeight;
//         menu.itemRect = QRectF(itemRectX, itemRectY, itemRectWidth, itemRectHeight);

//         *aZoneFileStream >> menu.itemHAlignment >> menu.itemVAlignment >> menu.itemGroupPtr
//             >> menu.itemWindowStyle >> menu.itemWindowBorder >> menu.itemOwnerDraw
//             >> menu.itemOwnerDrawFlags >> menu.itemBorderSize >> menu.itemStaticFlags
//             >> menu.itemDynamicFlags >> menu.itemNextTime;

//         float itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA,
//             itemBackgroundColorR, itemBackgroundColorG, itemBackgroundColorB, itemBackgroundColorA,
//             itemBorderColorR, itemBorderColorG, itemBorderColorB, itemBorderColorA,
//             itemOutlineColorR, itemOutlineColorG, itemOutlineColorB, itemOutlineColorA;
//         *aZoneFileStream >> itemForegroundColorR >> itemForegroundColorG >> itemForegroundColorB >> itemForegroundColorA
//             >> itemBackgroundColorR >> itemBackgroundColorG >> itemBackgroundColorB >> itemBackgroundColorA
//             >> itemBorderColorR >> itemBorderColorG >> itemBorderColorB >> itemBorderColorA
//             >> itemOutlineColorR >> itemOutlineColorG >> itemOutlineColorB >> itemOutlineColorA;

//         menu.itemForegroundColor = QColor(itemForegroundColorR, itemForegroundColorG, itemForegroundColorB, itemForegroundColorA);
//         menu.itemBackgroundColor = QColor(itemBackgroundColorR, itemBackgroundColorG, itemBackgroundColorB, itemBackgroundColorA);
//         menu.itemBorderColor = QColor(itemBorderColorR, itemBorderColorG, itemBorderColorB, itemBorderColorA);
//         menu.itemOutlineColor = QColor(itemOutlineColorR, itemOutlineColorG, itemOutlineColorB, itemOutlineColorA);

//         *aZoneFileStream >> menu.itemMaterialPtr;

//         float itemTextRectX, itemTextRectY, itemTextRectWidth, itemTextRectHeight;
//         *aZoneFileStream >> itemTextRectX >> itemTextRectY >> itemTextRectWidth >> itemTextRectHeight;
//         menu.itemTextRect = QRectF(itemTextRectX, itemTextRectY, itemTextRectWidth, itemTextRectHeight);

//         quint32 hItemTextAlignInt, vItemTextAlignInt, itemType, fontTypeInt, textStyleInt;
//         *aZoneFileStream >> hItemTextAlignInt >> vItemTextAlignInt >> itemType >> menu.dataType
//             >> menu.alignment >> fontTypeInt >> menu.textAlignMode >> menu.textalignx >> menu.textaligny
//             >> menu.textscale >> textStyleInt >> menu.gameMsgWindowIndex >> menu.gameMsgWindowMode
//             >> menu.testPtr >> menu.textSavegameInfo >> menu.parentPtr;
//         menu.itemText_hAlign = (MENU_H_ALIGNMENT)hItemTextAlignInt;
//         menu.itemText_vAlign = (MENU_V_ALIGNMENT)vItemTextAlignInt;
//         menu.itemType = (MENU_ITEM_TYPE)itemType;
//         menu.fontEnum = (MENU_FONT_TYPE)fontTypeInt;
//         menu.textStyle = (MENU_ITEM_TEXTSTYLE)textStyleInt;

//         *aZoneFileStream >> menu.mouseEnterText >> menu.mouseExitText >> menu.mouseEnter >> menu.mouseExit
//             >> menu.action >> menu.onAccept >> menu.onFocus >> menu.leaveFocus >> menu.dvar >> menu.dvarTest
//             >> menu.keyHandlerPtr >> menu.enableDvarPtr >> menu.dvarFlags >> menu.focusSoundPtr
//             >> menu.special >> menu.cursorPos;

//         // itemDefData_t typeData;

//         // listBoxDef_s *listBox;

//         *aZoneFileStream >> menu.startPos >> menu.endPos >> menu.drawPadding;

//         *aZoneFileStream >> menu.elementWidth >> menu.elementHeight;

//         *aZoneFileStream >> menu.elementStyle >> menu.numColumns;

//         //columnInfo_s columnInfo[16];

//         *aZoneFileStream >> menu.doubleClickPtr;


//         *aZoneFileStream >> menu.notselectable >> menu.noScrollBars >> menu.usePaging;

//         float itemSelectBorderColorR, itemSelectBorderColorG, itemSelectBorderColorB, itemSelectBorderColorA,
//             itemDisableColorR, itemDisableColorG, itemDisableColorB, itemDisableColorA,
//             itemFocusColorR, itemFocusColorG, itemFocusColorB, itemFocusColorA;
//         *aZoneFileStream >> itemSelectBorderColorR >> itemSelectBorderColorG >> itemSelectBorderColorB >> itemSelectBorderColorA
//             >> itemDisableColorR >> itemDisableColorG >> itemDisableColorB >> itemDisableColorA
//             >> itemFocusColorR >> itemFocusColorG >> itemFocusColorB >> itemFocusColorA;
//         menu.itemSelectBorderColor = QColor(itemSelectBorderColorR, itemSelectBorderColorG, itemSelectBorderColorB, itemSelectBorderColorA);
//         menu.itemDisableColor = QColor(itemDisableColorR, itemDisableColorG, itemDisableColorB, itemDisableColorA);
//         menu.itemFocusColor = QColor(itemFocusColorR, itemFocusColorG, itemFocusColorB, itemFocusColorA);

//         *aZoneFileStream >> menu.selectIconPtr >> menu.backgroundItemListboxPtr >> menu.highlightTexturePtr;

//         // editFieldDef_s *editField;

//         *aZoneFileStream >> menu.minVal >> menu.maxVal >> menu.defVal >> menu.range >> menu.maxChars
//             >> menu.maxCharsGotoNext >> menu.maxPaintChars >> menu.paintOffset;

//         // multiDef_s *multi;

//         for (int i = 0; i < 32; i++) {
//             quint32 dvarList;
//             *aZoneFileStream >> dvarList;
//             menu.dvarListPtrs.push_back(dvarList);
//         }

//         for (int i = 0; i < 32; i++) {
//             quint32 dvarStr;
//             *aZoneFileStream >> dvarStr;
//             menu.dvarStrPtrs.push_back(dvarStr);
//         }

//         for (int i = 0; i < 32; i++) {
//             float dvarValue;
//             *aZoneFileStream >> dvarValue;
//             menu.dvarValues.push_back(dvarValue);
//         }

//         *aZoneFileStream >> menu.count >> menu.strDef >> menu.enumDvarNamePtr;
//         aZoneFileStream->skipRawData(4);
//         //>> menu.dataPtr
//         *aZoneFileStream >> menu.itemImageTrack;

//         qDebug() << aZoneFileStream->device()->pos();

//         //statement_s visibleExp;
//         //statement_s textExp;
//         //statement_s materialExp;
//         //statement_s rectXExp;
//         //statement_s rectYExp;
//         //statement_s rectWExp;
//         //statement_s rectHExp;
//         //statement_s foreColorAExp;
//         result.menuDefinitions << menu;
//     }
//     return result;
// }

// void ZoneFile_COD6_360::pParseASSET_TYPE_WEAPON(XDataStream *aZoneFileStream) {
//     //WEAPON_FILE
//     Q_UNUSED(aZoneFileStream);
// }

// void ZoneFile_COD6_360::pParseASSET_TYPE_D3DBSP(XDataStream *aZoneFileStream) {
//     //D3DBSP_DUMP
//     Q_UNUSED(aZoneFileStream);
// }

// StringTable ZoneFile_COD6_360::pParseASSET_TYPE_STRINGTABLE(XDataStream *aZoneFileStream) {
//     StringTable result;

//     aZoneFileStream->skipRawData(4);

//     *aZoneFileStream
//         >> result.columnCount
//         >> result.rowCount;

//     // Todo fix this
//     result.columnCount = 0;
//     result.rowCount = 0;

//     aZoneFileStream->skipRawData(4);

//     QString stringTableName;
//     char stringTableNameChar;
//     *aZoneFileStream >> stringTableNameChar;
//     while (stringTableNameChar != 0) {
//         result.name += stringTableNameChar;
//         *aZoneFileStream >> stringTableNameChar;
//     }

//     for (quint32 i = 0; i < result.rowCount; i++) {
//         QByteArray pointerData(4, Qt::Uninitialized);
//         aZoneFileStream->readRawData(pointerData.data(), 4);
//         result.tablePointers.push_back(pointerData.toHex());

//         aZoneFileStream->skipRawData(4);
//     }

//     for (const QString &pointerAddr : result.tablePointers) {
//         QString leadingContent = "";
//         if (pointerAddr == "FFFFFFFF") {
//             char leadingContentChar;
//             *aZoneFileStream >> leadingContentChar;
//             while (leadingContentChar != 0) {
//                 leadingContent += leadingContentChar;
//                 *aZoneFileStream >> leadingContentChar;
//             }
//         } else {
//             leadingContent = pointerAddr;
//         }

//         QString content;
//         char contentChar;
//         *aZoneFileStream >> contentChar;
//         while (contentChar != 0) {
//             content += contentChar;
//             *aZoneFileStream >> contentChar;
//         }
//         result.content[leadingContent] = content;
//     }
//     return result;
// }
