#include "lotrodatmanager.h"
#include "filesystem.h"
#include "LotroDat/Subfiles/TextSubFile.h"

#include <QtConcurrent/QtConcurrent>
#include <QFontDatabase>
#include <QMessageBox>
#include <QDebug>

#include <string>
#include <iostream>
#include <fstream>

Q_DECLARE_METATYPE(LOTRO_DAT::FILE_TYPE)
Q_DECLARE_METATYPE(LOTRO_DAT::SubfileData)

LotroDatManager::LotroDatManager(QSettings* app_settings_, QObject *parent) :
    QObject(parent), app_settings(app_settings_) {

    qRegisterMetaType<LOTRO_DAT::FILE_TYPE>();
    qRegisterMetaType<LOTRO_DAT::SubfileData>();


}

void LotroDatManager::initialiseDatFile(QString file_path) {
    emit processStarted("initialiseDatFile", {file_path});

    qDebug() << "Initialising file " << file_path;

    if (!FileSystem::fileExists(file_path)) {
        emit caughtError(QString("initialiseDatFile"), {QString("Ошибка инициализации"), QString("Файл " + file_path + " несуществует! Невозможно инициализировать файл ресурсов.")});
        emit processFinished("initialiseDatFile", {QString("Error"), file_path});
        return;
    }

    file.Initialise((file_path).toStdString(), 0);
    emit processFinished("initialiseDatFile", {QString("Success"), file_path});
}

void LotroDatManager::deinitialiseDatFile()
{
    emit processStarted("deintialiseDatFile", {});
    qDebug() << "Deinitialising file...";
    file.Deinitialize();
    emit processFinished("deinitialiseDatFile", {});
}

void LotroDatManager::changeLocale() {
    qDebug() << "Changing locale of dat file...";
    // Setting locale, opposite to current
    auto current_locale = file.GetLocaleManager().GetCurrentLocale();
    auto new_locale = current_locale == LOTRO_DAT::DatLocaleManager::PATCHED ?
                LOTRO_DAT::DatLocaleManager::ORIGINAL :
                LOTRO_DAT::DatLocaleManager::PATCHED;

    QString old_locale_name = (current_locale == LOTRO_DAT::DatLocaleManager::PATCHED ? "Русифицированная" : "Оригинальная");
    QString new_locale_name = (new_locale == LOTRO_DAT::DatLocaleManager::PATCHED ? "Русифицированная" : "Оригинальная");
    emit processStarted("changeLocale", {old_locale_name, new_locale_name});


    auto operation = file.GetLocaleManager().SetLocale(new_locale);

    auto new_current_locale = file.GetLocaleManager().GetCurrentLocale();
    QString new_current_locale_name = (new_current_locale == LOTRO_DAT::DatLocaleManager::PATCHED ? "Русифицированная" : "Оригинальная");

    if (operation.result == LOTRO_DAT::SUCCESS) {
        emit processFinished("changeLocale", {"Success", new_current_locale_name});
    } else {
        emit caughtError("changeLocale", {"Ошибка смены локали!", QString("Не удалось сменить локаль игры! Текущая локаль: ") + new_current_locale_name});
        emit processFinished("changeLocale", {"Error", new_current_locale_name});
    }
}

void LotroDatManager::getLocaleFileContents(long long file_id, int locale) {
    emit processStarted("getLocaleFileContents", {file_id, locale});

    auto getfile_op = file.GetLocaleManager().GetLocaleFile(file_id, (LOTRO_DAT::DatLocaleManager::LOCALE)locale);

    if (!getfile_op.result && locale != LOTRO_DAT::DatLocaleManager::ORIGINAL) {
        emit caughtError("getLocaleFileContents", {"Файл не найден!", QString("Не удаётся найти файл с id ") + QString::number(file_id)});
        emit processFinished("getLocaleFileContents", {"Error"});
        return;
    }

    LOTRO_DAT::SubFile subfile = getfile_op.value;

    auto getrealfile_op = file.GetFileSystem().GetFile(file_id);
    if (!getrealfile_op.result) {
        emit caughtError("getLocaleFileContents", {"Файл не найден!", QString("Не удаётся найти в словаре файл с id ") + QString::number(file_id)});
        emit processFinished("getLocaleFileContents", {"Error"});
        return;
    }

    if (getrealfile_op.value->FileType() != LOTRO_DAT::TEXT) {
        emit caughtError("getLocaleFileContents", {"Некорректный формат!", QString("Получение данных локали доступно только для текстовых файлов!")});
        emit processFinished("getLocaleFileContents", {"Error"});
        return;
    }


    // If there's no locale file in ORIGINAL locale, but id is correct - then use it from
    // FileManager dictionary
    if (!getfile_op.result)
        subfile = *(getrealfile_op.value);

    LOTRO_DAT::TextSubFile text_subfile(subfile);

    auto getfiledata_op = file.GetFileSystem().GetFileData(subfile, 8);

    if (getfiledata_op.result == LOTRO_DAT::ERROR) {
        emit caughtError("getLocaleFileContents", {"Ошибка извлечения!", QString("Обнаружены некорректные данные файла в словаре! Файл ресурсов мог быть повреждён!\nid = ") + QString::number(file_id) + ", locale_id = " + QString::number(locale)});
        emit processFinished("getLocaleFileContents", {"Error"});
        return;
    }

    LOTRO_DAT::SubfileData result = text_subfile.PrepareForExport(getfiledata_op.value);
    emit localeFileContentsReceived(locale, result);
    emit processFinished("getLocaleFileContents", {"Success", file_id, locale});
}

void LotroDatManager::importFilesFromDatabase(QString database_path) {
    emit processStarted("importFilesFromDatabase", {database_path});

    if (!FileSystem::fileExists(database_path)) {
        emit caughtError(QString("importFilesFromDatabase"), {QString("Ошибка импорта!"), QString("Файл " + database_path + " не существует! Невозможно инициализировать базу данных!")});
        emit processFinished("importFilesFromDatabase", {QString("Error")});
        return;
    }

    LOTRO_DAT::Database db;
    if (!db.InitDatabase(database_path.toStdString())) {
        emit caughtError("importFilesFromDatabase", {QString("Ошибка импорта!"), QString("Внутренняя ошибка инициализации базы данных!")});
        emit processFinished("importFilesFromDatabase", {QString("Error")});
        return;
    }

    auto patch_operation = file.GetPatcher().PatchAllDatabase(&db);

    if (patch_operation.result == LOTRO_DAT::SUCCESS) {
        file.GetFileSystem().CommitDirectories();
        file.GetLocaleManager().CommitLocales();
        emit processFinished("importFilesFromDatabase", {QString("Success"), patch_operation.value});
    } else {
        emit processFinished("importFilesFromDatabase", {QString("Error"), 0});
    }
}

void LotroDatManager::importFile(long long file_id, QString file_path) {
    emit processStarted("importFile", {file_id, file_path});

    if (!FileSystem::fileExists(file_path)) {
        emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Файл ") + file_path + QString(" не существует!")});
        emit processFinished("importFile", {QString("Error")});
        return;
    }

    LOTRO_DAT::SubfileData data;

    data.options["fid"] = file_id;

    auto getfile_op = file.GetFileSystem().GetFile(file_id);
    if (getfile_op.result == LOTRO_DAT::ERROR) {
        emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Файл с id ") + QString::number(file_id) + QString(" не существует в ресурсах игры! Невозможно импортировать :/")});
        emit processFinished("importFile", {QString("Error")});
        return;
    }

    std::shared_ptr<LOTRO_DAT::SubFile> subfile = getfile_op.value;
    data.options["ext"] = subfile->Extension();
    data.options["cat"] = subfile->category;

    if (subfile->FileType() == LOTRO_DAT::TEXT) {
        std::basic_ifstream<char16_t> input_stream(file_path.toStdString(), std::ios::in);
        if (!input_stream.is_open()) {
            emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Текстовый файл ") + file_path + QString(" не удаётся открыть!")});
            emit processFinished("importFile", {QString("Error")});
            return;
        }

        std::basic_stringstream<char16_t>  strStream;
        strStream << input_stream.rdbuf();//read the file
        data.text_data = strStream.str();//str holds the content of the file

        input_stream.close();
    } else {
        QFile data_file(file_path);
        data_file.open(QIODevice::ReadOnly);

        if (!data_file.isOpen()) {
            emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Файл ") + file_path + QString(" не удаётся открыть!")});
            emit processFinished("importFile", {QString("Error")});
            return;
        }

        QByteArray contents = data_file.readAll();
        data.binary_data = LOTRO_DAT::BinaryData(contents.constData(), contents.size());
    }


    auto patchfile_op = file.GetPatcher().PatchFile(data);

    if (patchfile_op.result == LOTRO_DAT::SUCCESS) {
        file.GetFileSystem().CommitDirectories();
        file.GetLocaleManager().CommitLocales();
        emit processFinished("importFile", {QString("Success")});
    } else {
        emit caughtError("importFile", {QString("Ошибка импорта!"), QString("Возникла внутренняя ошибка применения патча. Импорт завершился с ошибкой")});
        emit processFinished("importFile", {QString("Error")});
    }
    return;
}

void LotroDatManager::importTextFragment(long long file_id, long long fragment_id,
                               QString fragment_contents, QString arguments) {
    emit processStarted("importTextFragment", {file_id, fragment_id});

    if (fragment_contents.contains("DO_NOT_TOUCH-1!")) {
        emit caughtError("importTextFragment", {"Ошибка формата!", QString("Текстовые данные содержат указатели на аргументы DO_NOT_TOUCH! с встроенным указанием порядка аргументов (как на сайте) Такого быть не должно! Пользуйтесь порядком перечисления аргументов внизу")});
        emit processFinished("importTextFragment", {"Error"});
        return;
    }

    auto getfile_op = file.GetFileSystem().GetFile(file_id);
    if (!getfile_op.result) {
        emit caughtError("importTextFragment", {"Файл не найден!", QString("Не удаётся найти в ресурсах файл с id ") + QString::number(file_id)});
        emit processFinished("importTextFragment", {"Error"});
        return;
    }

    auto subfile = getfile_op.value;

    auto getfiledata_op = file.GetFileSystem().GetFileData(*subfile, 8);

    if (getfile_op.result == LOTRO_DAT::ERROR) {
        emit caughtError("importTextFragment", {"Ошибка импорта!", QString("Обнаружены некорректные данные файла в словаре! Файл ресурсов мог быть повреждён!\nid = ") + QString::number(file_id)});
        emit processFinished("importTextFragment", {"Error"});
        return;
    }

    LOTRO_DAT::SubfileData data = subfile->PrepareForExport(getfiledata_op.value);
    if (data.Empty()) {
        emit caughtError("importTextFragment", {"Ошибка импорта!", QString("Не удалось подготовить файл к изменению фрагмента!\nid = ") + QString::number(file_id)});
        emit processFinished("importTextFragment", {"Error"});
        return;
    }

    unsigned beginning = data.text_data.find(QString::number(fragment_id).toStdU16String(), 0);
    if (beginning == std::u16string::npos) {
        emit caughtError("importTextFragment", {"Ошибка импорта!", QString("Не удалось найти фрагмент в файле!\nid = ") + QString::number(file_id) + "\nfragment_id = " + QString::number(fragment_id)});
        emit processFinished("importTextFragment", {"Error"});
        return;
    }

    unsigned ending = data.text_data.find(QString("|||").toStdU16String(), beginning);

    QString new_fragment = QString::number(fragment_id) + ":::" + arguments + ":::" + fragment_contents;
    std::u16string new_text =  data.text_data.substr(0, beginning) + new_fragment.toStdU16String() + data.text_data.substr(ending);
    data.text_data = new_text;

    auto patchfile_op = file.GetPatcher().PatchFile(data);

    if (patchfile_op.result == LOTRO_DAT::SUCCESS) {
        file.GetFileSystem().CommitDirectories();
        file.GetLocaleManager().CommitLocales();
        emit processFinished("importTextFragment", {QString("Success")});
    } else {
        emit caughtError("importTextFragment", {QString("Ошибка импорта!"), QString("Возникла внутренняя ошибка применения патча. Импорт завершился с ошибкой")});
        emit processFinished("importTextFragment", {QString("Error")});
    }
}

void LotroDatManager::getTextFragment(long long file_id, long long fragment_id) {
    emit processStarted("getTextFragment", {file_id, fragment_id});

    auto getfile_op = file.GetFileSystem().GetFile(file_id);
    if (!getfile_op.result) {
        emit caughtError("getTextFragment", {"Файл не найден!", QString("Не удаётся найти в ресурсах файл с id ") + QString::number(file_id)});
        emit processFinished("getTextFragment", {"Error"});
        return;
    }

    auto subfile = getfile_op.value;

    auto getfiledata_op = file.GetFileSystem().GetFileData(*subfile, 8);

    if (getfile_op.result == LOTRO_DAT::ERROR) {
        emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Обнаружены некорректные данные файла в словаре! Файл ресурсов мог быть повреждён!\nid = ") + QString::number(file_id)});
        emit processFinished("getTextFragment", {"Error"});
        return;
    }

    LOTRO_DAT::SubfileData data = subfile->PrepareForExport(getfiledata_op.value);
    if (data.Empty()) {
        emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Не удалось подготовить файл к изменению фрагмента!\nid = ") + QString::number(file_id)});
        emit processFinished("getTextFragment", {"Error"});
        return;
    }

    unsigned beginning = data.text_data.find(QString::number(fragment_id).toStdU16String(), 0);
    if (beginning == std::u16string::npos) {
        emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Не удалось найти фрагмент в файле!\nid = ") + QString::number(file_id) + "\nfragment_id = " + QString::number(fragment_id)});
        emit processFinished("getTextFragment", {"Error"});
        return;
    }

    unsigned ending = data.text_data.find(QString("|||").toStdU16String(), beginning);

    unsigned size = std::u16string::npos;

    if (ending != std::u16string::npos)
        size = ending - beginning;

    std::u16string str = data.text_data.substr(beginning, size);

    QStringList splitted_fragment = QString::fromStdU16String(str).split(":::");
    if (splitted_fragment.size() != 3) {
        emit caughtError("getTextFragment", {"Ошибка импорта!", QString("Получены некорректные данные фрагмента!\nДанные:") + QString::fromStdU16String(str)});
        emit processFinished("getTextFragment", {"Error"});
        return;
    }

    emit textFragmentReceived(splitted_fragment.at(1), splitted_fragment.at(2));
    emit processFinished("getTextFragment", {"Success"});
}

void LotroDatManager::createCoreStatusFile(QString output_filename) {
    emit processStarted("createCoreStatusFile", {output_filename});
    auto gatherinfo_op = file.GatherInformation(output_filename.toStdString());

    if (gatherinfo_op.result == LOTRO_DAT::SUCCESS) {
        emit processFinished("createCoreStatusFile", {"Success", output_filename});
    } else {
        emit caughtError("createCoreStatusFile", {"Ошибка сбора информации!", QString("Не удаётся создать файл информации ядра")});
        emit processFinished("createCoreStatusFile", {"Error", output_filename});
    }
}

void LotroDatManager::extractSingleFile(QString output_filename, long long file_id) {
    emit processStarted("extractSingleFile", {output_filename, file_id});
    auto extractfile_op = file.GetExporter().ExtractFileById(file_id, output_filename.toStdString());
    if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
        emit processFinished("extractSingleFile", {"Success", output_filename, file_id});
    } else {
        emit caughtError("extractSingleFile", {"Ошибка экспорта!", QString("Не удаётся экспортировать файл " + QString::number(file_id) + " в файл " + output_filename)});
        emit processFinished("extractSingleFile", {"Error", output_filename});
    }
}

void LotroDatManager::extractSingleFileToDatabase(QString database_path, long long file_id) {
    emit processStarted("extractSingleFileToDatabase", {database_path, file_id});
    LOTRO_DAT::Database db;
    if (!db.InitDatabase(database_path.toStdString())) {
        emit caughtError("extractSingleFileToDatabase", {"Ошибка экспорта!", QString("Не удаётся создать/открыть базу данных " + database_path)});
        emit processFinished("extractSingleFileToDatabase", {"Error", database_path});
        return;
    }

    auto extractfile_op = file.GetExporter().ExtractFileById(file_id, &db);

    if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
        emit processFinished("extractSingleFileToDatabase", {"Success", database_path, file_id});
    } else {
        emit caughtError("extractSingleFileToDatabase", {"Ошибка экспорта!", QString("Не удаётся экспортировать файл " + QString::number(file_id) + " в базу данных " + database_path)});
        emit processFinished("extractSingleFileToDatabase", {"Error", database_path});
    }
}

void LotroDatManager::extractGrouppedFiles(QString output_foldername, LOTRO_DAT::FILE_TYPE type) {
    emit processStarted("extractGrouppedFiles", {output_foldername, type});
    auto extractfile_op = file.GetExporter().ExtractAllFilesByType(type, output_foldername.toStdString());
    if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
        emit processFinished("extractGrouppedFiles", {"Success", output_foldername, type, extractfile_op.value});
    } else {
        emit caughtError("extractGrouppedFiles", {"Ошибка экспорта!", QString("Не удаётся экспортировать файлы с типом " + QString::number(type) + " в папку " + output_foldername)});
        emit processFinished("extractGrouppedFiles", {"Error", output_foldername, type, extractfile_op.value});
    }
}

void LotroDatManager::extractGrouppedFilesToDatabase(QString database_path, LOTRO_DAT::FILE_TYPE type) {
    emit processStarted(QString("extractGrouppedFilesToDatabase"), {database_path, type});
    LOTRO_DAT::Database db;
    if (!db.InitDatabase(database_path.toStdString())) {
        emit caughtError("extractGrouppedFilesToDatabase", {"Ошибка экспорта!", QString("Не удаётся создать/открыть базу данных " + database_path)});
        emit processFinished("extractGrouppedFilesToDatabase", {"Error", database_path});
        return;
    }

    auto extractfile_op = file.GetExporter().ExtractAllFilesByType(type, &db);
    if (extractfile_op.result == LOTRO_DAT::SUCCESS) {
        emit processFinished("extractGrouppedFilesToDatabase", {"Success", database_path, type, extractfile_op.value});
    } else {
        emit caughtError("extractGrouppedFilesToDatabase", {"Ошибка экспорта!", QString("Не удаётся экспортировать файлы с типом " + QString::number(type) + " в базу данных " + database_path)});
        emit processFinished("extractGrouppedFilesToDatabase", {"Error", database_path, extractfile_op.value});
    }
}

void LotroDatManager::getUnactiveCategories() {
    emit processStarted("getUnactiveCategories", {});

    const std::set<long long>& categories = file.GetLocaleManager().GetInactiveCategories();

    QStringList result;
    for (long long category : categories) {
        result.append(QString::number(category));
    }

    qDebug() << "Received category set: " << result;

    emit unactiveCategoriesReceived(result);
    emit processFinished("getUnactiveCategories", {"Success"});
}

void LotroDatManager::startGame() {
    emit processStarted("startGame", {});

    QStringList args;
    args << "-skiprawdownload" << "-nosplash";
    if (file.GetLocaleManager().GetCurrentLocale() == LOTRO_DAT::DatLocaleManager::PATCHED)
        args << "-disablePatch";

    file.Deinitialize();

    if(FileSystem::fileExists(QApplication::applicationDirPath() + "/user.ini")){
        QSettings login(QApplication::applicationDirPath() + "/user.ini", QSettings::IniFormat );
        login.beginGroup("Account");
        QString username = login.value("username", "").toString();
        QString password = login.value("password", "").toString();
        login.endGroup();
        args << "-username" << username << "-password" << password;
    }

    qDebug() << "Запускаем игру со следующими аргументами: " << args;

    QFile f(app_settings->value("Local", "folder").toString() + "/LotroLauncher.exe");
    QProcess process;

    if (FileSystem::fileExists(f.fileName())) {
        if(f.fileName().contains(" ")) f.setFileName("\"" + f.fileName() + "\"");
        process.startDetached(f.fileName(), args);
        process.waitForFinished(-1);
        emit processFinished("startGame", {});
    } else {
        emit caughtError("startGame", {"Ошибка запуска игры!", QString("Не удалось найти файл LotroLauncher в папке: ") + app_settings->value("Local", "folder").toString()});
        emit processFinished("startGame", {"Error"});
    }
}

void LotroDatManager::getLocaleFileInfo(long long file_id, int locale) {
    emit processStarted("getLocaleFileInfo", {file_id, locale});

    auto getfile_op = file.GetLocaleManager().GetLocaleFile(file_id, (LOTRO_DAT::DatLocaleManager::LOCALE)locale);

    // If there's no locale file, but requested locale is original - trying to return file from
    // FileSystem dictionary

    if (!getfile_op.result && locale != LOTRO_DAT::DatLocaleManager::ORIGINAL) {
        emit caughtError("getLocaleFileInfo", {"Файл не найден!", QString("Не удаётся найти в ресурсах файл с id ") + QString::number(file_id)});
        emit processFinished("getLocaleFileInfo", {"Error"});
        return;
    }

    LOTRO_DAT::SubFile subfile;
    if (getfile_op.result) {
        subfile = getfile_op.value;
    } else {
        auto getdictfile_op = file.GetFileSystem().GetFile(file_id);
        if (!getdictfile_op.result) {
            emit caughtError("getLocaleFileInfo", {"Файл не найден!", QString("Не удаётся найти в ресурсах файл с id ") + QString::number(file_id)});
            emit processFinished("getLocaleFileInfo", {"Error"});
            return;
        }

        subfile = *(getdictfile_op.value);
    }


    QString result = "Locale file info:\n "
                     "dictionary_offset: " + QString::number(subfile.dictionary_offset()) + "\n"
                     "unknown1: " + QString::number(subfile.unknown1()) + "\n"
                     "file_id: " + QString::number(subfile.file_id()) + "\n"
                     "file_offset: " + QString::number(subfile.file_offset()) + "\n"
                     "file_size: " + QString::number(subfile.file_size()) + "\n"
                     "timestamp: " + QString::number(subfile.timestamp()) + "\n"
                     "version: " + QString::number(subfile.version()) + "\n"
                     "block_size: " + QString::number(subfile.block_size()) + "\n"
                     "unknown2: " + QString::number(subfile.file_id()) + "\n"
                     "category: " + QString::number(subfile.category) + "\n";

    emit localeFileInfoReceived(locale, result);
    emit processFinished("getLocaleFileInfo", {"Success"});
}

void LotroDatManager::getFileInfo(long long file_id) {
    emit processStarted(QString("getFileInfo"), {file_id});

    auto getfile_op = file.GetFileSystem().GetFile(file_id);
    if (!getfile_op.result) {
        emit caughtError("getFileInfo", {"Файл не найден!", QString("Не удаётся найти файл с id ") + QString::number(file_id)});
        emit processFinished("getFileInfo", {"Error"});
        return;
    }

    LOTRO_DAT::SubFile subfile = *getfile_op.value;

    QString result = "Locale file info:\n "
                     "dictionary_offset: " + QString::number(subfile.dictionary_offset()) + "\n"
                     "unknown1: " + QString::number(subfile.unknown1()) + "\n"
                     "file_id: " + QString::number(subfile.file_id()) + "\n"
                     "file_offset: " + QString::number(subfile.file_offset()) + "\n"
                     "file_size: " + QString::number(subfile.file_size()) + "\n"
                     "timestamp: " + QString::number(subfile.timestamp()) + "\n"
                     "version: " + QString::number(subfile.version()) + "\n"
                     "block_size: " + QString::number(subfile.block_size()) + "\n"
                     "unknown2: " + QString::number(subfile.file_id()) + "\n";

    emit fileInfoReceived(result);
    emit processFinished("getFileInfo", {"Success"});
}

void LotroDatManager::disableCategory(long long category_id)
{
    emit processStarted(QString("disableCategory"), {category_id});
    file.GetLocaleManager().DisableCategory(category_id);
    file.GetLocaleManager().CommitLocales();
    file.GetFileSystem().CommitDirectories();
    getUnactiveCategories();
    emit processFinished("disableCategory", {"Success"});
}

void LotroDatManager::enableCategory(long long category_id)
{
    emit processStarted(QString("enableCategory"), {category_id});
    file.GetLocaleManager().EnableCategory(category_id);
    file.GetLocaleManager().CommitLocales();
    file.GetFileSystem().CommitDirectories();
    getUnactiveCategories();
    emit processFinished("enableCategory", {"Success"});
}

LOTRO_DAT::DatStatus *LotroDatManager::getStatusModule()
{
    return &file.GetStatusModule();
}

bool LotroDatManager::initialised() {
    return file.Initialized();
}

int LotroDatManager::currentLocale() {
    return file.GetLocaleManager().GetCurrentLocale();
}

bool LotroDatManager::notPatched() {
    return file.GetStatusModule().CheckIfNotPatched();
}
