GLOBAL.require "fonts_cn_assets"
GLOBAL.require "fonts_cn_chars"
PrefabFiles = {
    "fonts_cn"
}
Assets = {}
for _,font in ipairs( GLOBAL.FONTS_CN_ASSETS ) do
    table.insert(Assets, Asset("FONT", MODROOT..font.filename))
    table.insert(GLOBAL.FONTS, {filename = MODROOT..font.filename, alias = font.alias})
end

ENCODE = nil
if "中" == "\228\184\173" then
    ENCODE = "UTF-8"
elseif "中" == "\214\208" then
    ENCODE = "GBK"
end

local lang = GetModConfigData("MOD_LANGUAGE") or "chs_lmu"
local fontsizescale = GetModConfigData("MOD_FONT_SCALE") or 0.7

origInitializeModInfo = GLOBAL.KnownModIndex.InitializeModInfo
GLOBAL.KnownModIndex.InitializeModInfo = function(self,_modname)
    local info = origInitializeModInfo(self,_modname)
    if _modname == modname then
        lang = GLOBAL.LanguageTranslator.defaultlang or lang
        if lang == "chs" or lang == "chs_lmu" then
            STRINGS_LANGUAGE = "语言"
            STRINGS_LANGUAGE_CHS_LMU = "LMU简体中文"
            STRINGS_LANGUAGE_CHS = "简体中文"
            STRINGS_LANGUAGE_CHT = "繁體中文"
            STRINGS_LANGUAGE_NONE = "不加载"
            STRINGS_FONT_SIZE = "字体大小"
            STRINGS_DESCRIPTION = "中文支持Mod，语言切换在配置中\n系统编码为"
        elseif lang == "cht" then
            STRINGS_LANGUAGE = "語言"
            STRINGS_LANGUAGE_CHS_LMU = "LMU简体中文"
            STRINGS_LANGUAGE_CHS = "简体中文"
            STRINGS_LANGUAGE_CHT = "繁體中文"
            STRINGS_LANGUAGE_NONE = "不加載"
            STRINGS_FONT_SIZE = "字體大小"
            STRINGS_DESCRIPTION = "中文支持Mod，語言切換在配置中\n系統編碼為"
        else
            STRINGS_LANGUAGE = "Language"
            STRINGS_LANGUAGE_CHS_LMU = "LMU简体中文"
            STRINGS_LANGUAGE_CHS = "简体中文"
            STRINGS_LANGUAGE_CHT = "繁體中文"
            STRINGS_LANGUAGE_NONE = "Don't Load"
            STRINGS_FONT_SIZE = "Font Size"
            STRINGS_DESCRIPTION = "Chinese Support Mod,\nSystem encode is"
        end
        if "中" == "\228\184\173" then
            STRINGS_DESCRIPTION = STRINGS_DESCRIPTION .. "UTF-8"
        elseif "中" == "\214\208" then
            STRINGS_DESCRIPTION = STRINGS_DESCRIPTION .. "GBK"
        else
            STRINGS_DESCRIPTION = STRINGS_DESCRIPTION .. "Unknown"
        end
        info.configuration_options = {
            {
                name = "MOD_LANGUAGE",
                label = STRINGS_LANGUAGE,
                options = {
                    {description = STRINGS_LANGUAGE_CHS_LMU, data = "chs_lmu"},
                    {description = STRINGS_LANGUAGE_CHS, data = "chs"},
                    {description = STRINGS_LANGUAGE_CHT, data = "cht"},
                    {description = STRINGS_LANGUAGE_NONE, data = "none"},
                },
                default = "chs_lmu",
                hover = ""
            },
            {
                name = "MOD_FONT_SCALE",
                label = STRINGS_FONT_SIZE,
                options =   {
                                {description = "0.3x", data = 0.3},
                                {description = "0.4x", data = 0.4},
                                {description = "0.5x", data = 0.5},
                                {description = "0.6x", data = 0.6},
                                {description = "0.7x", data = 0.7},
                                {description = "0.8x", data = 0.8},
                                {description = "0.9x", data = 0.9},
                                {description = "1x", data = 1},
                                {description = "1.1x", data = 1.1},
                                {description = "1.2x", data = 1.2},
                                {description = "1.3x", data = 1.3},
                                {description = "1.4x", data = 1.4},
                                {description = "1.5x", data = 1.5},
                                {description = "1.6x", data = 1.6},
                                {description = "1.7x", data = 1.7},
                            },
                default = 0.7,
                hover = ""
            },
        }
        info.description = STRINGS_DESCRIPTION
    end
    return info
end

local function isUTF8(str)
    local i = 1
    local count = 0
    while i <= #str do
        local char = str:byte(i)
        local charLen
        if char < 193 then
            charLen = 1
        elseif char < 225 then
            charLen = 2
        elseif char < 241 then
            charLen = 3
        else
            charLen = 1
        end
        if i-1 > #str then
            return 0
        end
        if GLOBAL.FONTS_CN_CHARS[str:sub(i,i+charLen-1)] then
            count = count + 1
        end
        i = i + charLen
    end
    return count
end

local function isGBK(str)
    local i = 1
    local newLine = true
    local count = 0
    while i <= #str do
        local char = str:byte(i)
        local charLen
        if char < 128 then
            charLen = 1
        elseif char < 151 then
            if i < #str or not newLine or GLOBAL.FONTS_CN_CHARS[str:sub(i,i+1)] then
                charLen = 2
            else
                charLen = 1
            end
        elseif char > 150 and char < 255 then
            if i+1 > #str then
                return 0
            end
            local char2 = str:byte(i+1)
            if char2 > 63 and char2 < 255 then
                charLen = 2
            else
                return 0
            end
        else
            return 0
        end
        if char == 10 then
            newLine = true
        else
            newLine = false
        end
        if GLOBAL.FONTS_CN_CHARS[str:sub(i,i+charLen-1)] then
            count = count + 1
        end
        i = i + charLen
    end
    return count
end

local function calculateFontSize(fontsize)
    local result = 0
    local maxSize = 0
    for _,FONTS_SIZE in ipairs(GLOBAL.FONTS_CN_SIZES) do
        if math.abs(FONTS_SIZE-fontsize) < 3 then
            return FONTS_SIZE
        end

        if result == 0 and fontsize < FONTS_SIZE then
            result = FONTS_SIZE
        end

        if fontsize < FONTS_SIZE and result > FONTS_SIZE then
            result = FONTS_SIZE
        end

        if maxSize < FONTS_SIZE then
            maxSize = FONTS_SIZE
        end
    end
    if result == 0 then
        result = maxSize
    end
    return result
end

local function parseString(str, encode)
    if type(str) ~= "string" then
        str = ""
    end
    local i = 1
    local fontCharsTable = {}
    fontCharsTable["empty"] = {}
    local isGBK = isGBK(str)
    local isUTF8 = isUTF8(str)
    if isGBK > 5 or isUTF8 > 5 then
        if isGBK > isUTF8 then
            encode = "GBK"
        else
            encode = "UTF-8"
        end
    end
    local newLine = true
    while i <= #str do
        local char = str:byte(i)
        local charLen
        if (encode or ENCODE) == "UTF-8" then
            if char < 193 then
                charLen = 1
            elseif char < 225 then
                charLen = 2
            elseif char < 241 then
                charLen = 3
            else
                charLen = 1
            end
        else
            if char < 128 then
                charLen = 1
            elseif char < 151 then
                if i == #str then
                    charLen = 1
                else
                    if not newLine or GLOBAL.FONTS_CN_CHARS[str:sub(i,i+1)] then
                        charLen = 2
                    else
                        charLen = 1
                    end
                end
            else
                charLen = 2
            end
        end
        if char == 10 then
            newLine = true
        else
            newLine = false
        end
        local charFontName
        local emptyChar = 2
        if charLen == 1 then
            emptyChar = 1
            if char < 19 and char > 2 then
                emptyChar = char
            end
        end
        local utf8char = str:sub(i, i+charLen-1)
        local utf8charInfo = GLOBAL.FONTS_CN_CHARS[utf8char]
        if utf8charInfo then
            charFontName = utf8charInfo.fontName
            charIndex = utf8charInfo.charIndex
        else
            charFontName = "empty"
            charIndex = emptyChar
        end
        if charLen == 1 and (char > 126 and char < 151) or char == 254 or char == 255 then
            emptyChar = char
            charIndex = char
        end
        if not fontCharsTable[charFontName] then
            fontCharsTable[charFontName] = {GLOBAL.unpack(fontCharsTable["empty"])}
        end
        for fontName, fontChars in pairs(fontCharsTable) do
            if fontName == charFontName then
                table.insert(fontChars, charIndex)
                if charIndex == 32 then
                    table.insert(fontChars, 1)
                else
                    if charLen > 1 then
                        table.insert(fontChars, 32)
                    end
                end
            else
                if charIndex == 32 then
                    table.insert(fontChars, 32)
                end
                table.insert(fontChars, emptyChar)
                if emptyChar == 2 then
                    table.insert(fontChars, 32)
                end
            end
        end
        i=i+charLen
    end
    if fontCharsTable['font_en'] == nil then
        fontCharsTable['font_en'] = fontCharsTable['empty']
    end
    fontCharsTable['empty']=nil
    return fontCharsTable
end

local Text = GLOBAL.require "widgets/text"
local textFn = function(self, font, size, text)
    self.font = font.."_50"
    self.fontsize = size
    local origSetColour = self.SetColour
    self.SetColour = function(self, r,g,b,a)
        if type(r) == "number" then
            self.color = {r,g,b,a}
        else
            self.color = {r[1], r[2], r[3], r[4]}
        end
        origSetColour(self, self.color[1], self.color[2], self.color[3], self.color[4])
        if self.cnTextWidgets then
            for fontName, cnTextWidget in pairs(self.cnTextWidgets) do
                cnTextWidget.inst.TextWidget:SetColour(self.color[1], self.color[2], self.color[3], self.color[4])
            end
        end
    end
    local origSetHorizontalSqueeze = self.SetHorizontalSqueeze
    self.SetHorizontalSqueeze = function(self, squeeze)
        self.squeeze = squeeze
        origSetHorizontalSqueeze(self, squeeze)
        if self.cnTextWidgets then
            for fontName, cnTextWidget in pairs(self.cnTextWidgets) do
                cnTextWidget.inst.TextWidget:SetHorizontalSqueeze(squeeze)
            end
        end
    end
    local origSetAlpha = self.SetAlpha
    self.SetAlpha = function(self, a)
        self.alpha = a
        origSetAlpha(self, a)
        if self.cnTextWidgets then
            for fontName, cnTextWidget in pairs(self.cnTextWidgets) do
                cnTextWidget.inst.TextWidget:SetColour(1,1,1, a)
            end
        end
    end
    local origSetRegionSize = self.SetRegionSize
    self.SetRegionSize = function(self, w, h)
        self.regionSize = {w, h}
        origSetRegionSize(self, w, h)
        if self.cnTextWidgets then
            for fontName, cnTextWidget in pairs(self.cnTextWidgets) do
                cnTextWidget.inst.TextWidget:SetRegionSize(w, h)
            end
        end
    end
    self.SetFont = function(self, font)
        self.font = font
    end
    local origSetSize = self.SetSize
    self.SetSize = function(self, fontsize)
        self.fontsize = fontsize
        origSetSize(self, fontsize * fontsizescale)
        if self.cnTextWidgets then
            for fontName, cnTextWidget in pairs(self.cnTextWidgets) do
                cnTextWidget.inst.TextWidget:SetSize(fontsize * fontsizescale)
            end
        end
    end
    local origSetString = self.SetString
    self.SetString = function(self, str)
        if str == nil then
            str = ""
        end
        self.string = str
        if not self.cnTextWidgets then
            self.cnTextWidgets = {}
        end
        local fontCharsTable = parseString(str)
        self.inst.TextWidget:SetFont("font_en_"..calculateFontSize(self.fontsize))
        self.inst.TextWidget:SetSize(self.fontsize * fontsizescale)
        if fontCharsTable["font_en"] then
            self.inst.TextWidget:SetString(string.char(GLOBAL.unpack(fontCharsTable["font_en"])))
            fontCharsTable["font_en"] = nil
        else
            self.inst.TextWidget:SetString("")
        end
        if self.cnTextWidgets then
            for fontName, cnTextWidget in pairs(self.cnTextWidgets) do
                cnTextWidget.inst.TextWidget:SetString("")
            end
        end
        local onlyEn = true
        for fontName, fontChars in pairs(fontCharsTable) do
            onlyEn = false
            if not self.cnTextWidgets[fontName] then
                self.cnTextWidgets[fontName] = self:AddChild(Text(fontName.."_"..calculateFontSize(self.fontsize), self.fontsize * fontsizescale))
                if self.color then
                    self.cnTextWidgets[fontName].inst.TextWidget:SetColour(self.color[1], self.color[2], self.color[3], self.color[4])
                end
                if self.squeeze then
                    self.cnTextWidgets[fontName].inst.TextWidget:SetHorizontalSqueeze(self.squeeze)
                end
                if self.alpha then
                    self.cnTextWidgets[fontName].inst.TextWidget:SetColour(1,1,1, self.alpha)
                end
                if self.regionSize then
                    self.cnTextWidgets[fontName].inst.TextWidget:SetRegionSize(self.regionSize[1], self.regionSize[2])
                end
                if self.vAlign then
                    self.cnTextWidgets[fontName].inst.TextWidget:SetVAnchor(self.vAlign)
                end
                if self.hAlign then
                    self.cnTextWidgets[fontName].inst.TextWidget:SetHAnchor(self.hAlign)
                end
                if self.enableWordWrap then
                    self.cnTextWidgets[fontName].inst.TextWidget:EnableWordWrap(self.enableWordWrap)
                end
            end
            self.cnTextWidgets[fontName].inst.TextWidget:SetString(string.char(GLOBAL.unpack(fontChars)))
        end
        -- if onlyEn then
        --     self.inst.TextWidget:SetFont(self.font)
        --     self.inst.TextWidget:SetSize(self.fontsize)
        --     self.inst.TextWidget:SetString(str)
        -- end
    end
    origSetVAlign = self.SetVAlign
    self.SetVAlign = function(self, anchor)
        self.vAlign = anchor
        origSetVAlign(self, anchor)
        if self.cnTextWidgets then
            for fontName, cnTextWidget in pairs(self.cnTextWidgets) do
                cnTextWidget.inst.TextWidget:SetVAnchor(anchor)
            end
        end
    end
    origSetHAlign = self.SetHAlign
    self.SetHAlign = function(self, anchor)
        self.hAlign = anchor
        origSetHAlign(self, anchor)
        if self.cnTextWidgets then
            for fontName, cnTextWidget in pairs(self.cnTextWidgets) do
                cnTextWidget.inst.TextWidget:SetHAnchor(anchor)
            end
        end
    end
    origEnableWordWrap = self.EnableWordWrap
    self.EnableWordWrap = function(self, enable)
        self.enableWordWrap = enable
        origEnableWordWrap(self, enable)
        if self.cnTextWidgets then
            for fontName, cnTextWidget in pairs(self.cnTextWidgets) do
                cnTextWidget.inst.TextWidget:EnableWordWrap(enable)
            end
        end
    end
    if text then
        self:SetString(text)
    end
end
AddClassPostConstruct("widgets/text", textFn)

if lang == "chs_lmu" then
    if GLOBAL.IsDLCEnabled(GLOBAL.CAPY_DLC) then
        LoadPOFile("LMU_DS_sw.po", "chs")
    elseif GLOBAL.IsDLCEnabled(GLOBAL.REIGN_OF_GIANTS) then
        LoadPOFile("LMU_DS_rog.po", "chs")
    else
        LoadPOFile("LMU_DS.po", "chs")
    end
elseif lang == "chs" then
    LoadPOFile("chs.po", "chs")
elseif lang == "cht" then
    LoadPOFile("cht.po", "cht")
end
