----------------------------------------------------------------
-- 文件名: LibLocale.lua
-- 日期: 2013-12-03
-- 描述: 本地化类库
-- 作者: 盒子哥
-- 特别感谢ace
----------------------------------------------------------------

local MAJOR, MINOR = "LibLocale", 1

local LibLocale, oldminor = LibStub:NewLibrary(MAJOR, MINOR)

-- Lua APIs
local assert, tostring, error = assert, tostring, error
local getmetatable, setmetatable, rawset, rawget = getmetatable, setmetatable, rawset, rawget

-- 假设我们的语言环境是zhCN, 国际化只需要添加这个接口
function GetLocale()
	return "zhCN"
end

local gameLocale = GetLocale()

LibLocale.apps = {}
LibLocale.appnames = {}

-- 未显式赋值报错模式
local readmeta = {
	__index = function(self, key) -- requesting totally unknown entries: fire off a nonbreaking error and return key
		rawset(self, key, key)      -- only need to see the warning once, really
		geterrorhandler()(MAJOR..": "..tostring(LibLocale.appnames[self])..": Missing entry for '"..tostring(key).."'")
		return key
	end
}

-- 未显式赋值不报错模式
local readmetasilent = {
	__index = function(self, key) -- requesting totally unknown entries: return key
		rawset(self, key, key)      -- only need to invoke this function once
		return key
	end
}

local registering
local assertfalse = function() assert(false) end

local writeproxy = setmetatable({}, {
	__newindex = function(self, key, value)
		rawset(registering, key, value == true and key or value) -- assigning values: replace 'true' with key string
	end,
	__index = assertfalse
})

local writedefaultproxy = setmetatable({}, {
	__newindex = function(self, key, value)
		if not rawget(registering, key) then
			rawset(registering, key, value == true and key or value)
		end
	end,
	__index = assertfalse
})

function LibLocale:NewLocale(application, locale, isDefault, silent)

	-- GAME_LOCALE allows translators to test translations of addons without having that wow client installed
	local app = LibLocale.apps[application]

	if silent and app and getmetatable(app) ~= readmetasilent then
		geterrorhandler()("Usage: NewLocale(application, locale[, isDefault[, silent]]): 'silent' must be specified for the first locale registered")
	end

	if not app then
		if silent=="raw" then
			app = {}
		else
			app = setmetatable({}, silent and readmetasilent or readmeta)
		end
		LibLocale.apps[application] = app
		LibLocale.appnames[app] = application
	end

	if locale ~= gameLocale and not isDefault then
		return -- nop, we don't need these translations
	end

	registering = app -- remember globally for writeproxy and writedefaultproxy

	if isDefault then
		return writedefaultproxy
	end

	return writeproxy
end

function LibLocale:GetLocale(application, silent)
	if not silent and not LibLocale.apps[application] then
		error("Usage: GetLocale(application[, silent]): 'application' - No locales registered for '"..tostring(application).."'", 2)
	end
	return LibLocale.apps[application]
end