#include "subfiles/ddssubfile.h"

#include "EasyLogging++/easylogging++.h"

namespace LOTRO_DAT {
namespace Subfiles {

SubfileData Subfile<DDS>::BuildForExport(const BinaryData &file_data) {
    if (file_data.Empty() || file_data.size() < 256) {
        return SubfileData();
    }

    BinaryData ddsData(file_data.size() - 24 + 128);
    for (int i = 0; i < 128; i++)
        ddsData[i] = 0;

    memcpy(ddsData.data() + 128, file_data.data() + 24, file_data.size() - 24);

    ddsData[0] = 0x44; // D
    ddsData[1] = 0x44; // D
    ddsData[2] = 0x53; // S
    ddsData[3] = 0x20;
    ddsData[4] = 0x7C;

    ddsData[8] = 7;
    ddsData[9] = 0x10;

    // width, height
    ddsData[12] = file_data[12];
    ddsData[13] = file_data[13];
    ddsData[14] = file_data[14];
    ddsData[15] = file_data[15];

    ddsData[16] = file_data[8];
    ddsData[17] = file_data[9];
    ddsData[18] = file_data[10];
    ddsData[19] = file_data[11];

    long long compression = file_data.ToNumber<4>(0x10);

    switch (compression) {
        case 20:        // 14 00 00 00 - 888 (R8G8B8)
            ddsData[0x4C] = 0x20;  // ?
            ddsData[0x50] = 0x40;  // compressed or not

            ddsData[0x58] = 0x18;  // bytes per pixel
            ddsData[0x5E] = 0xFF;
            ddsData[0x61] = 0xFF;
            ddsData[0x64] = 0xFF;
            break;
        case 21:        // 15 00 00 00 - 8888 (R8G8B8A8)
            ddsData[0x4C] = 0x20;  // ?
            ddsData[0x50] = 0x40;  // compressed or not

            ddsData[0x58] = 0x20;  // bytes per pixel
            ddsData[0x5E] = 0xFF;
            ddsData[0x61] = 0xFF;
            ddsData[0x64] = 0xFF;
            ddsData[0x6B] = 0xFF;
            break;
        case 28:        // 1C 00 00 00 - 332 (?)
            ddsData[0x4C] = 0x20;  // ?
            ddsData[0x50] = 0x40;  // compressed or not

            ddsData[0x58] = 0x08;  // bytes per pixel
            ddsData[0x5E] = 0xFF;
            ddsData[0x61] = 0xFF;
            ddsData[0x64] = 0xFF;
            break;
        case 827611204: // 44 58 54 31 - DXT1
            ddsData[76] = 32;
            ddsData[80] = 4;

            ddsData[84] = 68;
            ddsData[85] = 88;
            ddsData[86] = 84;
            ddsData[87] = 49;
            break;
        case 861165636: // 44 58 54 33 - DXT3
            ddsData[22] = 1;
            ddsData[76] = 32;
            ddsData[80] = 4;

            ddsData[84] = 68;
            ddsData[85] = 88;
            ddsData[86] = 84;
            ddsData[87] = 51;

            ddsData[108] = 8;
            ddsData[109] = 16;
            ddsData[110] = 64;
            break;
        case 894720068: // 44 58 54 35 - DXT5
            ddsData[10] = 8;
            ddsData[22] = 1;
            ddsData[28] = 1;
            ddsData[76] = 32;
            ddsData[80] = 4;

            ddsData[84] = 68;
            ddsData[85] = 88;
            ddsData[86] = 84;
            ddsData[87] = 53;

            ddsData[88] = 32;
            ddsData[94] = 255;
            ddsData[97] = 255;
            ddsData[100] = 255;
            ddsData[107] = 255;
            ddsData[109] = 16;
            break;
        default:
            LOG(ERROR) << "Unknown header format.";
            return SubfileData();
    }

    SubfileData result;
    result.binary_data = ddsData;
    result.options["ext"] = ".dds";
    return result;
}

BinaryData Subfile<DDS>::BuildForImport(const BinaryData &old_data, const SubfileData &data) {
    BinaryData file_size = BinaryData::FromNumber<4>(data.binary_data.size() - 128);
    return old_data.CutData(0, 20) + file_size + data.binary_data.CutData(128);
}

}; // namespace Subfiles
}; // namespace LOTRO_DAT