-- CountDoomSpellTimer stuff
-- Author: Scrum


CDTimerSpell_numSpells = 0;
CDTimerSpell_spellID = 0;


CDTimerSpells = {};
-- timerIndex = timerIndex;    
-- warningHit = false;
-- spellAbbreviation = spellAbbreviation;
-- announceWarning = false;
-- warningSound = false;
-- announceEnd = false;
-- endSound = false;
-- targetName = nil;
-- targetLevel = nil;
-- type = nil;
-- ID = 0;


local function CDTimerSpell_Dump( spellIndex )
    CountDoom.dpf( "Spell#: "            .. spellIndex );
    CountDoom.dpf( "  timerIndex: "      .. CountDoom.ToStr( CDTimerSpells[ spellIndex ].timerIndex ) );
    CountDoom.dpf( "  spellID: "         .. CountDoom.ToStr( CDTimerSpells[ spellIndex ].spellID ) );
    CountDoom.dpf( "  warningHit: "      .. CountDoom.ToStr( CDTimerSpells[ spellIndex ].warningHit ) );
    CountDoom.dpf( "  spellAbbreviation: "       .. CDTimerSpells[ spellIndex ].spellAbbreviation );
    CountDoom.dpf( "  announceWarning: " .. CountDoom.ToStr( CDTimerSpells[ spellIndex ].announceWarning ) );
    CountDoom.dpf( "  warningSound: "    .. CountDoom.ToStr( CDTimerSpells[ spellIndex ].warningSound ) );
    CountDoom.dpf( "  announceEnd: "     .. CountDoom.ToStr( CDTimerSpells[ spellIndex ].announceEnd ) );
    CountDoom.dpf( "  endSound: "        .. CountDoom.ToStr( CDTimerSpells[ spellIndex ].endSound ) );
end


local function CDTimerSpell_DumpAll()
    if CountDoom.debugVerbose then
        local spellIndex;
        for spellIndex = 0, CDTimerSpell_numSpells - 1 do
            CDTimerSpell_Dump( spellIndex );
        end
    end        
end


local function CDTimerSpell_AnnounceMessage( msg )
    if CountDoom.config.announceSpells == nil or CountDoom.config.announceSpells == "never" then
        return;
    end

    local announceRaid = CountDoom.config.announceSpells == "all" or CountDoom.config.announceSpells == "raid";
    local announceParty = CountDoom.config.announceSpells == "all" or CountDoom.config.announceSpells == "party";

    local isRaid = GetNumRaidMembers() > 0;
    local isParty = GetNumPartyMembers() > 0;
    
    if( CountDoom.debugVerbose ) then
        isRaid = false;
        isParty = false;
    end
    
    if( announceRaid and isRaid ) then
        SendChatMessage( msg, "RAID" )
    elseif( announceParty and isParty ) then
        SendChatMessage( msg, "PARTY" );
    elseif ( CountDoom.config.announceSpells == "channel" )and 
           ( CountDoom.config.announceChannel ~= nil ) then

        local channelID = GetChannelName( CountDoom.config.announceChannel );
        if channelID ~= nil then
            SendChatMessage( msg, "CHANNEL", nil, channelID);
        else
            CountDoom.prt( msg, 1, 1, 1);
        end
    else
        CountDoom.prt( msg, 1, 1, 1);
    end
end


function CDTimerSpell_OnTimerWarning( timerIndex, timeUsed )
    local spellIndex = CDTimer_GetUserHandle( timerIndex );
    
    if spellIndex == nil then
        return;
    elseif CDTimerSpells[ spellIndex ].warningHit ~= true then
        if CountDoom.config.flashSpells ~= nil and
            CountDoom.config.flashSpells == true then
            CDTimer_EnableFlash( timerIndex, 2.0 );
        end

        CDTimerSpells[ spellIndex ].warningHit = true;
        
        local spellAbbreviation = CDTimerSpells[ spellIndex ].spellAbbreviation;
        local spellText = CountDoomSpell[ spellAbbreviation ].text;
        
        --
        -- Announce a warning message
        --
        if CDTimerSpells[ spellIndex ].announceWarning then
            local timeRemaining = CountDoomSpell[ spellAbbreviation ].warningTime;
            
            CDTimerSpell_AnnounceMessage( string.format( "%s has %d seconds remaining.", spellText, timeRemaining ) );
        end
        
        --
        -- Play a warning sound
        --
        if CDTimerSpells[ spellIndex ].warningSound and CountDoom.config.playSounds then
            local soundFile = CountDoom.soundPath .. CDTimerSpells[ spellIndex ].warningSound .. ".wav";
            CountDoom.dpf("Playing " .. soundFile);
            PlaySoundFile(soundFile);
        end
    end
end


function CDTimerSpell_OnTimerEnd( timerIndex, arg1 )
    local spellIndex = CDTimer_GetUserHandle( timerIndex );
    
    if spellIndex ~= nil then
    
        local spellAbbreviation = CDTimerSpells[ spellIndex ].spellAbbreviation;
        local spellText = CountDoomSpell[ spellAbbreviation ].text;

        --
        -- Announce a completion message
        --
        if CDTimerSpells[ spellIndex ].announceEnd then
            CDTimerSpell_AnnounceMessage( string.format( "%s has finished.", spellText ) );
            CDTimerSpells[ spellIndex ].announceEnd = false;
        end
    
        --
        -- Play a completion sound
        --
        if CDTimerSpells[ spellIndex ].endSound and CountDoom.config.playSounds then
            local soundFile = CountDoom.soundPath .. CDTimerSpells[ spellIndex ].endSound .. ".wav";
            CountDoom.dpf("Playing " .. soundFile);
            PlaySoundFile(soundFile);
            CDTimerSpells[ spellIndex ].endSound = false;
        end
    
        local remainingTime = CDTimer_GetRemainingTime( timerIndex );
        if (remainingTime + CountDoom.config.postExpireDelay) < 0 then
            CDTimerSpell_DeleteIndex( spellIndex );
        end
    end
end


function CDTimerSpell_OnTimerMove( newTimerIndex, oldTimerIndex )
    local spellIndex = CDTimer_GetUserHandle( newTimerIndex );
    if spellIndex ~= nil then
        if CDTimerSpells[ spellIndex ] ~= nil then
            CDTimerSpells[ spellIndex ].timerIndex = newTimerIndex;
        else
            CountDoom.dpf( "Unexpected nil CDTimerSpells[ spellIndex ] in CDTimerSpell_OnTimerMove" );
        end
    else
        CountDoom.dpf( "Unexpected nil spellIndex in CDTimerSpell_OnTimerMove" );
    end
end


function CDTimerSpell_TargetUnit( spellIndex )
    if spellIndex == nil then
        return false
    end

    local changedTarget = false;
    
    if CDTimerSpells[ spellIndex ].targetID == CountDoom.targetID then
    
        if (UnitName( "target" ) == nil and CDTimerSpells[ spellIndex ].targetName ~= nil) then
            TargetByName( CDTimerSpells[ spellIndex ].targetName );
            changedTarget = true;
        end
        
    elseif UnitName( "target" ) == CDTimerSpells[ spellIndex ].targetName and
    
        UnitLevel( "target" ) == CDTimerSpells[ spellIndex ].targetLevel then
        -- Nothing to do here as this matches our target
        
    elseif( CDTimerSpells[ spellIndex ].targetName ~= nil ) then
    
        ClearTarget();
        TargetByName( CDTimerSpells[ spellIndex ].targetName );
        changedTarget = true;
        
    end
    
    return changedTarget;
end


function CDTimerSpell_RecastSpell( spellIndex )
    if spellIndex == nil or spellIndex == -1 then
        return
    end
    
    local spellAbbreviation = CDTimerSpells[ spellIndex ].spellAbbreviation;
    
    if spellAbbreviation ~= nil then
        local spellName = CountDoomSpell[ spellAbbreviation ].text;
        
        -- recast spell
        if spellName ~= nil and spellName ~= COUNTDOOMSPELL_SEDUCE then
        
            -- re-target this mob
            local changedTarget = CDTimerSpell_TargetUnit( spellIndex );

            -- cast the spell
            if CountDoom.spellTable and CountDoom.spellTable[spellName] then
                local maxRank = CountDoom.spellTable[spellName].maxRank;
                
                if maxRank then
                    local tab = CountDoom.spellTable[spellName][maxRank].tab;
                    local spellID = CountDoom.spellTable[spellName][maxRank].spell;
    
                    if spellID and tab then
                        CountDoom.dpf( "recasting " .. spellName .. " ID " .. spellID .. " tab " .. tab + 1 );
                        CastSpell( spellID, tab + 1 );
                    end
                end
            end            
        
            -- revert to previous target
            if changedTarget then
                TargetLastTarget();
            end
        end
    end
end


function CDTimerSpell_OnTimerClick( timerIndex, arg1 )
    local spellIndex = CDTimer_GetUserHandle( timerIndex );

    CountDoom.dpf( "CDTimerSpell_OnTimerClick(spellIndex = " .. spellIndex .. " arg1 = " .. arg1 .. ")" );
    
    if arg1 == "LeftButton" then 
        if IsShiftKeyDown() then
            if IsAltKeyDown() then
                -- Do nothing.  Too complex of a key combination
            else
                -- Delete this timer
                CDTimerSpell_DeleteIndex( spellIndex );
            end
        elseif IsAltKeyDown() then
        else
            -- re-target this mob
            CDTimerSpell_TargetUnit( spellIndex );
        end
    elseif arg1 == "RightButton" then
        if IsShiftKeyDown() then
            -- Cast secondary spell (conflagrate if immolated)
        elseif IsAltKeyDown() then
        else
            -- recast the spell                
            CDTimerSpell_RecastSpell( spellIndex );
        end
    end
end


function CDTimerSpell_OnEnter( timerIndex )
    local spellIndex = CDTimer_GetUserHandle( timerIndex );
    
    if spellIndex ~= nil then
        local msg = "Target: ";
        if( CDTimerSpells[ spellIndex ].targetName ~= nil ) then
            msg = msg .. CDTimerSpells[ spellIndex ].targetName .. "("; 
            msg = msg .. CDTimerSpells[ spellIndex ].targetLevel .. ")";
        end
        GameTooltip:AddLine( msg, 1.00, 1.00, 1.00 );
    end
    
    GameTooltip:AddLine("Left-click to target", 1.00, 1.00, 1.00);
    --GameTooltip:AddLine("Right-click to re-cast", 1.00, 1.00, 1.00);
    GameTooltip:AddLine("Shift+Left-click to delete", 1.00, 1.00, 1.00);
end


function CDTimerSpell_CreateTimerString(spellIndex)
    local timerIndex = CDTimerSpells[ spellIndex ].timerIndex;
    local targetName = CDTimerSpells[ spellIndex ].targetName;
    local targetLevel = CDTimerSpells[ spellIndex ].targetLevel;
    local spellAbbreviation = CDTimerSpells[ spellIndex ].spellAbbreviation;

    if targetName == nil then
        targetName = "Unknown";
    end;

    if targetLevel == nil then
        targetLevel = "??";
    end;

    local timerString = " - " .. string.upper(spellAbbreviation) .. " - ";
    timerString = timerString .. CountDoom.ToStr(targetName) .. "(" .. CountDoom.ToStr(targetLevel) .. ")";

    return timerString;
end


function CDTimerSpell_CreateBySpellAbbreviation( spellAbbreviation, targetInfo, in_rank )
    CountDoom.dpf( "CDTimerSpell_CreateBySpellAbbreviation( " .. CountDoom.ToStr( spellAbbreviation ) .. ")" );
    
    local spellIndex = -1;
    local replacedASpell = false;
    
    if CountDoomSpell.IsEnabled( spellAbbreviation ) ~= true then
        return -1, replacedASpell;
    end

    --See if the spell is already on our target
    local targetName = targetInfo.targetName;
    local targetLevel = targetInfo.targetLevel;
    local targetID = targetInfo.id;
    
    --If we're replacing a spell such as a curse, delete the old one
    for spellIndex = 0, CDTimerSpell_numSpells - 1 do
        if (CDTimerSpells[ spellIndex ].type == CountDoomSpell[ spellAbbreviation ].type ) and
            CDTimerSpells[ spellIndex ].targetName == targetName and
            CDTimerSpells[ spellIndex ].targetLevel == targetLevel then
            if CountDoomSpell[ spellAbbreviation ].replacesSameType then
        		CDTimerSpell_DeleteIndex( spellIndex );
		        replacedASpell = true;
            end
            break;
        end
    end
    
    spellIndex = CDTimerSpell_numSpells;
    CDTimerSpell_numSpells = CDTimerSpell_numSpells + 1;
        
    if CDTimerSpells[ spellIndex ] == nil then
        CDTimerSpells[ spellIndex ] = {};
    end

    --if rank was passed in as nil, use max rank    
    local rank = in_rank;
    if rank == nil then
        rank = 10;
    end;
    
    --determine duration
    local duration = nil;

    if CountDoomSpell[ spellAbbreviation ] ~= nil then
        duration = CountDoomSpell[ spellAbbreviation ].rankDuration[ rank ];
    end;
    
    while duration == nil and rank > 0 do
        rank = rank - 1;
        duration = CountDoomSpell[ spellAbbreviation ].rankDuration[ rank ];
    end
    
    local warningTime = duration - CountDoomSpell[ spellAbbreviation ].warningTime;
    local icon = CountDoomSpell[ spellAbbreviation ].icon;
    local type = CountDoomSpell[ spellAbbreviation ].type;
    
    -- Give unique spellIDs to each spell.
    local spellID = CDTimerSpell_spellID;
    CDTimerSpell_spellID = CDTimerSpell_spellID + 1;
    if CDTimerSpell_spellID > 1000 then
        CDTimerSpell_spellID = 0;
    end
    
    local timerIndex = CDTimer_Create( CDTIMERPRIORITY_MEDIUM, duration );
    CDTimerSpells[ spellIndex ].timerIndex          = timerIndex;    
    CDTimerSpells[ spellIndex ].warningHit          = false;
    CDTimerSpells[ spellIndex ].spellAbbreviation   = spellAbbreviation;
    CDTimerSpells[ spellIndex ].announceWarning     = CountDoomSpell[ spellAbbreviation ].announceWarning;
    CDTimerSpells[ spellIndex ].announceEnd         = CountDoomSpell[ spellAbbreviation ].announceEnd;

    CDTimerSpells[ spellIndex ].warningSound        = CountDoom.config.warningSound[ spellAbbreviation ];
    CDTimerSpells[ spellIndex ].endSound            = CountDoom.config.endSound[ spellAbbreviation ];
    
    CDTimerSpells[ spellIndex ].targetName          = targetName;
    CDTimerSpells[ spellIndex ].targetLevel         = targetLevel;
    CDTimerSpells[ spellIndex ].targetID            = targetID;
    CDTimerSpells[ spellIndex ].spellID             = spellID;
    CDTimerSpells[ spellIndex ].type                = type;

    if CountDoom.config.layout == "textonly" then
        local timerString = CDTimerSpell_CreateTimerString(spellIndex);
        CDTimer_SetTimerSuffix( timerIndex, timerString );
    end
    
    CDTimer_SetUserHandle( timerIndex, spellIndex );
    CDTimer_SetWarningTime( timerIndex, warningTime );
    CDTimer_SetCountDown( timerIndex, CountDoomSpell[ spellAbbreviation ].countDown );
    CDTimer_SetFunctionHandler( timerIndex, CDTIMEREVENT_ONTIMERWARNING, CDTimerSpell_OnTimerWarning );
    CDTimer_SetFunctionHandler( timerIndex, CDTIMEREVENT_ONTIMEREND, CDTimerSpell_OnTimerEnd );
    CDTimer_SetFunctionHandler( timerIndex, CDTIMEREVENT_ONMOVETIMER, CDTimerSpell_OnTimerMove );
    CDTimer_SetFunctionHandler( timerIndex, CDTIMEREVENT_ONCLICK, CDTimerSpell_OnTimerClick );
    CDTimer_SetFunctionHandler( timerIndex, CDTIMEREVENT_ONENTER, CDTimerSpell_OnEnter );
    CDTimer_SetIcon( timerIndex, icon );
    
    CDTimerSpell_DumpAll();

    return spellID, replacedASpell;
end


function CDTimerSpell_CreateBySpellName( spellName, targetInfo, rank )
    CountDoom.dpf( "CDTimerSpell_CreateBySpellName(" .. CountDoom.ToStr( spellName ) .. ")" );

    -- Enslave Demon is detected differently than the rest of the Warlock spells.
    -- It relies on a change on event in pet status
    if spellName == COUNTDOOMSPELL_ENSLAVEDEMON then
        return -1;
    end

    local spellAbbreviation = CountDoomSpellMapping[ spellName ];
    if spellAbbreviation ~= nil then
        return CDTimerSpell_CreateBySpellAbbreviation( spellAbbreviation, targetInfo, rank );
    end

    return -1, false;
end


function CDTimerSpell_DeleteIndex( spellIndex )
    CountDoom.dpf( "CDTimerSpell_DeleteIndex(" .. CountDoom.ToStr( spellIndex ) .. ")" );
    
    if spellIndex >= CDTimerSpell_numSpells then
        CountDoom.dpf( "Invalid param CDTimerSpell_DeleteIndex(" .. spellIndex .. ")" );
        return;
    end

    -- Destroy the timer associated with the spell
    CDTimer_Destroy( CDTimerSpells[ spellIndex ].timerIndex );
    
    -- Collapse the array table by removing the deleted spell
    local srcIndex;
    for srcIndex = spellIndex + 1, CDTimerSpell_numSpells - 1do
        local dstIndex = srcIndex - 1;
        CDTimerSpells[ dstIndex ].timerIndex        = CDTimerSpells[ srcIndex ].timerIndex;    
        CDTimerSpells[ dstIndex ].warningHit        = CDTimerSpells[ srcIndex ].warningHit;
        CDTimerSpells[ dstIndex ].spellAbbreviation = CDTimerSpells[ srcIndex ].spellAbbreviation;
        CDTimerSpells[ dstIndex ].announceWarning   = CDTimerSpells[ srcIndex ].announceWarning;
        CDTimerSpells[ dstIndex ].warningSound      = CDTimerSpells[ srcIndex ].warningSound;
        CDTimerSpells[ dstIndex ].announceEnd       = CDTimerSpells[ srcIndex ].announceEnd;
        CDTimerSpells[ dstIndex ].endSound          = CDTimerSpells[ srcIndex ].endSound;
        CDTimerSpells[ dstIndex ].targetName        = CDTimerSpells[ srcIndex ].targetName;
        CDTimerSpells[ dstIndex ].targetLevel       = CDTimerSpells[ srcIndex ].targetLevel;
        CDTimerSpells[ dstIndex ].targetID          = CDTimerSpells[ srcIndex ].targetID;
        CDTimerSpells[ dstIndex ].spellID           = CDTimerSpells[ srcIndex ].spellID;
        CDTimerSpells[ dstIndex ].type              = CDTimerSpells[ srcIndex ].type;
                
        CDTimer_SetUserHandle( CDTimerSpells[ dstIndex ].timerIndex, dstIndex );
    end
    
    -- Update spell count
    CDTimerSpell_numSpells = CDTimerSpell_numSpells - 1; 
    
    -- Erase the last spell
    CDTimerSpells[ CDTimerSpell_numSpells ] = nil;
    
    -- Dump all spells in debug mode
    CDTimerSpell_DumpAll();
end


function CDTimerSpell_DeleteID( spellID )
    CountDoom.dpf( "CDTimerSpell_DeleteID(" .. CountDoom.ToStr( spellID ) .. ")" );

    local matchingIndex = -1;
    local spellIndex;
    for spellIndex = 0, CDTimerSpell_numSpells - 1 do
        if CDTimerSpells[ spellIndex ].spellID == spellID then
            matchingIndex = spellIndex;
            break;
        end
    end
    
    if matchingIndex ~= -1 then
        CDTimerSpell_DeleteIndex( matchingIndex );
    end
end


function CDTimerSpell_GetSpellIndex( spellID )
    CountDoom.dpf( "CDTimerSpell_GetSpellIndex(" .. CountDoom.ToStr( spellID ) .. ")" );

    local matchingIndex = -1;
    local spellIndex;
    for spellIndex = 0, CDTimerSpell_numSpells - 1 do
        if CDTimerSpells[ spellIndex ].spellID == spellID then
            return spellIndex;
        end
    end

    return -1;    
end


function CDTimerSpell_DeleteTarget( targetID )
    CountDoom.dpf( "CDTimerSpell_DeleteID(" .. CountDoom.ToStr( targetID ) .. ")" );

    local matchingIndex = -1;
    local spellIndex;
    for spellIndex = 0, CDTimerSpell_numSpells - 1 do
        if CDTimerSpells[ spellIndex ].targetID == targetID then
            matchingIndex = spellIndex;
            break;
        end
    end
    
    if matchingIndex ~= -1 then
        CDTimerSpell_DeleteIndex( matchingIndex );
        return true;
    end
    return false;
end


function CDTimerSpell_DestroyBySpellAbbreviation( spellAbbreviation )
    local found = false;
    
    CountDoom.dpf( "CDTimerSpell_DestroyBySpellAbbreviation(" .. CountDoom.ToStr( spellAbbreviation ) .. " )" );
    
    -- Look for the spell in question
    local foundIndex = 0;
    local spellIndex;
    for spellIndex = 0, CDTimerSpell_numSpells - 1 do
        if CDTimerSpells[ spellIndex ].spellAbbreviation == spellAbbreviation then
            CountDoom.dpf( "[spellIndex]: " .. CDTimerSpells[ spellIndex ].spellAbbreviation );
            CountDoom.dpf( "spellAbbr: " .. spellAbbreviation );
            found = true;
            foundIndex = spellIndex;
            break;
        end
    end
    
    if not found then
        CountDoom.dpf( "Attempting to delete a spell not found: " .. spellAbbreviation );
        return;
    end
    
    CountDoom.dpf( CountDoom.ToStr( found ) .. " " .. CountDoom.ToStr( foundIndex ) .. ": " .. CountDoom.ToStr( CDTimerSpells[ foundIndex ].spellAbbreviation ) );
    
    -- Collapsed the spell table into a contiguous array
    CDTimerSpell_DeleteIndex( foundIndex );
end


function CDTimerSpell_DestroyBySpellName( spellName )
    CountDoom.dpf( "CDTimerSpell_DestroyBySpellName(" .. CountDoom.ToStr( spellName ) .. " )" );
    
    local spellAbbreviation = CountDoomSpellMapping[ spellName ];
    if spellAbbreviation ~= nil then
        CDTimerSpell_DestroyBySpellAbbreviation( spellAbbreviation );
    end
end


function CDTimerSpell_GetSpellName( spellIndex )
    if CDTimerSpells[ spellIndex ] ~= nil then
        local spellAbbreviation = CDTimerSpells[ spellIndex ].spellAbbreviation;
        if spellAbbreviation ~= nil and CountDoomSpell[ spellAbbreviation ] ~= nil then
            return CountDoomSpell[ spellAbbreviation ].text;
        else
            CountDoom.dpf( "CDTimerSpell_GetSpellName failed: " .. spellAbbreviation );
        end
    end
    
    return nil;
end


function CDTimerSpell_RemoveCombatSpellTimers()
    local spellIndex;

    for spellIndex = CDTimerSpell_numSpells - 1, 0, -1 do
        local spellAbbreviation = CDTimerSpells[ spellIndex ].spellAbbreviation;
        CountDoom.dpf( "Checking for combat removal: " .. spellAbbreviation );
        if CountDoomSpell[ spellAbbreviation ].combatOnly then
            CDTimerSpell_DeleteIndex( spellIndex );
        end
    end
end


function CDTimerSpell_UpdateSpellPrefixes()
    local spellIndex;

    for spellIndex = 0, CDTimerSpell_numSpells - 1 do
        local timerIndex = CDTimerSpells[ spellIndex ].timerIndex;
        if CountDoom.config.layout == "textonly" then
            local timerString = CDTimerSpell_CreateTimerString(spellIndex);
            CDTimer_SetTimerSuffix( timerIndex, timerString );
        else
            CDTimer_SetTimerSuffix( timerIndex, nil );
        end
    end
end


function TargetHasMyDebuff(spellAbbreviation)
    local spellIndex = 0;
    local TimerSpell_numSpells = CDTimerSpell_numSpells - 1;
    CountDoom.dpf(CDTimerSpell_numSpells.." Spells." );
    for spellIndex = 0, TimerSpell_numSpells do
--    CountDoom.dpf(CDTimerSpells[ spellIndex ].targetName.."--"..UnitName("target"));
--    CountDoom.dpf(CDTimerSpells[ spellIndex ].spellAbbreviation.."--"..spellAbbreviation);
--    CountDoom.dpf(CDTimerSpells[ spellIndex ].targetLevel.."--"..UnitLevel("target"));
        if CDTimerSpells[ spellIndex ].targetName == UnitName("target") and
           CDTimerSpells[ spellIndex ].spellAbbreviation == spellAbbreviation and
           CDTimerSpells[ spellIndex ].targetLevel == UnitLevel("target") then
           return true;
        end           
    end  
    return false;  
end  

function CDTimerSpell_isDebuffCast(spellAbbreviation)
    return TargetHasMyDebuff(spellAbbreviation);
end