--[[ * Copyright (c) 2011-2012 by Adam Hellberg. * * This file is part of Command. * * Command is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Command is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Command. If not, see <http://www.gnu.org/licenses/>. --]] -- NOTE: All error() calls use constant strings in english for debugging reasons. -- NOTE: return after error() shouldn't be needed. Consider remove. -- Upvalues local type = type local pairs = pairs local tostring = tostring local setmetatable = setmetatable local C = Command C.LocaleManager = { Settings = {}, Master = "enUS", -- Fallback locale Active = GetLocale(), Locales = {} } local LM = C.LocaleManager local function l_index(self, k) k = tostring(k):upper() master = LM:GetMaster() if self == master then -- Prevent recursion return ("%%%s%%"):format(k) end local val = master[k] if val then return val end end local s_meta = { __call = function(self, arg1, arg2, isPlr) if not arg1 and not arg2 then return nil end if arg2 then -- (locale, key) return self:GetLocale(arg1, isPlr)[tostring(arg2):upper()] end arg1 = tostring(arg1):upper() return self:GetActive()[arg1] end } -- Initialize LocaleManager function LM:Init() if self.Active == "enGB" then self.Active = "enUS" end setmetatable(self, s_meta) self:LoadSavedVars() end -- Load the saved variables function LM:LoadSavedVars() if type(C.Settings.LOCALE_MANAGER) ~= "table" then C.Settings.LOCALE_MANAGER = {} end self.Settings = C.Settings.LOCALE_MANAGER if type(self.Settings.LOCALE) ~= "string" then self.Settings.LOCALE = self.Active end if type(self.Settings.PLAYER_INDEPENDENT) ~= "boolean" then self.Settings.PLAYER_INDEPENDENT = true end end -- Register a new locale (might add a check against master to make sure no keys are missing) function LM:Register(locale, localeTable) if type(locale) ~= "string" or type(localeTable) ~= "table" then error("Invalid arguments for Register. Expected [string, table], got ["..type(locale)..", "..type(localeTable).."]!") return end locale = locale:lower() if self:LocaleLoaded(locale) then return end self.Locales[locale] = {} for k,v in pairs(localeTable) do if type(v) == "string" then self.Locales[locale][k] = v end end setmetatable(self.Locales[locale], {__index = l_index}) end -- Check if a locale has been loaded/registered function LM:LocaleLoaded(locale) locale = locale:lower() if self.Locales[locale] then return true end return false end -- Get the locale <locale> -- Will handle nonexistant locale -- However, if for some reason the client default or fallback locale is NOT loaded... -- ^NOTE^ Above should not happen, under any circumstance what-so-ever unless Locales table is modified. function LM:GetLocale(locale, isPlr) if isPlr and not self.Settings.PLAYER_INDEPENDENT then locale = self.Settings.LOCALE end locale = locale or self.Settings.LOCALE locale = locale:lower() if locale == "engb" then locale = "enus" end if not self:LocaleLoaded(locale) then if locale ~= self.Settings.LOCALE:lower() then -- Prevent infinite loop... return self:GetActive() elseif locale ~= self.Master:lower() then return self:GetMaster() else error("FATAL: GetLocale unable to resolve to working locale.") return nil end end return self.Locales[locale] end -- Returns client locale (or user setting if set) function LM:GetActive() return self:GetLocale(self.Settings.LOCALE) end -- Returns master (fallback) locale function LM:GetMaster() if not self:LocaleLoaded(self.Master) then error("FATAL! Master locale not loaded, AddOn cannot function!") return end return LM:GetLocale(self.Master) end -- Set the locale to use function LM:SetLocale(locale) if locale:lower() == "engb" then locale = "enUS" end if not self:LocaleLoaded(locale) then return false, "LOCALE_NOT_LOADED" end self.Settings.LOCALE = locale return "LOCALE_UPDATE", {self.Settings.LOCALE} end -- Reset locale to client default function LM:ResetLocale() return self:SetLocale(self.Active) end -- Set locale to master (fallback) locale function LM:UseMasterLocale() return self:SetLocale(self.Master) end function LM:SetPlayerIndependent(active) self.Settings.PLAYER_INDEPENDENT = active if self.Settings.PLAYER_INDEPENDENT then return "LOCALE_PI_ACTIVE" end return "LOCALE_PI_INACTIVE" end function LM:EnablePlayerIndependent() return self:SetPlayerIndependent(true) end function LM:DisablePlayerIndependent() return self:SetPlayerIndependent(false) end function LM:TogglePlayerIndependent() return self:SetPlayerIndependent(not self.Settings.PLAYER_INDEPENDENT) end