require('strict')

local getArgs = require('Module:Arguments').getArgs
local yesno = require('Module:Yesno')
local lc = require('Module:WikitextLC')
local regions = mw.loadData('Module:Vgname/languages')

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

-- 中文變种列表
local variants = {
  {'cn'; simp = '中国大陆', trad = '中國大陸'; script = 'hans' },
  {'hk'; simp = '香港',     trad = '香港';     script = 'hant' },
  {'mo'; simp = '澳门',     trad = '澳門';     script = 'hant' },
  {'my'; simp = '马来西亚', trad = '馬來西亞'; script = 'hans' },
  {'sg'; simp = '新加坡',   trad = '新加坡';   script = 'hans' },
  {'tw'; simp = '台湾',     trad = '臺灣';     script = 'hant' },
}

-- 分割文字和<ref>標籤(泛用)
local function splitRef(str)
  local refPattern = '\127\'"`UNIQ%-%-[Rr][Ee][Ff]%-%x+%-QINU`"\'\127' -- [[:w:en:WP:UNIQ]]
  local text, ref = '', ''
  str = str or ''
  
  local s, _ = str:find(refPattern)
  if s then
    text, ref = str:sub(1, s-1), str:sub(s)
  else
    text = str
  end

  return text, ref
end

-- 加粗(用于标题组、各译名组)
local function boldText(args, str)
  local isBold = true
  str = str or ''

  if yesno(args.bold) == false then
    isBold = false
  end

  if isBold == true then
    str = "'''" .. str .. "'''"
  end
  
  return str
end

-- 文字套書名號或引號(用于标题组、各译名组)
local function bracketText(args, str, prefix, suffix)
  local bracketType = (args.bracketType == nil) and "" or args.bracketType
  
  if prefix and suffix then
    -- nothing to do
  elseif mw.ustring.lower(bracketType) == 'q' then -- 'q'爲了引號(quotation marks)
    prefix, suffix = '「', '」'
  elseif mw.ustring.lower(bracketType) == 's' then -- 's'爲了單書名號(single book title marks)
    prefix, suffix = '〈', '〉'
  elseif yesno(bracketType) == false then
    prefix, suffix = '', ''
  else
    prefix, suffix = "《", "》"
  end
  
  return prefix .. str .. suffix
end

-- 判定外语标签模式(用于原文名组、英文名组)
local function getLanguageLabelMode(args)
  local mode = 'same'
  
  if yesno(args.label) == true then
    mode = 'none'
  elseif yesno(args.diff) == true then
    mode = 'diff'
  elseif args.na or args.eu or args.au then
    mode = 'diff'
  end
  
  return mode
end

-- 斜体(用于原文名组、英文名组)
local function italicText(args, str, languageUsesItalic)
  local isItalic = false
  str = str or ''
  
  if yesno(args.italic) == false then
    isItalic = false
  elseif yesno(languageUsesItalic) == true then
    isItalic = true
  end
  
  if isItalic == true then
    str = "''" .. str .. "''"
  end
  
  return str
end

-- 语言变种继承(用于主译名组)
local variantsFallback = {
  ['cn'] = { 'sg', 'my' },
  ['hk'] = { 'mo', 'tw' },
  ['mo'] = { 'hk', 'tw' },
  ['my'] = { 'sg', 'cn' },
  ['sg'] = { 'my', 'cn' },
  ['tw'] = { 'hk', 'mo' },
}

-- 居然還要自己寫函式處理。。。
local function isInArray(t, val)
  for _, v in pairs(t) do
    if val == v then
      return true
    end
  end
end
  

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

-- 标题组
local function title(args)
  local title, ref = splitRef(args[1])
  
  title = boldText(args, title)
  title = bracketText(args, title, args["bracket-left"], args["bracket-right"])
  
  return title .. ref
end

-- 原文名组
local function original(args)
  local returnStr = ''
  local title, ref, titleLatin, refLatin = '', '', '', ''
  local language
  
  -- 检查原文名字段
  for _, v in ipairs(regions) do
    if args[v.langcode] then
      language = v
      break
    end
  end
  
  -- 若没有检测到原文名参数,则函数返回空字串
  if language then
    local t = mw.text.split(args[language.langcode], ',')
    title, ref = splitRef(t[1])
    titleLatin, refLatin = splitRef(t[2])
  else
    return ''
  end
  
  -- 加入原文名标签
  
  if getLanguageLabelMode(args) ~= 'none' then
    returnStr = language[getLanguageLabelMode(args)] .. ':'
  end
  
  -- 加入原文名及脚注
  title = mw.ustring.format('<span lang="%s"%s>-{%s}-</span>',
        language.langcode,
        (language.dir) == 'rtl' and ' dir="rtl"' or '',
        italicText(args, title, language.italic)
      )
  returnStr = returnStr .. title .. ref
  
  -- 加入原文名的拉丁字母写法及脚注(多用于日韩文游戏)
  if titleLatin ~= '' then
    titleLatin = mw.ustring.format('<span lang="%s">-{%s}-</span>', language.langcode, titleLatin)
    returnStr = returnStr .. ',' .. titleLatin .. refLatin
  end
  
  -- 此两参数用于除错,不在模板说明文档中介绍
  if args['original-before'] then
    returnStr = args['original-before'] .. returnStr
  end
  
  if args['original-after'] then
    returnStr = returnStr .. args['original-after']
  end 
  
  -- 告一段落
  return returnStr
end


-- 英文名组
local function englishes(args)
  local returnStr = ''
  
  -- 处理北美、欧洲、澳洲版名
  -- 澳洲版(au)名为除错用,不在模板说明文档中介绍
  for _, v in ipairs{'na', 'eu', 'au'} do
    if args[v] then
      returnStr = (returnStr == '') and '' or (returnStr .. ',')
      local title, ref = splitRef(args[v])
      
      if getLanguageLabelMode(args) ~= 'none' then
        returnStr = returnStr .. regions[v][getLanguageLabelMode(args)] .. ':'
      end
      
      title = mw.ustring.format('<span lang="%s"%s>-{%s}-</span>',
        regions[v].langcode,
        (regions[v].dir) == 'rtl' and ' dir="rtl"' or '',
        italicText(args, title, regions[v].italic)
      )
      
      returnStr = returnStr .. title .. ref
    end
  end
  
  -- 如果没有填北美、欧洲、澳洲版名……
  if (returnStr == '') and (args.en) then
    local title, ref = splitRef(args.en)
    
    if getLanguageLabelMode(args) ~= 'none' then
      returnStr = regions.en[getLanguageLabelMode(args)] .. ':'
    end
    
    title = mw.ustring.format('<span lang="%s"%s>-{%s}-</span>',
      regions.en.langcode,
      (regions.en.dir) == 'rtl' and ' dir="rtl"' or '',
      italicText(args, title, regions.en.italic)
    )
    
    returnStr = returnStr .. title .. ref
  end
  
  -- 此两参数用于除错,不在模板说明文档中介绍
  if args['englishes-before'] then
    returnStr = args['englishes-before'] .. returnStr
  end
  
  if args['englishes-after'] then
    returnStr = returnStr .. args['englishes-after']
  end 

  return returnStr
end

-- 中文译名主组
local function translations(args)
  local returnStr = ''
  local variantList = {'cn', 'tw', 'hk', 'sg', 'my', 'mo'}
  local translationArray = {}
  
  for _, v in ipairs(variantList) do
    local variantCode, variantTranslation = v, args[v]
    
    if variantTranslation then
      if isInArray(variantList, variantTranslation) then    -- 若译名字段填写为'cn'、'tw'等代码,則
        for _, w in ipairs(translationArray) do    -- 檢查該代碼是否錄入陣列
          if isInArray( w.variants, variantTranslation ) then -- 若該代碼已登錄,則
            table.insert( w.variants, variantCode ) -- 追加登錄
          else
            table.insert( translationArray, { variants = {variantCode, variantTranslation} } ) -- 同時登錄兩個代碼
          end
        end
      elseif args[v] == 'en' then
        -- 使用英文
      else
        -- 檢查上方是否按nil登錄
        local idx
        for k, v in ipairs(translationArray) do
          if isInArray(v.variants, variantCode) then
            idx = k
            break
          end
        end

        if idx then
          translationArray[idx].translation = variantTranslation
        else
          table.insert( translationArray, { variants = {v}, translation = args[v] } )
        end
      end
    end
  end

  return translationArray[2].variants[2]
end


--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------

local p = {}

function p.vgname(frame)
  local args = getArgs(frame)
  return p._vgname(args)
end

function p._vgname(args)
  local args = args
  return translations(args)
end

return p