Quantcast
-- **************************************************************************
-- * TitanDefense.lua
-- *
-- * Originally By Tekkub
-- * Adopted by HonorGoG of the Titan Development Team
-- **************************************************************************
-- * 2020-03-14 : 5.0.3.11304 Subzone update, toc for WoW 1.13.4
-- * 2019-12-11 : 5.0.2.11303 Subzone update, toc for WoW 1.13.3
-- * 2019-12-07 : 5.0.1.11302 Subzone update
-- * 2019-08-15 : 5.0.0.11302 Version to work with Titan Panel Classic
-- * 2016-12-11 : 4.3.0.70100 Implemented NoTaint_UIDropDownMenu library routines and subzone update
-- * 2016-10-26 : 4.2.1.70100 Subzone update, toc for WoW 7.1
-- * 2016-07-20 : 4.2.0.70000 Subzone update, toc for WoW 7.0
-- * 2016-04-05 : 4.1.9.60200 Subzone update
-- * 2015-11-12 : 4.1.8.60200 Subzone update
-- * 2015-06-23 : 4.1.7.60200 toc for WoW 6.2
-- * 2015-06-04 : 4.1.6.60100 Subzone update
-- * 2015-02-24 : 4.1.5.60100 Subzone update, toc for WoW 6.1
-- * 2015-02-10 : 4.1.4.60000 Subzone update
-- * 2014-12-11 : 4.1.3.60000 Changed files from CRLF to Unix LF
-- * 2014-12-10 : 4.1.2.60000 Subzone update
-- * 2014-11-12 : 4.1.1.60000 Subzone update
-- * 2014-10-20 : 4.1.0.60000 Subzone update, toc for WoW 6.0
-- * 2013-10-29 : 4.0.4.50400 Fix for Blizzard's deprecation of GetCVar("realmName")
-- * 2013-09-09 : 4.0.3.50400 Subzone update, toc for WoW 5.4
-- * 2013-06-09 : 4.0.2.50300 Subzone update, toc for WoW 5.3
-- * 2013-03-07 : 4.0.1.50200 toc for WoW 5.2
-- * 2013-02-27 : 4.0.0.50100 Subzone update, toc for WoW 5.1, bug fixes, rewrote core
-- * 2011-12-01 : 3.0.16.40200 Subzone update and toc for WoW 4.3
-- * 2011-07-03 : 3.0.15.40200 toc for WoW 4.2
-- * 2011-06-02 : 3.0.14.40100 Subzone update and toc for WoW 4.1
-- * 2011-01-13 : 3.0.13.40000 Subzone update
-- * 2010-12-27 : 3.0.12.40000 Fixed minor error introduced in subzone update
-- * 2010-12-27 : 3.0.11.40000 Subzone update
-- * 2010-12-15 : 3.0.10.40000 Subzone update
-- * 2010-11-14 : 3.0.9.40000 "this", general code cleanup and resolved variable toggle issue
-- * 2010-10-28 : 3.0.8.40000 Subzone, API and WoW 4.0 updates
-- * 2009-12-01 : 3.0.7.30200 Subzone update, fixed linefeed MacOS problem
-- * 2009-08-04 : 3.0.6.30200 Subzone, API and WoW 3.2 updates
-- * 2009-04-06 : 3.0.5.30200 Subzone update (internal)
-- * 2009-04-16 : 3.0.4.30100a Removed embedded SVN directory
-- * 2009-04-15 : 3.0.4.30100 Subzone update and toc for WoW 3.1
-- * 2009-04-06 : 3.0.3.30000 Subzone update
-- * 2009-03-12 : 3.0.2.30000 Subzone update and a minor bug removed
-- * 2009-02-16 : 3.0.1.30000 Subzone update and added color for local attacks
-- * 2009-02-02 : 3.0.0.30000 Massive Ace3 update completed for new release
-- * 2008-03-16 : 2.3.0.20300 Massive overall structure update
-- * 2008-03-11 : 2.2.1.20300 Bug fixes
-- * 2008-02-20 : 2.2.0.20300 Released for Titan Panel 3.2.0
-- * 2007-11-13 : 2.1.1.20300 Adopted by HonorGoG and released for WoW 2.3.3
-- **************************************************************************

-- ********************************** Ace3 **********************************
TPCD = LibStub("AceAddon-3.0"):NewAddon("TitanPanelClassicDefense", "AceTimer-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("TitanClassic", true)

-- ******************************** Constants *******************************
TITAN_DEFENSE_ID = "Defense";
local _G = getfenv(0);
TITAN_DEFENSE_VERSION = GetAddOnMetadata("TitanClassicDefense", "Version") or L["TITAN_NA"]
TITAN_DEFENSE_VERSION_STRING = "|cffffd700Titan Panel Classic [Defense] "..GREEN_FONT_COLOR_CODE..TITAN_DEFENSE_VERSION.."|cffffd700 by |cffff8c00HonorGoG";
local TITAN_DEFENSE_DEBUG = false;

-- ******************************** Variables *******************************
TitanDefense_warningDuration = 40;
TitanDefense_uploadNotRequested = false;
TitanDefense_subzones = {};
TitanDefense_pname = "";
TitanDefense_laststamp = 0;
TitanDefense_attacks = {};                -- [index] = Subzone, Timestamp
TitanDefense_SubzoneSum = {};             -- [Subzone] = Sum
TitanDefense_ZoneSum = {};                -- [Zone] = Sum
TitanDefense_SubzoneTimestamp = {};       -- [Subzone] = timestamp
TitanDefense_ZoneTimestamp = {};          -- [Zone] = timestamp
TitanDefense_SortedSubzoneSum = {};       -- [Rank] = Subzone
TitanDefense_SortedZoneSum = {};          -- [Rank] = Zone
TitanDefense_SortedSubzoneTimestamp = {}; -- [Rank] = Subzone
TitanDefense_SortedZoneTimestamp = {};    -- [Rank] = Zone
TitanDefenseTimer = nil;

-- ***************************** SavedVariables *****************************
-- TitanDefense_options : Stored options
-- TitanClassicDefense_newSubzones : ["Subzone"] = "Zone"
-- TitanClassicDefense_unknowns : List of unknown subzones

-- ******************************** Functions *******************************

-- **************************************************************************
-- NAME : TitanPanelDefenseButton_OnLoad(self)
-- DESC : Register event and display versioning to chat frame
-- **************************************************************************
function TitanPanelDefenseButton_OnLoad(self)
     TPCDefense_Debug("TitanPanelDefenseButton_OnLoad");
     if (DEFAULT_CHAT_FRAME) then
         DEFAULT_CHAT_FRAME:AddMessage(TITAN_DEFENSE_VERSION_STRING);
     end
     self.registry = {
          id = TITAN_DEFENSE_ID,
          version = TITAN_DEFENSE_VERSION,
          menuText = L["TITAN_DEFENSE_STRINGS_MENUTEXT"],
          category = "Information",
          buttonTextFunction = "TitanPanelDefenseButton_GetButtonText",
          tooltipTitle = L["TITAN_DEFENSE_STRINGS_TOOLTIP"],
          tooltipTextFunction = "TitanPanelDefenseButton_GetTooltipText",
          icon = "Interface\\Icons\\Ability_Parry.blp",
          iconWidth = 16,
          savedVariables = {
               ShowLabelText = 1,
               ShowColoredText = 1,
               ShowIcon = 1,
               SZT = true,
               ZT = true,
               SZS = true,
               ZS = true,
               numSZT = 5,
               numZT = 5,
               numSZS = 5,
               numZS = 5,
               hideWD = true,
               hideLD = true,
          }
     };
     self:RegisterEvent("VARIABLES_LOADED");
     self:RegisterEvent("ZONE_CHANGED_NEW_AREA");
     self:RegisterEvent("ZONE_CHANGED");
     self:RegisterEvent("ZONE_CHANGED_INDOORS");
end

-- **************************************************************************
-- NAME : TitanPanelDefense_OnEvent(self,event,...)
-- DESC : Create three second countdown timer for variables loaded event and
--        handle zone change events
-- VARS : event = the triggered event we are watching
--        ... = nonexistant parameters
-- **************************************************************************
function TitanPanelDefense_OnEvent(self, event, ...)
     TPCDefense_DebugFunc("TitanPanelDefense_OnEvent", {event});
     if (event == "VARIABLES_LOADED") then
          if not TitanDefenseTimer then
               TPCD:ScheduleTimer(TitanPanelDefense_Init, 3)
               TitanDefenseTimer = true;
          end
     end
     if ((event == "ZONE_CHANGED_NEW_AREA") or (event == "ZONE_CHANGED") or (event == "ZONE_CHANGED_INDOORS")) then
          TitanPanelDefense_handleZoneChange();
     end
end

-- **************************************************************************
-- NAME : TPCDfilter(event, handler)
-- DESC :
-- **************************************************************************
local function TPCDfilter(self, event, message, sender, _, _, _, _, channelID, _, _, _, lineID, _)
    TPCDefense_DebugFunc("TPCDfilter", {event});
    if (channelID == 23) then
        TPCDefense_Debug("Chatter on WD: ".. sender.. "> ".. message);
        local _, _, zone = string.find(message, L["TITAN_DEFENSE_STRINGS_ZONEATTACKSEARCH"])
        if (zone) then
            TitanPanelDefense_HandleWorld(zone);
            if (TitanDefense_options[TitanDefense_pname]["hideWD"]) then
                TPCDefense_Debug("Blocking WD: ".. message);
                return true;
            else
                TPCDefense_Debug("Allowing WD: ".. message);
                if (lineID ~= lastlineID) then
                    DEFAULT_CHAT_FRAME:AddMessage(message);
                    lastlineID = lineID;
                end
            end
        end
    elseif (channelID == 22) then
        TPCDefense_Debug("Chatter on LD: ".. sender.. "> ".. message);
        local _, _, zone = string.find(message, L["TITAN_DEFENSE_STRINGS_ZONEATTACKSEARCH"])
        if (zone) then
            TitanPanelDefense_HandleLocal(zone);
            if (TitanDefense_options[TitanDefense_pname]["hideLD"]) then
                TPCDefense_Debug("Blocking LD: ".. message);
                return true;
            else
                TPCDefense_Debug("Allowing LD: ".. message);
                if (lineID ~= lastlineID) then
                    DEFAULT_CHAT_FRAME:AddMessage(message);
                    lastlineID = lineID;
                end
            end
        end
    end
    return false;
end

-- **************************************************************************
-- NAME : TitanPanelDefense_OnUpdate()
-- DESC : Nothing
-- **************************************************************************
function TitanPanelDefense_OnUpdate()
end

-- **************************************************************************
-- NAME : TitanPanelDefense_Init()
-- DESC : Nothing
-- **************************************************************************
--function TitanPanelDefense_Init()
function TitanPanelDefense_Init()
     TPCDefense_DebugFunc("TitanPanelDefense_Init");

     -- Remove timer
     TPCD:CancelTimer("TitanPanelDefense_Init", true)
     TitanDefenseTimer = nil;

     -- Init some variables
     if (not TitanClassicDefense_newSubzones) then TitanClassicDefense_newSubzones = {}; end
     if (not TitanClassicDefense_unknowns) then TitanClassicDefense_unknowns = {}; end
     TitanPanelDefense_cleanNewSubzones();

     -- Add a filter so we can supress server alerts
     ChatFrame_AddMessageEventFilter("CHAT_MSG_CHANNEL", TPCDfilter)

     -- Check that we're in the Def Channels
     --TPCDefense_Debug("GetChannelNameWD:"..GetChannelName(L["TITAN_DEFENSE_STRINGS_WDCHANNAME"]));
     --TPCDefense_Debug("GetChannelNameLD:"..GetChannelName(L["TITAN_DEFENSE_STRINGS_LDCHANNAME"]));
     if (GetChannelName(L["TITAN_DEFENSE_STRINGS_WDCHANNAME"]) == 0) then
          JoinPermanentChannel(L["TITAN_DEFENSE_STRINGS_WDCHANNAME"]);
          TPCDefense_Debug("JoinPermanentChannel("..L["TITAN_DEFENSE_STRINGS_WDCHANNAME"]..")");
     end
     if (GetChannelName(L["TITAN_DEFENSE_STRINGS_LDCHANNAME"]) == 0) then
          JoinPermanentChannel(L["TITAN_DEFENSE_STRINGS_LDCHANNAME"]);
          TPCDefense_Debug("JoinPermanentChannel("..L["TITAN_DEFENSE_STRINGS_LDCHANNAME"]..")");
     end

     TitanDefense_pname = GetRealmName().. UnitName("player");
     if (not TitanDefense_options) then TitanDefense_options = {}; end
     if (not TitanDefense_options[TitanDefense_pname]) then
          TitanDefense_options[TitanDefense_pname] = {};
          TitanDefense_options[TitanDefense_pname]["SZT"] = true;
          TitanDefense_options[TitanDefense_pname]["ZT"] = true;
          TitanDefense_options[TitanDefense_pname]["SZS"] = true;
          TitanDefense_options[TitanDefense_pname]["ZS"] = true;
          TitanDefense_options[TitanDefense_pname]["numSZT"] = 5;
          TitanDefense_options[TitanDefense_pname]["numZT"] = 5;
          TitanDefense_options[TitanDefense_pname]["numSZS"] = 5;
          TitanDefense_options[TitanDefense_pname]["numZS"] = 5;
          TitanDefense_options[TitanDefense_pname]["hideWD"] = true;
          TitanDefense_options[TitanDefense_pname]["hideLD"] = true;
     end
end

------------------------------
--      Chat Functions      --
------------------------------
-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_HandleWorld(location)
     if (TitanDefense_laststamp == time()) then return; end
     TitanDefense_laststamp = time();
     TPCDefense_DebugFunc("TitanPanelDefense_HandleWorld", {location});
     TitanPanelDefense_RecordAttack(location, time());
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_HandleLocal(location)
     TPCDefense_DebugFunc("TitanPanelDefense_HandleLocal", {location});
     local zone = GetZoneText();
     TitanPanelDefense_updateZoneList(location, zone);
end

------------------------------
--Attack Tracking Functions --
------------------------------
-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_RecordAttack(subzone, timestamp)
     TPCDefense_DebugFunc("TitanPanelDefense_RecordAttack", {subzone, timestamp});

     table.insert(TitanDefense_attacks, {subzone, timestamp});
     TitanPanelDefense_AddToTables(timestamp, subzone);
     TitanPanelDefense_SortTables();
     TitanPanelButton_UpdateButton(TITAN_DEFENSE_ID);
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_AddToTables(timestamp, subzone)
     local mainzone = TitanPanelDefense_getMainZone(subzone);

     if (not TitanDefense_SubzoneSum[subzone]) then TitanDefense_SubzoneSum[subzone] = 0; end
     if (not TitanDefense_ZoneSum[mainzone]) then TitanDefense_ZoneSum[mainzone] = 0; end

     TitanDefense_SubzoneSum[subzone] = TitanDefense_SubzoneSum[subzone] + 1;
     TitanDefense_ZoneSum[mainzone] = TitanDefense_ZoneSum[mainzone] + 1;
     TitanDefense_SubzoneTimestamp[subzone] = timestamp;
     TitanDefense_ZoneTimestamp[mainzone] = timestamp;
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_SortTables()
     TitanDefense_SortedSubzoneSum = TitanPanelDefense_Sort(TitanDefense_SubzoneSum);
     TitanDefense_SortedZoneSum = TitanPanelDefense_Sort(TitanDefense_ZoneSum);
     TitanDefense_SortedSubzoneTimestamp = TitanPanelDefense_Sort(TitanDefense_SubzoneTimestamp);
     TitanDefense_SortedZoneTimestamp = TitanPanelDefense_Sort(TitanDefense_ZoneTimestamp);
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_Sort(intable)
     local table1 = {};
     local returntable = {};
     for key,val in pairs(intable) do table1[key] = val; end;

     local tablesize = 0;
     for key,val in pairs(table1) do tablesize = tablesize+1; end;

     for i=1, tablesize do
          local maxval = 0;
          local maxkey = "";
          for key,val in pairs(table1) do
               if (val > maxval) then
                    maxval = val;
                    maxkey = key;
               end
          end
          returntable[i] = maxkey;
          table1[maxkey] = nil;
     end

     return returntable;
end

------------------------------
--  Zone Tracking Functions --
------------------------------
-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_handleZoneChange()
     local subzone = GetSubZoneText();
     local zone = GetZoneText();

     if (subzone == nil) then
          subzone = zone;
     end
     if (subzone == "") then
          subzone = zone;
     end

     TitanPanelDefense_updateZoneList(subzone, zone);
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_updateZoneList(subzone, zone)
     if (TitanDefense_subzones[subzone] == nil) then
          if (TitanClassicDefense_newSubzones[subzone] == nil) then
               -- Subzone has not been seen before
               TitanClassicDefense_newSubzones[subzone] = zone;
               if (TitanDefense_uploadNotRequested) then
                    DEFAULT_CHAT_FRAME:AddMessage(L["TITAN_DEFENSE_STRINGS_NEWZONE1"].. subzone.. "/".. zone.. L["TITAN_DEFENSE_STRINGS_NEWZONE2"]);
                    TitanDefense_uploadNotRequested = false;
               end
               return 1;
          end
     end

     return 0;
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_isLocal(subzone)
     local zone = GetZoneText();

     if (TitanDefense_subzones[subzone] == zone) then
          return true;
     end

     if (TitanClassicDefense_newSubzones[subzone] == zone) then
          return true;
     end

     return false;
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_cleanNewSubzones()
     local TitanDefense_oldNewSubzones = TitanClassicDefense_newSubzones;
     TitanClassicDefense_newSubzones = {};

     for loc in pairs(TitanDefense_oldNewSubzones) do
          if(TitanDefense_subzones[loc] == nil) then
               TitanClassicDefense_newSubzones[loc] = TitanDefense_oldNewSubzones[loc];
          end
     end
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_getMainZone(subzone)
     if (TitanDefense_subzones[subzone]) then
          return TitanDefense_subzones[subzone];
     end

     if (TitanClassicDefense_newSubzones[subzone]) then
          return TitanClassicDefense_newSubzones[subzone];
     end

     if (not TitanClassicDefense_unknowns[subzone]) then
          TitanClassicDefense_unknowns[subzone] = 1;
     end

     return L["TITAN_DEFENSE_STRINGS_UNKNOWNZONE"];

end



------------------------------
--     Output Functions     --
--     Used in plugins      --
------------------------------
-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_GetTimeText(secs)
     local returnstring = "";

     if (secs < 60) then
          returnstring = secs.. L["TITAN_DEFENSE_STRINGS_SECONDS"];
     elseif (secs < 300) then
          returnstring = math.floor(secs/60*4)/4 .. L["TITAN_DEFENSE_STRINGS_MINUTES"];
     elseif (secs < 3600) then
          returnstring = math.floor(secs/60) .. L["TITAN_DEFENSE_STRINGS_MINUTES"];
     else
          returnstring = math.floor(secs/3600*4)/4 .. L["TITAN_DEFENSE_STRINGS_HOUR"];
     end

     return returnstring
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_GetTooltipRawData(dataarray)
     if (table.getn(TitanDefense_attacks) == 0) then return nil; end

     local returnstring = "";

     if dataarray then
          for key,val in pairs(dataarray) do
               returnstring = returnstring.. "[".. key.. "] ".. val.. "\n";
          end
     end

     return returnstring;
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_GetTooltipData(dataarray, numvals, isSubzone)
     local returnstring = "";
     for i=1,numvals do
          if (dataarray[i]) then
               local zone = dataarray[i];
               local atttime = 0;
               local numatt = 0;

               if (isSubzone) then
                    numatt = TitanDefense_SubzoneSum[zone];
                    atttime = TitanDefense_SubzoneTimestamp[zone];
               else
                    numatt = TitanDefense_ZoneSum[zone];
                    atttime = TitanDefense_ZoneTimestamp[zone];
               end

               local elapsedtime = TitanPanelDefense_GetTimeText(time() - atttime);
               local mainzone = TitanPanelDefense_getMainZone(zone);

               if (isSubzone) then
                    if (TitanPanelDefense_isLocal(zone)) then
                         returnstring = returnstring.. L["TITAN_DEFENSE_STRINGS_LOCALHEADER"].. zone.. " (".. numatt.. ")\t".. elapsedtime.. L["TITAN_DEFENSE_STRINGS_AGOENDER"].. "\n";
                    elseif (mainzone == loc) then
                         returnstring = returnstring.. zone.. " (".. numatt.. ")\t".. elapsedtime.. L["TITAN_DEFENSE_STRINGS_AGOENDER"].. "\n";
                    else
                         returnstring = returnstring.. mainzone.. ": ".. zone.. " (".. numatt.. ")\t".. elapsedtime.. L["TITAN_DEFENSE_STRINGS_AGOENDER"].. "\n";
                    end
               else
                    returnstring = returnstring.. zone.. " (".. numatt.. ")\t".. elapsedtime.. L["TITAN_DEFENSE_STRINGS_AGOENDER"].. "\n";
               end
          end
     end
     return returnstring;
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_getLastAttack()
     if (table.getn(TitanDefense_attacks) == 0) then return nil; end

     local lasttime = TitanDefense_attacks[table.getn(TitanDefense_attacks)][2];
     local lastsubzone = TitanDefense_attacks[table.getn(TitanDefense_attacks)][1];

     local returnstring = ""..lastsubzone.." ("..TitanDefense_SubzoneSum[lastsubzone]..")";
     local islocal = false;

     if (TitanPanelDefense_isLocal(lastsubzone)) then
          islocal = true;
     end

     return returnstring, islocal, lasttime;
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_GetNumAttText()
     if (table.getn(TitanDefense_attacks) == 0) then
          return L["TITAN_DEFENSE_STRINGS_NOATTACKS"];
     elseif (table.getn(TitanDefense_attacks) == 1) then
          return L["TITAN_DEFENSE_STRINGS_ATTACKTEXT"];
     else
          return table.getn(TitanDefense_attacks).. L["TITAN_DEFENSE_STRINGS_ATTACKSTEXT"];
     end
end

------------------------------
--    Titan Panel Support   --
------------------------------
-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefenseButton_GetButtonText(id)
     local button, id = TitanUtils_GetButton(id, true);

     local att, islocal, atttime = TitanPanelDefense_getLastAttack();

     if (not att) then
          att = TitanPanelDefense_GetNumAttText();
          return TitanUtils_GetGreenText(att);
     elseif (atttime + TitanDefense_warningDuration < time()) then
          att = TitanPanelDefense_GetNumAttText();
          return TitanUtils_GetGreenText(att);
     elseif (islocal) then
          return TitanUtils_GetNormalText(att);
     else
          return TitanUtils_GetRedText(att);
     end
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefenseButton_GetTooltipText()
     if (TitanDefense_numAttacks == 0) or (TitanDefenseTimer) then return L["TITAN_DEFENSE_STRINGS_NOATTACKS"]; end

     local rawdataset = {
          {"------SubzoneSum-----\n", TitanDefense_SortedSubzoneSum},
          {"------ZoneSum-----\n", TitanDefense_SortedZoneSum},
          {"------SubzoneTime-----\n", TitanDefense_SortedSubzoneTimestamp},
          {"------ZoneTime-----\n", TitanDefense_SortedZoneTimestamp},
          {"------Unknowns-----\n", TitanClassicDefense_unknowns},
          {"------Attacks-----\n", TitanDefense_attacks}
     };

     local dataset = {
          {L["TITAN_DEFENSE_STRINGS_SZTIMETITLE"], TitanDefense_options[TitanDefense_pname]["SZT"],
               TitanDefense_options[TitanDefense_pname]["numSZT"], TitanDefense_SortedSubzoneTimestamp, true},
          {L["TITAN_DEFENSE_STRINGS_ZTIMETITLE"], TitanDefense_options[TitanDefense_pname]["ZT"],
               TitanDefense_options[TitanDefense_pname]["numZT"], TitanDefense_SortedZoneTimestamp, false},
          {L["TITAN_DEFENSE_STRINGS_SZFRQTITLE"], TitanDefense_options[TitanDefense_pname]["SZS"],
               TitanDefense_options[TitanDefense_pname]["numSZS"], TitanDefense_SortedSubzoneSum, true},
          {L["TITAN_DEFENSE_STRINGS_ZFRQTITLE"], TitanDefense_options[TitanDefense_pname]["ZS"],
               TitanDefense_options[TitanDefense_pname]["numZS"], TitanDefense_SortedZoneSum, false}
     };

     local returnstring = "";

     returnstring = returnstring.. TitanPanelDefense_GetNumAttText().. "\n";

     for i,arrayinfo in pairs(dataset) do
          if (arrayinfo[2]) then
               returnstring = returnstring.."\n".. TitanUtils_GetHighlightText(arrayinfo[1]).. "\n";
               returnstring = returnstring..TitanPanelDefense_GetTooltipData(arrayinfo[4], arrayinfo[3], arrayinfo[5]);
          end
     end

     return returnstring;
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelRightClickMenu_PrepareDefenseMenu()
     if (not TitanDefense_options) or (not TitanDefense_options[TitanDefense_pname]) then return false; end

     TitanPanelRightClickMenu_AddTitle(TitanPlugins[TITAN_DEFENSE_ID].menuText);

     local id = TITAN_DEFENSE_ID;
     local info = {};

     local items = {
          {"Supress WorldDef Alerts", "hideWD"},
          {"Supress LocalDef Alerts", "hideLD"},
          {"Show Recent Subzones", "SZT"},
          {"Show Recent Zones", "ZT"},
          {"Show Freq Subzones", "SZS"},
          {"Show Freq Zones", "ZS"},
     };

     for i,arr in pairs(items) do
          info.text = arr[1];
          info.value = arr[2];
          info.checked = TitanDefense_options[TitanDefense_pname][arr[2]];
          info.func = TitanPanelDefense_Toggle;
          L_UIDropDownMenu_AddButton(info, 1);
     end

     TitanPanelRightClickMenu_AddSpacer();
     TitanPanelRightClickMenu_AddCommand(L["TITAN_PANEL_MENU_HIDE"], id, TITAN_PANEL_MENU_FUNC_HIDE);
end

-- **************************************************************************
-- NAME :
-- DESC :
-- **************************************************************************
function TitanPanelDefense_Toggle(self)
     local setting = self.value;
     if (TitanDefense_options[TitanDefense_pname][setting]) then
          TitanDefense_options[TitanDefense_pname][setting] = false;
     else
          TitanDefense_options[TitanDefense_pname][setting] = true;
     end
     if (TitanDefense_options[TitanDefense_pname]["hideWD"]) then
         TPCDefense_Debug("ToggleWD: true");
     else
         TPCDefense_Debug("ToggleWD: false");
     end
     if (TitanDefense_options[TitanDefense_pname]["hideLD"]) then
         TPCDefense_Debug("ToggleLD: true");
     else
         TPCDefense_Debug("ToggleLD: false");
     end
end

-- **************************************************************************
-- NAME : TPCDefense_DebugFunc(func, args)
-- DESC : Display function and arguments if debug mode is active
-- VARS : func = name of the function, args = arguments passed to function
-- **************************************************************************
function TPCDefense_DebugFunc(func, args)
     local argstring = "(";
     if args then
          for i=1, table.getn(args) do
               if (not (i==1)) then argstring = argstring.. ", "; end
               argstring = argstring.. args[i];
          end
     end
     argstring = argstring.. ")";
     if (TITAN_DEFENSE_DEBUG) then DEFAULT_CHAT_FRAME:AddMessage("TitanDefenseDebug: ".. func.. argstring); end
end

-- **************************************************************************
-- NAME : TPCDefense_Debug(msg)
-- DESC : Display message if debug mode is active
-- VARS : msg = message to display
-- **************************************************************************
function TPCDefense_Debug(msg)
     if (TITAN_DEFENSE_DEBUG) then DEFAULT_CHAT_FRAME:AddMessage("TitanDefenseDebug: ".. msg); end
end