#pragma once
#include <map>
#include <mutex>
#include <string>
#include <string_view>
#include <vector>
#include <memory>
#include "Common/Common.h"
#include "Common/File/Path.h"
class I18NRepo;
class IniFile;
class Section;
enum class I18NCat : uint8_t {
AUDIO = 0,
CONTROLS,
CWCHEATS,
DESKTOPUI,
DEVELOPER,
DIALOG,
ERRORS,
GAME,
GRAPHICS,
INSTALLZIP,
KEYMAPPING,
MAINMENU,
MAINSETTINGS,
MAPPABLECONTROLS,
NETWORKING,
PAUSE,
POSTSHADERS,
PSPCREDITS,
MEMSTICK,
REMOTEISO,
REPORTING,
SAVEDATA,
SCREEN,
SEARCH,
STORE,
SYSINFO,
SYSTEM,
TEXTURESHADERS,
THEMES,
UI_ELEMENTS,
VR,
ACHIEVEMENTS,
PSPSETTINGS,
CATEGORY_COUNT,
NONE = CATEGORY_COUNT,
};
struct I18NEntry {
I18NEntry(std::string_view t) : text(t), readFlag(false) {}
I18NEntry() : readFlag(false) {}
std::string text;
bool readFlag;
};
class I18NCategory {
public:
I18NCategory() {}
explicit I18NCategory(const Section §ion);
std::string_view T(std::string_view key, std::string_view def = "");
const char *T_cstr(const char *key, const char *def = nullptr);
std::map<std::string, std::string> Missed() const;
const std::map<std::string, I18NEntry, std::less<>> &GetMap() { return map_; }
void ClearMissed() { missedKeyLog_.clear(); }
void Clear();
private:
I18NCategory(I18NRepo *repo, const char *name) {}
void SetMap(const std::map<std::string, std::string> &m);
std::map<std::string, I18NEntry, std::less<>> map_;
mutable std::mutex missedKeyLock_;
std::map<std::string, std::string> missedKeyLog_;
friend class I18NRepo;
};
class I18NRepo {
public:
I18NRepo();
bool IniExists(const std::string &languageID) const;
bool LoadIni(const std::string &languageID, const Path &overridePath = Path());
std::string LanguageID();
std::shared_ptr<I18NCategory> GetCategory(I18NCat category);
std::string_view T(I18NCat category, std::string_view key, std::string_view def = "") {
if (category == I18NCat::NONE)
return !def.empty() ? def : key;
return cats_[(size_t)category]->T(key, def);
}
const char *T_cstr(I18NCat category, const char *key, const char *def = nullptr) {
if (category == I18NCat::NONE)
return def ? def : key;
return cats_[(size_t)category]->T_cstr(key, def);
}
void LogMissingKeys() const;
private:
Path GetIniPath(const std::string &languageID) const;
void Clear();
mutable std::mutex catsLock_;
std::shared_ptr<I18NCategory> cats_[(size_t)I18NCat::CATEGORY_COUNT];
std::string languageID_;
};
extern I18NRepo g_i18nrepo;
std::shared_ptr<I18NCategory> GetI18NCategory(I18NCat cat);
inline std::string_view T(I18NCat category, std::string_view key, std::string_view def = "") {
return g_i18nrepo.T(category, key, def);
}
inline const char *T_cstr(I18NCat category, const char *key, const char *def = "") {
return g_i18nrepo.T_cstr(category, key, def);
}