#include "subfile.h"

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

namespace LOTRO_DAT {

FILE_TYPE FileTypeFromString(std::string ext) {
  if (ext == ".txt")
    return TEXT;
  if (ext == ".jpg")
    return JPG;
  if (ext == ".dds")
    return DDS;
  if (ext == ".wav")
    return WAV;
  if (ext == ".ogg")
    return OGG;
  if (ext == ".fontbin")
    return FONT;
  return UNKNOWN;
}

FILE_TYPE FileTypeFromFileContents(int file_id, const BinaryData& file_data) {
    // Text check based on file_id
    if ((file_id >> 24) == 0x25)
        return TEXT;

    // Font check based on file_id
    if ((file_id >> 24) == 0x42)
        return FONT;

    // jpeg / dds check
    if ((file_id >> 24) == 0x41) {
        long long soi = file_data.ToNumber<2>(24);
        // long long marker = file_data.ToNumber<2>(26);

        //auto markerSize = header.ToNumber<short>(28);
        //auto four = header.ToNumber<int>(30);

        if (soi == 0xD8FF)
            return JPG;
        return DDS;
    }

    // Ogg and Wav check
    if (file_data[8] == 0x4F && file_data[9] == 0x67 && file_data[10] == 0x67 && file_data[11] == 0x53)
        return OGG;

    if (file_data[8] == 0x52 && file_data[9] == 0x49 && file_data[10] == 0x46 && file_data[11] == 0x46)
        return WAV;

    return UNKNOWN;
}

std::string StringFromFileType(FILE_TYPE type) {
    if (type == TEXT)
        return ".txt";
    if (type == JPG)
        return ".jpg";
    if (type == DDS)
        return ".dds";
    if (type == WAV)
        return ".wav";
    if (type == OGG)
        return ".ogg";
    if (type == FONT)
        return ".fontbin";
    return ".subfile";
}

BinaryData BuildForImport(const BinaryData& old_data, const SubfileData& outer_data) {
    if (!outer_data.options["ext"]) {
        LOG(WARNING) << "No extension established for file with id " << outer_data.options["fid"].as<std::string>();
        return BinaryData();
    }

    FILE_TYPE type = FileTypeFromString(outer_data.options["ext"].as<std::string>());
    switch (type)
    {
    case TEXT:
        return Subfiles::Subfile<TEXT>::BuildForImport(old_data, outer_data);
    case JPG:
        return Subfiles::Subfile<JPG>::BuildForImport(old_data, outer_data);
    case DDS:
        return Subfiles::Subfile<DDS>::BuildForImport(old_data, outer_data);
    case WAV:
        return Subfiles::Subfile<WAV>::BuildForImport(old_data, outer_data);
    case OGG:
        return Subfiles::Subfile<OGG>::BuildForImport(old_data, outer_data);
    case FONT:
        return Subfiles::Subfile<FONT>::BuildForImport(old_data, outer_data);
    default:
        return Subfiles::Subfile<UNKNOWN>::BuildForImport(old_data, outer_data);
    }
}

SubfileData BuildForExport(int file_id, const BinaryData& inner_data) {
    FILE_TYPE type = FileTypeFromFileContents(file_id, inner_data);
    SubfileData result;
    switch (type)
    {
    case TEXT:
        result = Subfiles::Subfile<TEXT>::BuildForExport(inner_data);
        break;
    case JPG:
        result = Subfiles::Subfile<JPG>::BuildForExport(inner_data);
        break;
    case DDS:
        result = Subfiles::Subfile<DDS>::BuildForExport(inner_data);
        break;
    case WAV:
        result = Subfiles::Subfile<WAV>::BuildForExport(inner_data);
        break;
    case OGG:
        result = Subfiles::Subfile<OGG>::BuildForExport(inner_data);
        break;
    case FONT:
        result = Subfiles::Subfile<FONT>::BuildForExport(inner_data);
        break;
    default:
        result = Subfiles::Subfile<UNKNOWN>::BuildForExport(inner_data);
    }
    result.options["fid"] = file_id;
    return result;
}

}; // namespace LOTRO_DAT