--[[
  Name: Recount FailBot Module
  Heavily based on: Ideas and code posted by sylvanaar
  Author: Elsia
]]

if not Recount then return end --  Forget about this if no Recount is present

local Recount = Recount

local RecountFailBot = LibStub("AceAddon-3.0"):NewAddon("RecountFailBot")
RecountFailBot.Version = tonumber(string.sub("$Revision: 24 $", 12, -3))

local RL = LibStub("AceLocale-3.0"):GetLocale("Recount")
local L = LibStub("AceLocale-3.0"):GetLocale("RecountFailBot")
local BZ = LibStub("LibBabble-Zone-3.0"):GetUnstrictLookupTable()

local fail = LibStub("LibFail-1.0")
local fail_events = fail:GetSupportedEvents()

local DetailTitles={}
DetailTitles.FailedHow={
    TopNames = RL["Ability Name"],
    TopCount = "",
    TopAmount = RL["Count"],
    BotNames = "",
    BotMin = "",
    BotAvg = "",
    BotMax = "",
    BotAmount = RL["Count"]
}

local Epsilon=0.000000000000000001

local defaults = {
    profile = {
        fails = { ["*"] = true },
    },
}

local zone_based_fail_events_list = {}

function RecountFailBot:GenerateFailTableByZone(zone)
    local fail_events_list = {}
    for _, v in pairs(fail:GetSupportedZoneEvents(zone)) do
--        local label = L["label_"..v]
        local label = "label_"..v

        if label == "label_"..v then
            local spell = GetSpellInfo(fail:GetEventSpellId(v))
            fail_events_list[v] = tostring(spell)
        else
            fail_events_list[v] = label
        end
    end
    zone_based_fail_events_list[zone] = fail_events_list
    return zone_based_fail_events_list[zone]
end

function RecountFailBot:GetMultiselect(info, key)
    return self.db.profile[info[#info]][key]
end

function RecountFailBot:SetMultiselect(info, key, value)
    self.db.profile[info[#info]][key] = value
end

local options = {
    name = "Recount Failbot",
    desc = "Filtering Options for Recount Failbot",
    type = "group",
    handler = RecountFailBot,
    args = {
        IcecrownCitadel = {
            type = "group",
            name = BZ["Icecrown Citadel"],
            args = {
                fails = {
                    name = BZ["Icecrown Citadel"],
                    type = "multiselect",
                    values = RecountFailBot:GenerateFailTableByZone("Icecrown Citadel"),
                    get = "GetMultiselect",
                    set = "SetMultiselect",
                },
            },
        },
        OnyxiasLair = {
            type = "group",
            name = BZ["Onyxia's Lair"],
            args = {
                fails = {
                    name = BZ["Onyxia's Lair"],
                    type = "multiselect",
                    values = RecountFailBot:GenerateFailTableByZone("Onyxia's Lair"),
                    get = "GetMultiselect",
                    set = "SetMultiselect",
                },
            },
        },
        TrialoftheCrusader = {
            type = "group",
            name = BZ["Trial of the Crusader"],
            args = {
                fails = {
                    name = BZ["Trial of the Crusader"],
                    type = "multiselect",
                    values = RecountFailBot:GenerateFailTableByZone("Trial of the Crusader"),
                    get = "GetMultiselect",
                    set = "SetMultiselect",
                },
            },
        },
        Ulduar = {
            type = "group",
            name = BZ["Ulduar"],
            args = {
                fails = {
                    name = BZ["Ulduar"],
                    type = "multiselect",
                    values = RecountFailBot:GenerateFailTableByZone("Ulduar"),
                    get = "GetMultiselect",
                    set = "SetMultiselect",
                },
            },
        },
        Naxxramas = {
            type = "group",
            name = BZ["Naxxramas"],
            args = {
                fails = {
                    name = BZ["Naxxramas"],
                    type = "multiselect",
                    values = RecountFailBot:GenerateFailTableByZone("Naxxramas"),
                    get = "GetMultiselect",
                    set = "SetMultiselect",
                },
            },
        },
        TheObsidianSanctum = {
            type = "group",
            name = BZ["The Obsidian Sanctum"],
            args = {
                fails = {
                    name = BZ["The Obsidian Sanctum"],
                    type = "multiselect",
                    values = RecountFailBot:GenerateFailTableByZone("The Obsidian Sanctum"),
                    get = "GetMultiselect",
                    set = "SetMultiselect",
                },
            },
        },
        EyeofEternity = {
            type = "group",
            name = BZ["The Eye of Eternity"],
            args = {
                fails = {
                    name = BZ["The Eye of Eternity"],
                    type = "multiselect",
                    values = RecountFailBot:GenerateFailTableByZone("Eye of Eternity"),
                    get = "GetMultiselect",
                    set = "SetMultiselect",
                },
            },
        },
        VaultofArchavon = {
            type = "group",
            name = BZ["Vault of Archavon"],
            args = {
                fails = {
                    name = BZ["Vault of Archavon"],
                    type = "multiselect",
                    values = RecountFailBot:GenerateFailTableByZone("Vault of Archavon"),
                    get = "GetMultiselect",
                    set = "SetMultiselect",
                },
            },
        },
    }
}

function RecountFailBot:OnDisable()
end

function RecountFailBot:OnEnable()
    LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable("RecountFailBot", options)
    LibStub("AceConfigDialog-3.0"):AddToBlizOptions("RecountFailBot", "RecountFailBot")

    self.db = LibStub("AceDB-3.0"):New("RecountFailBotDB", defaults, "Default")

end

-- Stolen straight from Sylvannars skeleton, don't use fatal but oh well
local function onFail(event, who, fatal)
    if not RecountFailBot.db.profile.fails[event] then return end
    if not Recount.db2.combatants[who] then
        Recount:DPrint("No source combatant!")
    else
        local sourceData=Recount.db2.combatants[who]
        local sourceName = sourceData.Name
        Recount:AddAmount(sourceData,"Fails",1)
        local spell = GetSpellInfo(fail:GetEventSpellId(event)) or ""
        Recount:AddTableDataStats(sourceData,"FailedHow",spell,sourceName,1)
    end
end

for _, event in ipairs(fail_events) do
    fail.RegisterCallback("RecountFailBot", event, onFail)
end

function RecountFailBot:DataModesFailBot(data, num)
    if not data then return 0 end
    if num==1 then
        return (data.Fights[Recount.db.profile.CurDataSet].Fails or 0)
    else
        return (data.Fights[Recount.db.profile.CurDataSet].Fails or 0), {{data.Fights[Recount.db.profile.CurDataSet].FailedHow,L["'s Fail Events"],DetailTitles.FailedHow}}
    end
end

function RecountFailBot:TooltipFuncsFailBot(name,data)
    local SortedData,total
    GameTooltip:ClearLines()
    GameTooltip:AddLine(name)
    Recount:AddSortedTooltipData(RL["Top 3"].." "..L["Fails"],data and data.Fights[Recount.db.profile.CurDataSet] and data.Fights[Recount.db.profile.CurDataSet].FailedHow,3)
    GameTooltip:AddLine("<"..RL["Click for more Details"]..">",0,0.9,0)
end



Recount:AddModeTooltip(L["Fails"],RecountFailBot.DataModesFailBot,RecountFailBot.TooltipFuncsFailBot,nil,nil,nil,nil)
