local _AddonName, _EchoRaidTools = ...;

local _PermaMarks = _EchoRaidTools:NewModule("perma-marks")

function _PermaMarks:ADDON_LOADED(addonName)
    if (addonName ~= _AddonName) or (_PermaMarks.AddonLoaded) then return end
    EchoRaidToolsDB.PermaMarks = EchoRaidToolsDB.PermaMarks or {}
    EchoRaidToolsDB.PermaMarks.UnitNames = EchoRaidToolsDB.PermaMarks.UnitNames or {}
    EchoRaidToolsDB.PermaMarks.EnableModule = EchoRaidToolsDB.PermaMarks.EnableModule or false
    EchoRaidToolsDB.PermaMarks.AllowMutipleNames = EchoRaidToolsDB.PermaMarks.AllowMutipleNames or false
    EchoRaidToolsDB.PermaMarks.IgnoreDead = EchoRaidToolsDB.PermaMarks.IgnoreDead or false
    EchoRaidToolsDB.PermaMarks.GuildNames = EchoRaidToolsDB.PermaMarks.GuildNames or false
    _PermaMarks.nicknameList = _PermaMarks.nicknameList or {}
    _PermaMarks:BuildNicknameList()
    _PermaMarks:UpdatePlayerCanMarkState()
    _PermaMarks:ChangeModuleState(_PermaMarks:GetModuleEnabled())
    _PermaMarks.AddonLoaded = true
end


function _PermaMarks:GetButtonInfo()
    return "Perma Marks",
    nil,
    function()
        return _PermaMarks:GetEditor()
    end,
    nil,
    4
end

function _PermaMarks:GetEditor()
    if not _PermaMarks.editor then
        _PermaMarks.editor = CreateFrame("Frame", "EchoRaidToolsPermaMarksOptions", _EchoRaidTools.panels.main, "EchoRaidTools_PermaMarks_Options")
        _PermaMarks.editor.Header.EnableModule:Hide()
        _PermaMarks.editor.Header.HeaderText:ClearAllPoints()
        _PermaMarks.editor.Header.HeaderText:SetPoint("LEFT", 10, 0)
        _PermaMarks.editor.Header.HeaderText:SetText("Permanent Raid Markers")
        _PermaMarks.editor:SetScript("OnShow",_PermaMarks.OnShow)
        _PermaMarks.editor:SetScript("OnHide",_PermaMarks.OnHide)

        for i=1,8 do
            local row = _PermaMarks.editor["rt"..i]
            if row then
                row.Icon:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcon_" .. i)
            end

            _PermaMarks:SetMarkerString(i,_PermaMarks:GetMarkerString(i))

            row.EditBox:SetScript("OnTextChanged",function()
                _PermaMarks:SetMarkerString(i,row.EditBox:GetText())
            end)

            row.ClearTextButton:SetScript("OnClick",function()
                _PermaMarks:SetMarkerString(i)
            end)

            row.Dropdown.tooltip = "Insert a player from the current group"

        end

        _PermaMarks.UpdateDropDowns()

        _PermaMarks.editor.clearmarks:SetScript("OnClick",_PermaMarks.ClearAllMarkers)
        _PermaMarks.editor.clearmarks.tooltip = "Clears all Raid Marks"

        _PermaMarks.editor.clear:SetScript("OnClick",_PermaMarks.ClearAllFields)
        _PermaMarks.editor.clear.tooltip = "Clears all EditBoxes"

        _PermaMarks.editor.activate:SetScript("OnClick",_PermaMarks.ToggleModuleEnabled)
        _PermaMarks.editor.activate.tooltip = "Attempts to permanently mark the desired players"

        if _PermaMarks:GetModuleEnabled() then
            _PermaMarks.editor.activate:SetText("Deactivate")
        end


    _PermaMarks.editor.multiplenames.CheckButton:SetChecked(_PermaMarks:GetAllowMutipleNames())
    _PermaMarks.editor.multiplenames.CheckButton:SetScript("OnClick",_PermaMarks.ToggleAllowMutipleNames)
    _PermaMarks.editor.multiplenames.CheckButton.tooltip = "Allow multiple names to be assigned to each mark. First valid unit in the list will be marked"

    _PermaMarks.editor.unmarkdead.CheckButton:SetChecked(_PermaMarks:GetIgnoreDead())
    _PermaMarks.editor.unmarkdead.CheckButton:SetScript("OnClick",_PermaMarks.ToggleIgnoreDead)
    _PermaMarks.editor.unmarkdead.CheckButton.tooltip = "Will only attempt to mark living units. If multiple units are assigned to a marker, first living unit will be marked"

    _PermaMarks.editor.guildnote.CheckButton:SetChecked(_PermaMarks:GetGuildNames())
    _PermaMarks.editor.guildnote.CheckButton:SetScript("OnClick",_PermaMarks.ToggleGuildNames)
    _PermaMarks.editor.guildnote.CheckButton.tooltip = "Attempts to match nicknames from guildnote"

    _PermaMarks.OnShow()
    end
    return _PermaMarks.editor
end


function _PermaMarks:ShowOptions()
    _EchoRaidTools:ShowContent(_PermaMarks:GetEditor())
end

function _PermaMarks:ChangeModuleState(state)
    EchoRaidToolsDB.PermaMarks.EnableModule = state
    _PermaMarks.enabled = state
    if state then
        if _PermaMarks.editor and _PermaMarks.editor.activate then
            _PermaMarks.editor.activate:SetText("Deactivate")
        end
        if not _PermaMarks.eventFrame then
        _PermaMarks:CreateEventFrame()
        end
        _PermaMarks:ParseUnitsFromEditBox()
    else
        if _PermaMarks.editor and _PermaMarks.editor.activate then
            _PermaMarks.editor.activate:SetText("Activate")
        end
    end

    if _PermaMarks.eventFrame then
        _PermaMarks.UpdateWatchedEvents()
    end
end

function _PermaMarks:GetModuleEnabled()
    return EchoRaidToolsDB.PermaMarks.EnableModule
end

function _PermaMarks:ToggleModuleEnabled()
    EchoRaidToolsDB.PermaMarks.EnableModule = not EchoRaidToolsDB.PermaMarks.EnableModule
    _PermaMarks:ChangeModuleState(EchoRaidToolsDB.PermaMarks.EnableModule)
end

function _PermaMarks:GetAllowMutipleNames()
    return EchoRaidToolsDB.PermaMarks.AllowMutipleNames
end

function _PermaMarks:ToggleAllowMutipleNames()
    EchoRaidToolsDB.PermaMarks.AllowMutipleNames  = not EchoRaidToolsDB.PermaMarks.AllowMutipleNames
        _PermaMarks:FindMarkableUnits()
end

function _PermaMarks:GetIgnoreDead()
    return EchoRaidToolsDB.PermaMarks.IgnoreDead
end

function _PermaMarks:ToggleIgnoreDead()
    EchoRaidToolsDB.PermaMarks.IgnoreDead  = not EchoRaidToolsDB.PermaMarks.IgnoreDead
    _PermaMarks:FindMarkableUnits()
end

function _PermaMarks:GetGuildNames()
    return EchoRaidToolsDB.PermaMarks.GuildNames
end

function _PermaMarks:ToggleGuildNames()
    EchoRaidToolsDB.PermaMarks.GuildNames  = not EchoRaidToolsDB.PermaMarks.GuildNames
    _PermaMarks:FindMarkableUnits()
end

function _PermaMarks:UpdatePlayerCanMarkState()
    _PermaMarks.PlayerCanMark = UnitIsGroupAssistant("player") or UnitIsGroupLeader("player") or not IsInGroup()
end

function _PermaMarks:RefreshRaidMarks()
    for marker, unitName in pairs(_PermaMarks.unitsToBeMarked) do
        if UnitExists(unitName) and GetRaidTargetIndex(unitName) ~= marker then
            SetRaidTarget(unitName, marker)
        end
    end
end

function _PermaMarks:GetMarkerStrings()
    return (EchoRaidToolsDB.PermaMarks.UnitNames or {})
end

function _PermaMarks:GetMarkerString(i)
    return EchoRaidToolsDB.PermaMarks.UnitNames[i] or nil
end

function _PermaMarks:SetMarkerString(i,string,concat)
    if string and concat and EchoRaidToolsDB.PermaMarks.AllowMutipleNames then
        EchoRaidToolsDB.PermaMarks.UnitNames[i] = EchoRaidToolsDB.PermaMarks.UnitNames[i].." "..string
    else
        EchoRaidToolsDB.PermaMarks.UnitNames[i] = string or nil
    end
        _PermaMarks.editor["rt"..i].EditBox:SetText(EchoRaidToolsDB.PermaMarks.UnitNames[i] or "")
    if _PermaMarks:GetModuleEnabled() then
        _PermaMarks:ParseUnitsFromEditBox()
    end
end

function _PermaMarks:ClearAllFields()
    for i = 8, 1, -1 do
    _PermaMarks:SetMarkerString(i)
    end
end

function _PermaMarks:ClearAllMarkers()
    local throttle = 0.25
    if not IsInGroup()then
        throttle = 0.01
    end
    local previousModuleState = _PermaMarks:GetModuleEnabled()
    if previousModuleState then
        _PermaMarks:ToggleModuleEnabled()
        C_Timer.After(throttle * 10,_PermaMarks.ToggleModuleEnabled)
    end

    for i = 1, 9 do
        if i < 9 then
            C_Timer.After(throttle*i - throttle, function() SetRaidTarget("player", i)end) --anti throttle
        else
            C_Timer.After(throttle*i - throttle, function() SetRaidTarget("player", 0)end)
        end
    end
end

function _PermaMarks.UpdateDropDowns()
    local items = {}
    for i=1,8 do
        items[i] = {}
    end

    for unit in _EchoRaidTools.IterateGroup() do
        local name = UnitName(unit)
        local label = GetClassColoredTextForUnit(unit, name)
        for i=1,8 do
            local row = _PermaMarks.editor["rt"..i]
            local item = {
                label = label,
                value = name,
                onclick = function()
                _PermaMarks:SetMarkerString(i,name,true)
                row.Dropdown:UpdateSelection("")
                end,
                desc = "Insert "..label,
            }
            table.insert(items[i], item)
        end
    end
    local extraUnits = {"Player","Focus","Target","Mouseover"}
    for i=1,8 do
        local row = _PermaMarks.editor["rt"..i]
        for y=1, 4 do
            local name = extraUnits[y]
            local item = {
                label = name,
                value = name,
                onclick = function()
                _PermaMarks:SetMarkerString(i,name,true)
                row.Dropdown:UpdateSelection("")
                end,
                desc = "Insert "..name,
            }
            table.insert(items[i], item)
        end
        row.Dropdown:SetupSelections(items[i], 0)
    end
end

_PermaMarks.ConfigOpen = false
function _PermaMarks.OnShow()
    _PermaMarks.ConfigOpen = true
    if _PermaMarks.UpdateDropDowns then _PermaMarks.UpdateDropDowns()end
    if not _PermaMarks.eventFrame then
        _PermaMarks:CreateEventFrame()
    end
end

function _PermaMarks.OnHide()
    _PermaMarks.ConfigOpen = false
    _PermaMarks.UpdateWatchedEvents()
end

function _PermaMarks:ParseUnitsFromEditBox()
    _PermaMarks.parsedUnitNames = {}
    for i, editBoxString in pairs(EchoRaidToolsDB.PermaMarks.UnitNames or {}) do
        for playerName in editBoxString:gmatch("%S+") do
            _PermaMarks.parsedUnitNames[i] = _PermaMarks.parsedUnitNames[i] or {}
            table.insert(_PermaMarks.parsedUnitNames[i],string.lower(playerName))
        end
    end
    _PermaMarks:FindMarkableUnits()
end

function _PermaMarks:FindMarkableUnits()
    _PermaMarks.registerTarget = false
    _PermaMarks.registerFocus = false
    _PermaMarks.registerMouseover = false
    if _PermaMarks.parsedUnitNames and _PermaMarks.PlayerCanMark and _PermaMarks:GetModuleEnabled() then
        local usedGUIDs = {}
        _PermaMarks.unitsToBeMarked = {}
        --for markerNum, marker in pairs(_PermaMarks.parsedUnitNames) do --was reordering for some strange reason
            for markerNum = 1, 8 do
                if _PermaMarks.parsedUnitNames[markerNum] then
                    for i, unitName in pairs(_PermaMarks.parsedUnitNames[markerNum]) do
                             if unitName == "target" then
                                _PermaMarks.registerTarget = true
                            elseif unitName == "focus" then
                                _PermaMarks.registerFocus = true
                            elseif unitName == "mouseover" then --why tho
                                _PermaMarks.registerMouseover = true
                            end
                            if _PermaMarks:GetGuildNames() then
                                unitName = _PermaMarks.nicknameList[unitName] or unitName
                            end
                        if UnitExists(unitName or "") and CanBeRaidTarget(unitName) and not usedGUIDs[UnitGUID(unitName)] and  (not EchoRaidToolsDB.PermaMarks.IgnoreDead or not UnitIsDeadOrGhost(unitName))then
                            _PermaMarks.unitsToBeMarked[markerNum] = unitName
                            usedGUIDs[UnitGUID(unitName)] = true
                            break
                        end

                        if not _PermaMarks:GetAllowMutipleNames() then
                            break
                        end
                    end
                end
            end
        _PermaMarks:RefreshRaidMarks()
    end
    _PermaMarks.UpdateWatchedEvents()
end

function _PermaMarks:BuildNicknameList()
    local _, onlineMembers = GetNumGuildMembers()
    for i = 1,  onlineMembers do
        local _, _, _, _, _, _, guildNote, _, _, _, _, _, _, _, _, _, GUID = GetGuildRosterInfo(i)
        if GUID and guildNote and guildNote ~= "" and not guildNote:find(" ") then
            local playerName = select(6,GetPlayerInfoByGUID(GUID))
            if playerName and (UnitInRaid(playerName) or UnitInParty(playerName) or UnitIsUnit("player", playerName)) then
                _PermaMarks.nicknameList[string.lower(guildNote)] = string.lower(playerName)
            end
        end
    end
end
