
---------------------------------
-- 物品信息庫 Author: M
---------------------------------

--Toolip
local tooltip = CreateFrame("GameTooltip", "TinyLibItemTooltip", UIParent, "GameTooltipTemplate")
local unittip = CreateFrame("GameTooltip", "TinyLibUnitTooltip", UIParent, "GameTooltipTemplate")

--物品是否本地化
local function hasLocally(ItemID)
    if (not ItemID or ItemID == "" or ItemID == "0") then return true end
    return select(10, GetItemInfo(tonumber(ItemID)))
end

--物品是否本地化
local function ItemLocally(ItemLink)
    local id, gem1, gem2, gem3 = string.match(ItemLink, "item:(%d+):[^:]*:(%d-):(%d-):(%d-):")
    return (hasLocally(id) and hasLocally(gem1) and hasLocally(gem2) and hasLocally(gem3))
end

--物品等級匹配規則
local ItemLevelPattern = gsub(ITEM_LEVEL, "%%d", "(%%d+)")

--獲取物品實際信息
local function GetItemInfoActually(ItemLink)
    if (not ItemLink or ItemLink == "") then
        return 0, 0
    end
    if (not string.match(ItemLink, "item:%d+:")) then
        return -1, 0
    end
    if (not ItemLocally(ItemLink)) then
        return 1, 0
    end
    local level, text
    tooltip:SetOwner(UIParent, "ANCHOR_NONE")
    tooltip:ClearLines()
    tooltip:SetHyperlink(ItemLink)
    for i = 2, 5 do
        text = _G[tooltip:GetName().."TextLeft" .. i]:GetText() or ""
        level = string.match(text, ItemLevelPattern)
        if (level) then break end
    end
    return 0, tonumber(level) or 0, GetItemInfo(ItemLink)
end

--獲取UNIT物品實際信息
local function GetUnitItemInfo(unit, index)
    if (not UnitExists(unit)) then return 1, 0 end
    unittip:SetOwner(UIParent, "ANCHOR_NONE")
    unittip:ClearLines()
    unittip:SetInventoryItem(unit, index)
    local ItemLink = select(2, unittip:GetItem())
    if (not ItemLink or ItemLink == "") then
        return 0, 0
    end
    if (not ItemLocally(ItemLink)) then
        return 1, 0
    end
    local level, text
    for i = 2, 5 do
        text = _G[unittip:GetName().."TextLeft" .. i]:GetText() or ""
        level = string.match(text, ItemLevelPattern)
        if (level) then break end
    end
    return 0, tonumber(level) or 0, GetItemInfo(ItemLink)
end

--獲取UNIT的裝備等級
local function GetUnitItemLevel(unit)
    local total, counts, boa = 0, 0, 0
    local _, count, level, quality
    for i = 1, 15 do
        if (i ~= 4) then
            count, level, _, _, quality = GetUnitItemInfo(unit, i)
            total = total + level
            counts = counts + count
            if (quality == 7) then boa = boa + 1 end
        end
    end
    local mcount, mlevel, mquality, mslot, ocount, olevel, oquality, oslot
    mcount, mlevel, _, _, mquality, _, _, _, _, _, mslot = GetUnitItemInfo(unit, 16)
    ocount, olevel, _, _, oquality, _, _, _, _, _, oslot = GetUnitItemInfo(unit, 17)
    counts = counts + mcount + ocount
    if (mquality == 7) then boa = boa + 1 end
    if (oquality == 7) then boa = boa + 1 end
    --[神器]最高x2 [雙-雙 雙-X X-雙]最高x2
    if (mquality == 6 or oslot == "INVTYPE_2HWEAPON" or mslot == "INVTYPE_2HWEAPON" or mslot == "INVTYPE_RANGED" or mslot == "INVTYPE_RANGEDRIGHT") then 
        total = total + max(mlevel, olevel) * 2
    else
        total = total + mlevel + olevel
    end
    return counts, total/16, boa, total
end

--获取物品TIP处理信息
local function GetItemTooltipInfo(ItemLink, functions, context)
    assert(type(functions) == "table")
    assert(type(context) == "table")
    tooltip:SetOwner(UIParent, "ANCHOR_NONE")
    tooltip:ClearLines()
    tooltip:SetHyperlink(ItemLink)
    local text
    for i = 1, tooltip:NumLines() do
        text = _G[tooltip:GetName().."TextLeft" .. i]:GetText() or ""
        for _, func in ipairs(functions) do
            func(text, context)
        end
    end
    return context
end

--獲取UNIT物品TIP处理信息
local function GetUnitItemTooltipInfo(unit, index, functions, context)
    assert(type(functions) == "table")
    assert(type(context) == "table")
    unittip:SetOwner(UIParent, "ANCHOR_NONE")
    unittip:ClearLines()
    unittip:SetInventoryItem(unit, index)
    local text
    for i = 1, unittip:NumLines() do
        text = _G[unittip:GetName().."TextLeft" .. i]:GetText() or ""
        for _, func in ipairs(functions) do
            func(text, context)
        end
    end
    return context
end

-------------------------
--  輪詢封裝 schedule
-------------------------
local frame = CreateFrame("Frame", nil, UIParent)
frame.schedules, frame.paused = {}, true
local metatable = {
    timer     = 0,
    elasped   = 1,
    begined   = 0,
    expired   = 0,
    onStart   = function(self) end,
    onTimeout = function(self) end,
    onExecute = function(self) return true end
}
frame.AddTask = function(self, item)
    for i, v in ipairs(self.schedules) do
        if (v.identity == item.identity) then
            return
        end
    end
    setmetatable(item, {__index = metatable})
    item.onStart(item)
    tinsert(self.schedules, item)
    self.paused = false
end
frame.RemoveTask = function(self, identity, useLike)
    for i, v in ipairs(self.schedules) do
        if (useLike) then
            if (string.find(v.identity,identity)) then
                tremove(self.schedules, i)
            end
        elseif (v.identity == identity) then
            tremove(self.schedules, i)
        end
    end
end
frame.AwakeTask = function(self, identity, useLike)
    for i, v in ipairs(self.schedules) do
        if (useLike) then
            if (string.find(v.identity,identity) and v.onExecute(v)) then
                tremove(self.schedules, i)
            end
        elseif (v.identity == identity and v.onExecute(v)) then
            tremove(self.schedules, i)
        end
    end
end
frame:SetScript("OnUpdate", function(self, elasped)
    if (self.paused) then return end
    local t = GetTime()
    for i, item in ipairs(self.schedules) do
        if (t >= item.begined) then
            item.timer = item.timer + elasped
            if (item.timer >= item.elasped) then
                item.timer = 0
                if (t > item.expired) then
                    tremove(self.schedules, i)
                    item.onTimeout(item)
                elseif (item.onExecute(item)) then
                    tremove(self.schedules, i)
                end
            end
        end
    end
    if (#self.schedules == 0) then
        self.paused = true
    end
end)


--------------------------
--  API 封裝
--------------------------

local LibItem = CreateFrame("Frame", "EuiLibItem", UIParent)

--API 計劃任務
--[[
    LibItem:AddTask({
        identity  = UnitGUID(unit),     --唯一簽名
        elasped   = 1,                  --執行周期
        begined   = 0,                  --開始時間
        expired   = GetTime() + 5,      --過期時間
        onStart   = function(self) end, --任務第一次被調用時執行
        onTimeout = function(self) end, --超出過期時間時執行
        onExecute = function(self) end, --定時執行,直到返回true才停止執行
    })
]]
function LibItem:AddTask(item)
    frame:AddTask(item)
end

--API 刪除計劃任務
function LibItem:RemoveTask(identity, useLike)
    frame:RemoveTask(identity, useLike)
end

--API 喚起計劃任務
function LibItem:AwakeTask(identity, useLike)
    frame:AwakeTask(identity, useLike)
end

--API 獲取物品實際信息
--[[
    @param
      ItemLink  物品鏈接
    @return
      count     0:正常 1:異常 -1:非物品
      level     物品真實等級
      ...       GetItemInfo數據
]]
function LibItem:GetItemInfoActually(ItemLink)
    return GetItemInfoActually(ItemLink)
end

--API 獲取UNIT物品實際信息
--[[
    @param
      unit    一般是Inspect的unit
      index   裝備欄位號
    @return
      count   0:正常 1:異常
      level   物品真實等級
      ...     GetItemInfo數據
]]
function LibItem:GetUnitItemInfo(unit, index)
    return GetUnitItemInfo(unit, index)
end

--API 獲取UNIT的裝備等級
--[[
    @param
      unit    一般是Inspect的unit
    @return
      count   0:正常 >0:異常
      level   物品等級
      boa     帳號綁定物品數量
      total   裝等總和
]]
function LibItem:GetUnitItemLevel(unit)
    return GetUnitItemLevel(unit)
end

--API 获取物品TIP处理信息
function LibItem:GetItemTooltipInfo(ItemLink, functions, context)
    return GetItemTooltipInfo(ItemLink, functions, context)
end

--API 獲取UNIT物品TIP处理信息
function LibItem:GetUnitItemTooltipInfo(unit, index, functions, context)
    return GetUnitItemTooltipInfo(unit, index, functions, context)
end
