Quantcast
local GridStatus = Grid:GetModule("GridStatus");
local GridRoster = Grid:GetModule("GridRoster");
local SmartHealing = GridStatus:GetModule("GridStatusSmartHealing");

local GridStatusSmartHealing_InArea = SmartHealing:NewModule("GridStatusSmartHealing_InArea", "AceEvent-3.0");

local SortMethods =
{
    missingHealth = "Total missing health",
    mostInArea = "Number of units"
};

local CenterTextOptions =
{
    bestTarget = "Target sort #s",
    estimatedHeal = "Total Missing Health",
    numPlayers = "Number of Targets"
};

GridStatusSmartHealing_InArea.defaultDB =
{
    enable = false,
    color = { r = 1, g = 0, b = 1, a = 0.5 },
    priority = 50,
    --
    rangeFromTarget = 10,
    sortMethod = "missingHealth",
    minTargets = 3,
    maxStatuses = 15,
    centerTextOption = "bestTarget",
};

local options =
{
    ["rangeFromTarget"] =
    {
        order = 100,
        type = "range",
        name = "Yards from Unit. (Player in Raid)",
        desc = "Yards to look around unit. Ex size of Holy Radiance is 10 yards.",
        min = 1,
        max = 40,
        step = 0.5,
        width = "full",
        get = function()
            return GridStatusSmartHealing_InArea.db.profile.rangeFromTarget;
        end,
        set = function(info, v)
            GridStatusSmartHealing_InArea.db.profile.rangeFromTarget = v;
            GridStatusSmartHealing_InArea:ClearAll();
            GridStatusSmartHealing_InArea:RefreshAll();
        end,
    },
    ["sortMethod"] =
    {
        order = 110,
        type = "select",
        name = "Sort Method",
        desc = "Sort Method in which to display best target",
        style = "radio",
        values = SortMethods,
        get = function()
            return GridStatusSmartHealing_InArea.db.profile.sortMethod;
        end,
        set = function(info, v)
            GridStatusSmartHealing_InArea.db.profile.sortMethod = v;
            GridStatusSmartHealing_InArea:ClearAll();
            GridStatusSmartHealing_InArea:RefreshAll();
        end,
    },
    ["minTargets"] =
    {
        order = 130,
        type = "range",
        name = "Min Targets in Range",
        desc = "Min number of targets in range, before showing",
        min = 0,
        max = 40,
        step = 1,
        width = "full",
        get = function()
            return GridStatusSmartHealing_InArea.db.profile.minTargets;
        end,
        set = function(info, v)
           GridStatusSmartHealing_InArea.db.profile.minTargets = v;
           GridStatusSmartHealing_InArea:ClearAll();
           GridStatusSmartHealing_InArea:RefreshAll();
        end,
    },
    ["maxStatuses"] =
    {
        order = 130,
        type = "range",
        name = "Max Status Targets",
        desc = "Max number of status targets to show",
        min = 1,
        max = 40,
        step = 1,
        width = "full",
        get = function()
            return GridStatusSmartHealing_InArea.db.profile.maxStatuses;
        end,
        set = function(info, v)
           GridStatusSmartHealing_InArea.db.profile.maxStatuses = v;
           GridStatusSmartHealing_InArea:ClearAll();
           GridStatusSmartHealing_InArea:RefreshAll();
        end,
    },
    ["centerTextOption"] =
    {
        order = 140,
        type = "select",
        name = "Center Text Option",
        desc = "What center text will display (if selected in indicators)",
        values = CenterTextOptions,
        style = "radio",
        get = function()
            return GridStatusSmartHealing_InArea.db.profile.centerTextOption;
        end,
        set = function(info, v)
            GridStatusSmartHealing_InArea.db.profile.centerTextOption = v;
            GridStatusSmartHealing_InArea:ClearAll();
            GridStatusSmartHealing_InArea:RefreshAll();
        end,
    }
}

local thisStatus = "alert_gssh_playersinarea";
local Settings;

function GridStatusSmartHealing_InArea:PostInitialize()
    SmartHealing:RegisterStatus(self, thisStatus, "Smart Healing - Players in Area", options, false);

    Settings = self.db.profile;
end

function GridStatusSmartHealing_InArea:OnStatusEnable(status)
    SmartHealing:DoEnable();
    --nothing
    self:RefreshAll();
end

function GridStatusSmartHealing_InArea:OnStatusDisable(status)
    SmartHealing:DoDisable();
    --nothing
    self:ClearAll();
end

function GridStatusSmartHealing_InArea:ClearAll()
    self.core:SendStatusLostAllUnits(thisStatus);
end

function GridStatusSmartHealing_InArea:RefreshAll()
    -- nothing.
end

function GridStatusSmartHealing_InArea:Update()
    self:ClearAll();

    local deficits = {};

    for guid, unitId in GridRoster:IterateRoster() do
        local info = SmartHealing:GetUnitInfo(guid);
        -- if info == nil, probably a pet.
        if (info ~= nil and ((Settings.sortMethod == "missingHealth" and info.missingHealth > 0) or Settings.sortMethod == "bestTarget")) then
            table.insert(deficits, info);
        end
    end

    -- sort highest missing health first
    if (Settings.sortMethod == "missingHealth") then
        table.sort(deficits, function(a, b)
            return a.missingHealth > b.missingHealth;
        end);
    end

    local targets = {};
    local numDeficits = #deficits;

    for i = 1, numDeficits do
        local curUnit = deficits[i];

        curUnit.totalHealthMissing = curUnit.missingHealth;
        curUnit.targets = {};

        for x = 1, numDeficits do
            if (i ~= x) then
                local curUnit2 = deficits[x];
                local distance = SmartHealing:Distance(curUnit, curUnit);

                if (distance and distance <= Settings.rangeFromTarget) then
                    curUnit.totalHealthMissing = curUnit.totalHealthMissing + curUnit2.missingHealth;
                    table.insert(curUnit.targets, curUnit2);
                end
            end
        end

        if (curUnit and curUnit.targets and #curUnit.targets >= Settings.minTargets) then
            table.insert(targets, curUnit);
        end
    end

    self:Debug("NumTargets", #targets);

    if (Settings.sortMethod == "missingHealth") then
        table.sort(targets, function(a, b)
            return a.totalHealthMissing > b.totalHealthMissing;
        end);
    else
        table.sort(targets, function(a, b)
            return #a.targets > #b.targets;
        end);
    end

    if (#targets == 0) then
        return;
    end

    for i, target in pairs(targets) do
        if (i > Settings.maxStatuses) then
            return;
        end

        local text;
        if (Settings.centerTextOption == "bestTarget") then
            text = string.format("#%s", i);
        elseif (Settings.centerTextOption == "numPlayers") then
            text = string.format("^%s", #target.targets);
        else
            --text = (target.totalHealthMissing / 1000) + "k";
            text = string.format("^%.1fk", target.totalHealthMissing / 1000);
            --text = target.totalHealthMissing;
        end
        self.core:SendStatusGained(target.guid, thisStatus, Settings.priority, nil, Settings.color, string.format("%s", text), 1, nil, nil);
    end
end