--[[

  HealBot Contined
	
]]

local CalcEquipBonus=false;
local HasDivineSpirit=2;
local CheckForDivineSpirit=false;
local FlagEquipUpdate1=1;
local FlagEquipUpdate2=1;
local NeedEquipUpdate=0;
local HealBot_CastingSpell  = nil;
local HealBot_HealValue = 0;
local HealBot_IamRessing = nil;
local InitSpells=false;
local DebugDebuff=false;
local HealBot_RequestVer=nil;
local HealBot_TalentsChanged=false;
local HealBot_DelayData=0;
local HealBot_IamHealing = {};
local DruidInForm=0;
local HealBot_Loaded=false;
local HealBot_InnerFocusTalent=false;
local HealBot_HoT1={};
local HealBot_HoT2={};
local HealBot_HoT3={};
local HealBot_HoT1_Spell={};
local HealBot_HoT2_Spell={};
local HealBot_HoT3_Spell={};
local HealBot_HoT_iconTexture1={};
local HealBot_HoT_iconTexture2={};
local HealBot_HoT_iconTexture3={};
local HealBot_HoT_Waiting={};
local HealBot_HoT_WaitingSpell={};
local HealBot_HoT_WaitingSpellName={};

local HealBot_BuffNameSwap = { [HEALBOT_POWER_WORD_FORTITUDE] = HEALBOT_PRAYER_OF_FORTITUDE,
                               [HEALBOT_PRAYER_OF_FORTITUDE] = HEALBOT_POWER_WORD_FORTITUDE,
                               [HEALBOT_SHADOW_PROTECTION] = HEALBOT_PRAYER_OF_SHADOW_PROTECTION,
                               [HEALBOT_PRAYER_OF_SHADOW_PROTECTION] = HEALBOT_SHADOW_PROTECTION,
                               [HEALBOT_DIVINE_SPIRIT] = HEALBOT_PRAYER_OF_SPIRIT,
                               [HEALBOT_PRAYER_OF_SPIRIT] = HEALBOT_DIVINE_SPIRIT,
                               [HEALBOT_MARK_OF_THE_WILD] = HEALBOT_GIFT_OF_THE_WILD,
                               [HEALBOT_GIFT_OF_THE_WILD] = HEALBOT_MARK_OF_THE_WILD,
                               [HEALBOT_BLESSING_OF_MIGHT] = HEALBOT_GREATER_BLESSING_OF_MIGHT,
                               [HEALBOT_GREATER_BLESSING_OF_MIGHT] = HEALBOT_BLESSING_OF_MIGHT,
                               [HEALBOT_BLESSING_OF_WISDOM] = HEALBOT_GREATER_BLESSING_OF_WISDOM,
                               [HEALBOT_GREATER_BLESSING_OF_WISDOM] = HEALBOT_BLESSING_OF_WISDOM,
                               [HEALBOT_BLESSING_OF_KINGS] = HEALBOT_GREATER_BLESSING_OF_KINGS,
                               [HEALBOT_GREATER_BLESSING_OF_KINGS] = HEALBOT_BLESSING_OF_KINGS,
                               [HEALBOT_BLESSING_OF_LIGHT] = HEALBOT_GREATER_BLESSING_OF_LIGHT,
                               [HEALBOT_GREATER_BLESSING_OF_LIGHT] = HEALBOT_BLESSING_OF_LIGHT,
                               [HEALBOT_BLESSING_OF_SALVATION] = HEALBOT_GREATER_BLESSING_OF_SALVATION,
                               [HEALBOT_GREATER_BLESSING_OF_SALVATION] = HEALBOT_BLESSING_OF_SALVATION,
                               [HEALBOT_BLESSING_OF_SANCTUARY] = HEALBOT_GREATER_BLESSING_OF_SANCTUARY,
                               [HEALBOT_GREATER_BLESSING_OF_SANCTUARY] = HEALBOT_BLESSING_OF_SANCTUARY,
                               [HEALBOT_ARCANE_INTELLECT] = HEALBOT_ARCANE_BRILLIANCE,
                               [HEALBOT_ARCANE_BRILLIANCE] = HEALBOT_ARCANE_INTELLECT,
                       }


function HealBot_TooltipInit()
  if ( HealBot_ScanTooltip:IsOwned(this) ) then return; end;
  HealBot_ScanTooltip:SetOwner(this, 'ANCHOR_NONE' );
  HealBot_ScanTooltip:ClearLines();
end

function HealBot_AddChat(msg)
  local chanid=HealBot_GetChan("HBmsg");
  if chanid and HealBot_SpamCnt < 7 then
    HealBot_SpamCnt=HealBot_SpamCnt+1;
    local hour,minute = GetGameTime();
	if minute==0 then
      msg="["..hour..":00] "..msg;
    elseif minute<10 then
      msg="["..hour..":0"..minute.."] "..msg; 
    else
      msg="["..hour..":"..minute.."] "..msg; 
    end
    SendChatMessage(msg , "CHANNEL", nil, chanid); 
  elseif ( DEFAULT_CHAT_FRAME ) then
    DEFAULT_CHAT_FRAME:AddMessage(msg);
  end
end


function HealBot_AddDebug(msg)
  local chanid=HealBot_GetChan("HBmsg");
  if chanid and HealBot_SpamCnt < 7 then
    HealBot_SpamCnt=HealBot_SpamCnt+1;
    local hour,minute = GetGameTime();
	if minute==0 then
      msg="["..hour..":00] DEBUG: "..msg;
    elseif minute<10 then
      msg="["..hour..":0"..minute.."] DEBUG: "..msg; 
    else
      msg="["..hour..":"..minute.."] DEBUG: "..msg; 
    end
    SendChatMessage(msg , "CHANNEL", nil, chanid);
  end
end

function HealBot_Report_Error(msg)
  if HealBot_ErrorCnt<28 then
    HealBot_ErrorCnt=HealBot_ErrorCnt+1;
    ShowUIPanel(HealBot_Error);
    HealBot_ErrorsIn(msg,HealBot_ErrorCnt);
  end
end

function HealBot_AddError(msg)
  UIErrorsFrame:AddMessage(msg, 1.0, 1.0, 1.0, 1.0, UIERRORS_HOLD_TIME);
  HealBot_AddDebug(msg);
end

function HealBot_TogglePanel(panel)
  if (not panel) then return end
  if ( panel:IsVisible() ) then
    HideUIPanel(panel);
  else
    ShowUIPanel(panel);
  end
end

function HealBot_StartMoving(frame)
  if ( not frame.isMoving ) and ( frame.isLocked ~= 1 ) then
    frame:StartMoving();
    frame.isMoving = true;
  end
end

function HealBot_StopMoving(frame)
  if ( frame.isMoving ) then
    frame:StopMovingOrSizing();
    frame.isMoving = false;
  end
  if HealBot_Config.GrowUpwards==1 then
    local left,bottom = HealBot_Action:GetLeft(),HealBot_Action:GetBottom();
    if left and bottom then
      HealBot_Config.PanelAnchorX=left;
      HealBot_Config.PanelAnchorY=bottom;
    end
--    HealBot_AddDebug("Pos X="..HealBot_Config.PanelAnchorX.."  Pos Y="..HealBot_Config.PanelAnchorY)
  end

end

function HealBot_SlashCmd(cmd)
  if (cmd=="") then
    HealBot_TogglePanel(HealBot_Action);
    return
  end
  if (cmd=="o" or cmd=="options" or cmd=="opt" or cmd=="config" or cmd=="cfg") then
    HealBot_TogglePanel(HealBot_Options);
    return
  end
  if (cmd=="reset" or cmd=="recalc" or cmd=="defaults") then
    HealBot_Options_Defaults_OnClick(HealBot_Options_Defaults);
    initSpells=true;
  	NeedEquipUpdate=5;
    return
  end
  if (cmd=="ui") then
    ReloadUI();
    return;
  end
  if (cmd=="init") then
  	HealBot_RegisterThis(this);
  end
  if (cmd=="x") then
    initSpells=true;
	NeedEquipUpdate=5;
    return;
  end
  if (cmd=="ver") then
    local text=UnitName("player");
    HealBot_SendAddonMsg("HealBot", ">> RequestVersion <<=>> "..text.." <<=>> nil <<")
    return;
  end
  if (cmd=="chan") then
    HealBot_AddDebug( "Channel active" );
    return;
  end
  if (cmd=="status") then
    HealBot_DebugStatus();
    return;
  end
end

function HealBot_DebugStatus()
  if HealBot_PlayerDead then
    HealBot_Report_Error("HealBot_PlayerDead=true")
  else
    HealBot_Report_Error("HealBot_PlayerDead=false")
  end
  if HealBot_PlayerCanCast then
    HealBot_Report_Error("HealBot_PlayerCanCast=true")
  else
    HealBot_Report_Error("HealBot_PlayerCanCast=false")
  end
  if HealBot_InnerFocus then
    HealBot_Report_Error("HealBot_InnerFocus=true")
  else
    HealBot_Report_Error("HealBot_InnerFocus=false")
  end
  if HealBot_InnerFocusTalent then
    HealBot_Report_Error("HealBot_InnerFocusTalent=true")
  else
    HealBot_Report_Error("HealBot_InnerFocusTalent=false")
  end
end
  

function HealBot_TargetName()
  if UnitIsEnemy("target","player") then return nil end
--  if not UnitPlayerControlled("target") then return nil end
  if (UnitIsPlayer("target")) then
    if (UnitInRaid("target")) then 
      for i=1,40 do
        if UnitIsUnit("target","raid"..i) then return "raid"..i end
      end
    end
    if UnitIsUnit("target","player") then return "player" end
    if (UnitInParty("target")) then 
      for i=1,4 do
        if UnitIsUnit("target","party"..i) then return "party"..i end
      end
    end
  else
    if UnitIsUnit("target","pet") then return "pet" end
    if (UnitInRaid("player")) then 
      for i=1,40 do
        if UnitIsUnit("target","raidpet"..i) then return "raidpet"..i end
      end
    end
    if (UnitInParty("player")) then 
      for i=1,4 do
        if UnitIsUnit("target","partypet"..i) then return "partypet"..i end
      end
    end
  end
  return nil
end

function HealBot_GetSpellName(id)
  if (not id) then
    return nil;
  end
  local spellName, subSpellName = GetSpellName(id,BOOKTYPE_SPELL);
  if (not spellName) then
    return nil;
  end
  if (not subSpellName or subSpellName=="") then
    return spellName;
  end
  return spellName, subSpellName;
end

function HealBot_GetSpellId(spell)
  local id,idd = 1,0;
  if HealBot_Spells[spell] then   
    if HealBot_Spells[spell].id then return HealBot_Spells[spell].id; end
  end
  while true do 
    local spellName, subSpellName = GetSpellName(id,BOOKTYPE_SPELL);
    if (spellName) then
      if (spell == spellName .. " (" .. subSpellName .. ")") or (spell == spellName .. "(" .. subSpellName .. ")") then
       return id;
      end
      if (spell == spellName) then
        idd=id;
      end   
    else
      do break end
    end
    id = id + 1;
  end
  if idd>0 then
    return idd
  else
    return nil;
  end
end

function HealBot_ClearIncHeal()
    if HealBot_HealValue > 0 then
      for j in pairs(HealBot_IamHealing) do
        HealBot_SendAddonMsg(HEALBOT_ADDON_ID, ">> "..0-HealBot_HealValue.." <<=>> "..HealBot_IamHealing[j])
        HealBot_IamHealing[j] = nil;
      end    
      HealBot_HealValue=0;
    end
end

function HealBot_StopCasting()
  HealBot_ClearIncHeal();
  HealBot_CastingSpell  = nil;
  HealBot_CastingTarget = nil;
end


local HealBot_Health60 = {
  [HEALBOT_DRUID]   = 3500,
  [HEALBOT_HUNTER]    = 2500,
  [HEALBOT_MAGE]  = 3500,
  [HEALBOT_PALADIN] = 4000,
  [HEALBOT_PRIEST]  = 2500,
  [HEALBOT_ROGUE]   = 3500,
  [HEALBOT_SHAMAN]  = 3800,
  [HEALBOT_WARLOCK] = 3500,
  [HEALBOT_WARRIOR] = 5000,
}
function HealBot_UnitHealth(unit)
  local Current,Desired = UnitHealth(unit),UnitHealthMax(unit);
  if unit=='target' and Desired==100 then
    local Member_Name=UnitName(unit);
    local class,level = HealBot_UnitClass[Member_Name],HealBot_UnitLevel[Member_Name];
    if HealBot_Health60[class] and level>0 then
      Desired = math.floor(HealBot_Health60[class]/60*level+0.5)
    else
      Desired = UnitHealthMax('player');
    end
    Current = Desired/100*Current;
  end
  return Current,Desired;
end

-- TBD: use the event UNIT_AURA to keep track instead of querying each time

function HealBot_UnitAffected(unit,effect)
  if not effect then return nil; end
  local i = 1
  while true do
    local name, tmp, buff = UnitBuff(unit,i)
    if not buff then
      do break end
    end
    if name==effect then
      return name
    end
    i = i + 1
  end
  return nil;
end

function HealBot_FindHealSpells()
  local id = 1;
  if InitSpells then NeedEquipUpdate=1; return; end
  local SpiBonus = 0;
  
  HealBot_HealingBonus=GetSpellBonusHealing();
  if (HealBot_PlayerClassEN=="PRIEST") then
     SpiBonus = HealBot_SpiBonus();
  end
        
  table.foreach(HealBot_CurrentSpells, function (index,spell)
    if (HealBot_Spells[spell]) then
      if CalcEquipBonus then
        if HealBot_Spells[spell].NoBonus then
          HealBot_Spells[spell].RealHealing = 0
        else
          local healingbonus_penalty=1;
          if HealBot_Spells[spell].Level < 20 then
            healingbonus_penalty=(1-((20-HealBot_Spells[spell].Level)*0.0375));
          end
          local temp_Spell_cast=3;
          if HealBot_Spells[spell].Cast == 0 then
            temp_Spell_cast=3;
          end
          if HealBot_Spells[spell].Cast >= 1.5 and HealBot_Spells[spell].Cast < 3 then
            temp_Spell_cast=HealBot_Spells[spell].Cast;
          end
        
          RealHealing = ((HealBot_HealingBonus * healingbonus_penalty) * (temp_Spell_cast/3));
          local tmp = ((HealBot_Spells[spell].Level)+6)/(UnitLevel("player"))
          if tmp<1 then RealHealing=RealHealing*tmp; end
          RealHealing = RealHealing + ((SpiBonus * healingbonus_penalty) * (temp_Spell_cast/3));
          HealBot_Spells[spell].RealHealing = floor(RealHealing);
        end
      end
      HealBot_Spells[spell].HealsDur = floor((HealBot_Spells[spell].HealsCast+HealBot_Spells[spell].HealsExt) + HealBot_Spells[spell].RealHealing);
    end
  end);

  if CalcEquipBonus then
    HealBot_AddDebug("...Done Equip Bonus:"..HealBot_HealingBonus);
  end
  CalcEquipBonus=false;
end

function HealBot_GetShapeshiftForm()
  local forms = GetNumShapeshiftForms();
  if forms then
    local i;
    for i=1,forms do
      local icon,name,active = GetShapeshiftFormInfo(i);
      if active then return i; end
    end
  end
  return 0;
end

function HealBot_GetHealSpell(unit,pattern)
  local id;
  local spellname
  local Member_Name=UnitName(unit);
  
  if not HealBot_PlayerCanCast or HealBot_PlayerDead then return nil end;
 
--  if HealBot_PlayerClassEN=="DRUID" then
--    if HealBot_GetShapeshiftForm() then return nil end; 
--  end    
  if DruidInForm==2 then return nil end;
  
  if not HealBot_Spells[pattern] then
    id = HealBot_GetSpellId(pattern);
  elseif HealBot_Spells[pattern].id then
    id = HealBot_Spells[pattern].id
  else
    id = HealBot_GetSpellId(pattern);
  end
  local spell, spellrank = HealBot_GetSpellName(id)
  if not spell then 
    if pattern then
      if Member_Name~=HealBot_PlayerName then
        if IsItemInRange(pattern,unit)~=1 then
          return nil
        else
          return pattern;
        end
      else
        local usable, noMana = IsUsableItem(pattern, unit)
        if not usable then 
          return nil
        else
          return pattern;
        end
      end
    else
      return nil
    end
  end

  if spellrank then
    spellname=spell;
    spell=spell .. "(" .. spellrank .. ")";
  end

  if not HealBot_InnerFocus then
    if HealBot_Spells[spell] then
      if HealBot_Spells[spell].Mana>UnitMana("player") then return nil end;
      if DruidInForm==1 and HealBot_Spells[spell].CastTime>0 then return nil end;
    elseif HealBot_OtherSpells[spell] then
      if HealBot_OtherSpells[spell].Mana>UnitMana("player") then return nil end;
      if DruidInForm==1 and HealBot_OtherSpells[spell].CastTime>0 then return nil end;
    end
  end

  if Member_Name~=HealBot_PlayerName then
    if spellname==HEALBOT_PRAYER_OF_HEALING then
      if UnitInParty(unit) then
        if IsSpellInRange(HEALBOT_CURE_DISEASE, unit)~=1 then return nil end;
      else
        return nil;
      end
    else
      if IsSpellInRange(spell, unit)~=1 then return nil end;
    end  
  end
  return spell;
end

function HealBot_RecalcHeals(unit)
  HealBot_Action_Refresh(unit);
end

function HealBot_RecalcParty(HealBot_PreCombat)
  HealBot_Action_PartyChanged(HealBot_PreCombat);
end

function HealBot_RecalcSpells()
  HealBot_FindHealSpells();
--  HealBot_RecalcParty();
end

--------------------------------------------------------------------------------------------------
-- OnFoo functions
--------------------------------------------------------------------------------------------------

function HealBot_OnLoad(this)
  HealBot_PlayerClass, HealBot_PlayerClassEN=UnitClass("player")
--  if HealBot_PlayerClassEN=="PRIEST" or HealBot_PlayerClassEN=="DRUID" or HealBot_PlayerClassEN=="PALADIN" or HealBot_PlayerClassEN=="SHAMAN" then
    HealBot_PlayerName=UnitName("Player");
    this:RegisterEvent("VARIABLES_LOADED");
    this:RegisterEvent("PLAYER_ENTERING_WORLD");
    this:RegisterEvent("PLAYER_LEAVING_WORLD");
    SLASH_HEALBOT1 = "/healbot";
    SLASH_HEALBOT2 = "/hb";
    SlashCmdList["HEALBOT"] = function(msg)
      HealBot_SlashCmd(msg);
    end
    HealBot_AddError(HEALBOT_ADDON .. HEALBOT_LOADED);
--  else
--    HealBot_AddError(HEALBOT_ADDON .. " Not loaded - Not a healer");
--  end
end

function HealBot_RegisterThis(this)

end 

local HealBot_Timer1,HealsIn_Timer, HealBot_Timer2 = 0,0,0;
function HealBot_OnUpdate(this,arg1)
  if HealBot_Config.DisableHealBot==1 then return; end
  HealBot_Timer1 = HealBot_Timer1+arg1;
  HealBot_Timer2 = HealBot_Timer2+arg1;
  if HealBot_Timer2>=HealBot_Config.RangeCheckFreq then
    HealBot_Timer2=0;
    if HealBot_DelayData==0 and HealBot_PlayerCanCast then
      HealBot_RecalcHeals();
    end
  end
  if HealBot_Timer1>=1.0 then
    HealBot_Timer1 = 0;
	local i=0;
    if not HealBot_IsFighting then
      for unit,_ in pairs(HealBot_DelayDebuffCheck) do
  	    i=i+1
        HealBot_CheckUnitDebuffs(unit)
        HealBot_DelayDebuffCheck[unit] = nil;
        if i>3 then 
	      do break end;
	    end
      end
      for unit,_ in pairs(HealBot_DelayBuffCheck) do
        if i>2 then 
		  do break end;
		end
        HealBot_CheckUnitBuffs(unit)
        HealBot_DelayBuffCheck[unit] = nil;
	    i=i+1
      end
      HealsIn_Timer=HealsIn_Timer+1;
	  if HealsIn_Timer>=75 then
--        HealBot_HealsIn={};
--        HealBot_Healers={};
	    HealsIn_Timer=0;
        collectgarbage (collect)
      end
	  if Delay_RecalcParty>0 then
        Delay_RecalcParty=Delay_RecalcParty+1
        if Delay_RecalcParty>3 then
          Delay_RecalcParty=0;
          HealBot_RecalcParty();
        end
      elseif FlagEquipUpdate1>0 and FlagEquipUpdate2>0 then
	    FlagEquipUpdate1=0;
	    FlagEquipUpdate2=0;
	    NeedEquipUpdate=1;
	  elseif FlagEquipUpdate1>0 then
	    FlagEquipUpdate1=FlagEquipUpdate1+1;
        if FlagEquipUpdate1>5 then
	      FlagEquipUpdate1=0;
	    end
      elseif FlagEquipUpdate2>0 then
	    FlagEquipUpdate2=FlagEquipUpdate2+1;
        if FlagEquipUpdate2>5 then
	      FlagEquipUpdate2=0;
          HealBot_Options_Debuff_Reset();
	    end
      elseif InitSpells then
          InitSpells=false;
          local cnt=HealBot_InitSpells();
          NeedEquipUpdate=1;
      elseif NeedEquipUpdate>0 then
        NeedEquipUpdate=NeedEquipUpdate+1;
        if NeedEquipUpdate>5 then
          CalcEquipBonus=true;
          NeedEquipUpdate=0; 
          HealBot_RecalcSpells();
        end          
      elseif CheckForDivineSpirit then
        CheckForDivineSpirit=false
        local HasDS=0;
        local i=1;
        while true do
          local name, rank, icon, count, type = UnitBuff("player",i) 
          if name then
            if name==HEALBOT_DIVINE_SPIRIT or name==HEALBOT_PRAYER_OF_SPIRIT then
              HasDS=1;
              do break end;
            end
            i = i + 1;
          else
            do break end
          end
        end
        if HasDS~=HasDivineSpirit then
          HasDivineSpirit=HasDS;
          NeedEquipUpdate=1;
        end
      end
    else
	  HealsIn_Timer=0;
    end
    HealBot_SpamCnt = 0;
    if HealBot_RequestVer then
      HealBot_SendAddonMsg("HealBot", ">> SendVersion <<=>> "..HealBot_RequestVer.." <<=>> Version="..HEALBOT_VERSION)
      HealBot_RequestVer=nil;
    end
    if HealBot_DelayData>0 then
      if HealBot_DelayData==4 then
        HealBot_DelayData=0;
        if HealBot_Config.BuffWatch==1 then 
          HealBot_DelayBuffCheck["player"]=true;
          HealBot_DelayDebuffCheck["player"]=true;
        end
        if HealBot_PlayerClassEN=="PRIEST" then HealBot_HasInnerFocus(); end
        HealBot_PlayerCanCast=true;
        CheckForDivineSpirit=true;
        Delay_RecalcParty=1;
      elseif HealBot_DelayData==3 then
        HealBot_Options_Buff_Reset();
        HealBot_DelayData=HealBot_DelayData+1;
      elseif HealBot_DelayData==2 then
        HealBot_Options_Debuff_Reset();
        HealBot_DelayData=HealBot_DelayData+1;
      elseif HealBot_DelayData==1 then
        HealBot_Options_EmergencyFilter_Reset()
        HealBot_DelayData=HealBot_DelayData+1;
      end
    end
    
    for j in pairs(HealBot_Ressing) do
      if HealBot_Ressing[j]=="_NIL_" then 
        HealBot_Ressing[j]=nil;
      elseif HealBot_Ressing[j]=="_RESSED2_" then 
        HealBot_Ressing[j]="_NIL_";
      elseif HealBot_Ressing[j]=="_RESSED1_" then 
        HealBot_Ressing[j]="_RESSED2_";
      elseif HealBot_Ressing[j]=="_RESSED_" then 
        HealBot_Ressing[j]="_RESSED1_";
      end
    end
    
    for k in pairs(HealBot_HoT1) do
      HealBot_HoT1[k]=HealBot_HoT1[k]-1; 
      if HealBot_HoT1[k]<10 then
         HealBot_HoT_Update(1, HealBot_HoT1[k], k)    
      end
    end
    for k in pairs(HealBot_HoT2) do
      HealBot_HoT2[k]=HealBot_HoT2[k]-1; 
      if HealBot_HoT2[k]<10 then
         HealBot_HoT_Update(2, HealBot_HoT2[k], k)    
      end
    end
    for k in pairs(HealBot_HoT3) do
      HealBot_HoT3[k]=HealBot_HoT3[k]-1; 
      if HealBot_HoT3[k]<10 then
         HealBot_HoT_Update(3, HealBot_HoT3[k], k)    
      end
    end

    for k in pairs(HealBot_HoT_Waiting) do
      HealBot_HoT_Waiting[k]=HealBot_HoT_Waiting[k]-1; 
      if HealBot_HoT_Waiting[k]<=0 then
         HealBot_HoT_Waiting[k]=nil   
         HealBot_HoT_WaitingSpell[k]=nil         
         HealBot_HoT_WaitingSpellName[k]=nil 
       end
    end

  end
end

function HealBot_OnEvent(this, event, arg1,arg2,arg3,arg4)
  if HealBot_Config.DisableHealBot==1 then return; end
  if (event=="CHAT_MSG_ADDON") then
    HealBot_OnEvent_AddonMsg(this,arg1,arg2,arg3,arg4);
  elseif (event=="UNIT_HEALTH") then
    HealBot_OnEvent_UnitHealth(this,arg1);
  elseif (event=="UNIT_MANA") then
    HealBot_OnEvent_UnitMana(this,arg1);
  elseif (event=="UNIT_RAGE") then
    HealBot_OnEvent_UnitMana(this,arg1);
  elseif (event=="UNIT_ENERGY") then
    HealBot_OnEvent_UnitMana(this,arg1);
  elseif (event=="UNIT_AURA") then
    HealBot_OnEvent_UnitAura(this,arg1);
  elseif (event=="MODIFIER_STATE_CHANGED") then
    HealBot_OnEvent_ModifierStateChange(this,arg1,arg2);
  elseif (event=="UNIT_SPELLCAST_SENT") then
    HealBot_OnEvent_UnitSpellcastSent(this,arg1,arg2,arg3,arg4);  
  elseif (event=="UNIT_NAME_UPDATE") then
    HealBot_OnEvent_UnitNameUpdate(this,arg1);
  elseif (event=="UNIT_SPELLCAST_STOP") then
    HealBot_OnEvent_UnitSpellcastStop(this,arg1);
  elseif (event=="UNIT_SPELLCAST_FAILED") then
    HealBot_OnEvent_UnitSpellcastStop(this,arg1);
  elseif (event=="UNIT_SPELLCAST_INTERRUPTED") then
    HealBot_OnEvent_UnitSpellcastStop(this,arg1);
  elseif (event=="UNIT_SPELLCAST_SUCCEEDED") then
    HealBot_OnEvent_UnitSpellcastStop(this,arg1);
  elseif (event=="PLAYER_REGEN_DISABLED") then
    HealBot_OnEvent_PlayerRegenDisabled(this);
  elseif (event=="PLAYER_REGEN_ENABLED") then
    HealBot_OnEvent_PlayerRegenEnabled(this);
  elseif (event=="CHAT_MSG_SYSTEM") then
    HealBot_OnEvent_SystemMsg(this,arg1);
  elseif (event=="PARTY_MEMBERS_CHANGED") then
    HealBot_OnEvent_PartyMembersChanged(this);
  elseif (event=="PLAYER_TARGET_CHANGED") then
    HealBot_OnEvent_PlayerTargetChanged(this);
  elseif (event=="PLAYER_CONTROL_LOST") then
    HealBot_OnEvent_PlayerControlLost(this);
  elseif (event=="PLAYER_CONTROL_GAINED") then
    HealBot_OnEvent_PlayerControlGained(this);
  elseif (event=="UPDATE_INVENTORY_ALERTS") then
    HealBot_OnEvent_PlayerEquipmentChanged(this);
  elseif (event=="UNIT_INVENTORY_CHANGED") then
    HealBot_OnEvent_PlayerEquipmentChanged2(this,arg1);
  elseif (event=="UNIT_PET") then
    HealBot_OnEvent_PartyPetChanged(this);
  elseif (event=="SPELLS_CHANGED") then
    HealBot_OnEvent_SpellsChanged(this,arg1);
  elseif (event=="PLAYER_ENTERING_WORLD") then
    HealBot_OnEvent_PlayerEnteringWorld(this);
  elseif (event=="PLAYER_LEAVING_WORLD") then
    HealBot_OnEvent_PlayerLeavingWorld(this);
  elseif (event=="CHARACTER_POINTS_CHANGED") then
    HealBot_OnEvent_TalentsChanged(this, arg1);
  elseif (event=="ZONE_CHANGED_NEW_AREA") then
    HealBot_OnEvent_ZoneChanged(this);
  elseif (event=="VARIABLES_LOADED") then
    HealBot_OnEvent_VariablesLoaded(this);
  else
    HealBot_AddDebug("OnEvent (" .. event .. ")");
  end
end

function HealBot_OnEvent_VariablesLoaded(this)
    table.foreach(HealBot_ConfigDefaults, function (key,val)
      if not HealBot_Config[key] then
        HealBot_Config[key] = val;
      end
    end);
    if HealBot_Config.AutoClose==0 then HealBot_Config.ActionVisible=1; end
    if HealBot_Config.ActionVisible==1 then HealBot_Action:Show() end
    if HealBot_Config.HidePartyFrames==1 then
      HealBot_Options_DisablePartyFrame()
    end
    if HealBot_Config.HidePlayerTarget==1 then
      HealBot_Options_DisablePlayerFrame()
      HealBot_Options_DisablePetFrame()
      HealBot_Options_DisableTargetFrame()
    end
    HealBot_InitData();
    InitSpells=true;
    HealBot_Loaded=true;
    HealBot_Register_Events();
    HealBot_Action_ResetSkin();
end

function HealBot_Register_Events()
 if HealBot_Config.DisableHealBot==0 then
    this:RegisterEvent("ZONE_CHANGED_NEW_AREA");
    this:RegisterEvent("PLAYER_REGEN_DISABLED");
    this:RegisterEvent("PLAYER_REGEN_ENABLED");
    this:RegisterEvent("PLAYER_TARGET_CHANGED");
    this:RegisterEvent("PARTY_MEMBERS_CHANGED");
    this:RegisterEvent("UNIT_HEALTH");
    this:RegisterEvent("UNIT_MANA");
    this:RegisterEvent("UNIT_RAGE");
    this:RegisterEvent("UNIT_ENERGY");
    this:RegisterEvent("SPELLS_CHANGED");
    this:RegisterEvent("UNIT_SPELLCAST_SENT");
--    this:RegisterEvent("UNIT_SPELLCAST_START");
    this:RegisterEvent("UNIT_SPELLCAST_STOP");
    this:RegisterEvent("UNIT_SPELLCAST_FAILED");
    this:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED");
    this:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED");
    this:RegisterEvent("UNIT_AURA");
    this:RegisterEvent("CHARACTER_POINTS_CHANGED");
    this:RegisterEvent("UPDATE_INVENTORY_ALERTS");
    this:RegisterEvent("UNIT_INVENTORY_CHANGED");
    this:RegisterEvent("CHAT_MSG_ADDON");
    this:RegisterEvent("CHAT_MSG_SYSTEM");
    this:RegisterEvent("MODIFIER_STATE_CHANGED");
    this:RegisterEvent("PLAYER_CONTROL_LOST");
    this:RegisterEvent("PLAYER_CONTROL_GAINED");
    this:RegisterEvent("UNIT_PET");
    this:RegisterEvent("UNIT_NAME_UPDATE");
--    this:RegisterEvent("PARTY_MEMBER_DISABLE");
--    this:RegisterEvent("PARTY_MEMBER_ENABLE");
    HealBot_SendAddonMsg("CTRA", "SR")
  end
end

function HealBot_UnRegister_Events()
    
    this:UnregisterEvent("ZONE_CHANGED_NEW_AREA");
    this:UnregisterEvent("PLAYER_REGEN_DISABLED");
    this:UnregisterEvent("PLAYER_REGEN_ENABLED");
    this:UnregisterEvent("PLAYER_TARGET_CHANGED");
    this:UnregisterEvent("PARTY_MEMBERS_CHANGED");
    this:UnregisterEvent("UNIT_HEALTH");
    this:UnregisterEvent("UNIT_MANA");
    this:UnregisterEvent("UNIT_RAGE");
    this:UnregisterEvent("UNIT_ENERGY");
    this:UnregisterEvent("SPELLS_CHANGED");
    this:UnregisterEvent("UNIT_SPELLCAST_SENT");
--    this:UnregisterEvent("UNIT_SPELLCAST_START");
    this:UnregisterEvent("UNIT_SPELLCAST_STOP");
    this:UnregisterEvent("UNIT_SPELLCAST_FAILED");
    this:UnregisterEvent("UNIT_SPELLCAST_INTERRUPTED");
    this:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED");
    this:UnregisterEvent("UNIT_AURA");
    this:UnregisterEvent("CHARACTER_POINTS_CHANGED");
    this:UnregisterEvent("UPDATE_INVENTORY_ALERTS");
    this:UnregisterEvent("UNIT_INVENTORY_CHANGED");
    this:UnregisterEvent("CHAT_MSG_ADDON");
    this:UnregisterEvent("CHAT_MSG_SYSTEM");
    this:UnregisterEvent("MODIFIER_STATE_CHANGED");
    this:UnregisterEvent("PLAYER_CONTROL_LOST");
    this:UnregisterEvent("PLAYER_CONTROL_GAINED");
    this:UnregisterEvent("UNIT_PET");
    this:UnregisterEvent("UNIT_NAME_UPDATE");
--    this:UnregisterEvent("PARTY_MEMBER_DISABLE");
--    this:UnregisterEvent("PARTY_MEMBER_ENABLE");
end

function HealBot_OnEvent_AddonMsg(this,addon_id,msg,dist_target,sender_id)
  local inc_msg = string.gsub(msg, "%$", "s");
  inc_msg = string.gsub(inc_msg, "§", "S");
  if addon_id==HEALBOT_ADDON_ID then
    local tmpTest, unitname, heal_val
	tmpTest,tmpTest,heal_val,unitname = string.find(inc_msg, ">> (.%d+) <<=>> (.+)$" );
	if heal_val then
      if not HealBot_HealsIn[unitname] then
		HealBot_HealsIn[unitname]=0;
      end
      if tonumber(heal_val)>0 then
        HealBot_Healers[sender_id] = ">> "..heal_val.." <<=>> "..unitname;
      else
        HealBot_Healers[sender_id] = nil;
      end
      HealBot_HealsIn[unitname] = HealBot_HealsIn[unitname] + tonumber(heal_val);
      if tonumber(heal_val) > 0 then
        HealBot_RecalcHeals(HealBot_UnitID[unitname])
	  elseif HealBot_HealsIn[unitname] < 0 then
	    HealBot_HealsIn[unitname]=0;
      end
    end
  elseif addon_id=="HealBot" then
    local tmpTest, datatype, datamsg, sender
    local PName=UnitName("player");
    tmpTest, tmpTest, datatype, sender, datamsg = string.find(inc_msg, ">> (%a+) <<=>> (%a+) <<=>> (.+)");
    if datatype=="RequestVersion" then
      HealBot_RequestVer=sender;
    elseif datatype=="SendVersion" and PName==sender then
      HealBot_AddChat(sender_id..":  "..datamsg);
    end
  elseif addon_id=="CTRA" then
    if ( string.find(inc_msg, "#") ) then
      local arr = HealBot_Split(inc_msg, "#");
      for k in pairs(arr) do
        HealBot_ParseCTRAMsg(sender_id, arr[k]);
      end
    else
        HealBot_ParseCTRAMsg(sender_id, inc_msg);
    end
--   HealBot_AddDebug("CTRA msg: "..inc_msg)
  end
end

function HealBot_Split(msg, char)
	local arr = { };
	while (string.find(msg, char) ) do
		local iStart, iEnd = string.find(msg, char);
		tinsert(arr, strsub(msg, 1, iStart-1));
		msg = strsub(msg, iEnd+1, strlen(msg));
	end
	if ( strlen(msg) > 0 ) then
		tinsert(arr, msg);
	end
	return arr;
end

function HealBot_ParseCTRAMsg(sender_id, inc_msg)
    if ( strsub(inc_msg, 1, 3) == "RES" ) then
      if ( inc_msg == "RESNO" ) then
        for j in pairs(HealBot_Ressing) do
          if HealBot_Ressing[j]==sender_id then
            HealBot_Ressing[j] = "_RESSED_";
            break
          end
        end
      else
        local unitname, tmpTest
        tmpTest, tmpTest, unitname = string.find(inc_msg, "^RES (.+)$");
        if ( unitname ) then
          HealBot_Ressing[unitname] = sender_id;
          HealBot_RecalcHeals(HealBot_UnitID[unitname]);
         end
      end
    elseif ( strsub(inc_msg, 1, 4) == "SET " ) then
      local tmpTest, tmpTest, num, unitname = string.find(inc_msg, "^SET (%d+) (.+)$");
      if ( num and unitname ) then
        for k in pairs(HealBot_MainTanks) do
          if ( HealBot_MainTanks[k] == unitname ) then
            HealBot_MainTanks[k] = nil;
          end
        end
        HealBot_MainTanks[tonumber(num)] = unitname;
        Delay_RecalcParty=3;
      end
    elseif ( strsub(inc_msg, 1, 2) == "R " ) then
      local tmpTest, tmpTest, unitname = string.find(inc_msg, "^R (.+)$");
      if ( unitname ) then
        for k in pairs(HealBot_MainTanks) do
          if ( HealBot_MainTanks[k] == unitname ) then
            HealBot_MainTanks[k] = nil;
            Delay_RecalcParty=3;
          end
        end
      end
    end
end

function HealBot_Test_InComingMsg(addon_id,msg,dist_target,sender_id)
  local inc_msg = string.gsub(msg, "%$", "s");
  inc_msg = string.gsub(inc_msg, "§", "S");
  HealBot_AddDebug("id="..addon_id.."  msg="..inc_msg)
  if addon_id==HEALBOT_ADDON_ID then
    local tmpTest, unitname, heal_val
	tmpTest,tmpTest,heal_val,unitname = string.find(inc_msg, ">> (.%d+) <<=>> (.+)$" );
	if heal_val then
      if not HealBot_HealsIn[unitname] then
		HealBot_HealsIn[unitname]=0;
      end
      if tonumber(heal_val)>0 then
        HealBot_Healers[sender_id] = ">> "..heal_val.." <<=>> "..unitname;
      else
        HealBot_Healers[sender_id] = nil;
      end
      HealBot_HealsIn[unitname] = HealBot_HealsIn[unitname] + tonumber(heal_val);
      if tonumber(heal_val) > 0 then
        HealBot_AddDebug("recalc="..HealBot_UnitID[unitname].."  add="..heal_val)
        HealBot_RecalcHeals(HealBot_UnitID[unitname])
	  elseif HealBot_HealsIn[unitname] < 0 then
	    HealBot_HealsIn[unitname]=0;
      end
    end
  elseif addon_id=="HealBot" then
    local tmpTest, datatype, datamsg, sender
    local PName=UnitName("player");
    tmpTest, tmpTest, datatype, sender, datamsg = string.find(inc_msg, ">> (%a+) <<=>> (%a+) <<=>> (.+)");
    if datatype=="RequestVersion" then
      HealBot_RequestVer=sender;
    elseif datatype=="SendVersion" and PName==sender then
      HealBot_AddChat(sender_id..":  "..datamsg);
    end
  elseif addon_id=="CTRA" then
    if ( string.find(inc_msg, "#") ) then
      local arr = HealBot_Split(inc_msg, "#");
      for k in pairs(arr) do
        HealBot_ParseCTRAMsg(sender_id, arr[k]);
      end
    else
        HealBot_ParseCTRAMsg(sender_id, inc_msg);
    end
--   HealBot_AddDebug("CTRA msg: "..inc_msg)
  end
end

function HealBot_OnEvent_UnitHealth(this,unit)
    if (not HealBot_UnitName[unit]) then return end
    HealBot_RecalcHeals(unit);
    if unit==HealBot_Action_TooltipUnit then
      HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit);
    elseif unit==HealBot_Action_DisableTooltipUnit then
      HealBot_Action_RefreshDisabledTooltip(HealBot_Action_DisableTooltipUnit);
    end
end

function HealBot_OnEvent_UnitMana(this,unit)
  local Member_Name=UnitName(unit);
  if Member_Name==HealBot_PlayerName then
    if HealBot_Action_TooltipUnit then
       HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit);
    elseif HealBot_Action_DisableTooltipUnit then
       HealBot_Action_RefreshDisabledTooltip(HealBot_Action_DisableTooltipUnit);
    end
  end
  if Member_Name then 
    HealBot_Action_RefreshBar3(unit)
  end
end

function HealBot_OnEvent_ModifierStateChange(this,arg1,arg2)
  if HealBot_Action_TooltipUnit then
    HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit);
  elseif HealBot_Action_DisableTooltipUnit then
    HealBot_Action_RefreshDisabledTooltip(HealBot_Action_DisableTooltipUnit);
  end
end

function HealBot_OnEvent_ZoneChanged(this)
--  if HealBot_Loaded then
--    Delay_RecalcParty=2;
--  end
end

function HealBot_OnEvent_UnitAura(this,unit)
  local Member_Name=UnitName(unit);
  
  if HealBot_Config.DebuffWatch==1 and Member_Name and unit~="target" then
    if HealBot_Config.DebuffWatchInCombat==0 then
      if not HealBot_IsFighting then 
        HealBot_CheckUnitDebuffs(unit);
      else
        HealBot_DelayDebuffCheck[unit]=true;
      end
    else
      HealBot_CheckUnitDebuffs(unit);
    end
  end
  if HealBot_Config.BuffWatch==1 and Member_Name and unit~="target" then 
    if HealBot_Config.BuffWatchInCombat==0 then
      if not HealBot_IsFighting then 
        HealBot_CheckUnitBuffs(unit);
      else
        HealBot_DelayBuffCheck[unit]=true;
      end
    else
      HealBot_CheckUnitBuffs(unit);
    end
  end
  
  if Member_Name==HealBot_PlayerName then
    if HealBot_PlayerClassEN=="PRIEST" then
      CheckForDivineSpirit=true;
      if HealBot_InnerFocusTalent then HealBot_CheckForInnerFocus(); end
    elseif HealBot_PlayerClassEN=="DRUID" then
      local i=HealBot_GetShapeshiftForm();
      if i==0 then
        DruidInForm=0;
      elseif i==5 then
        DruidInForm=1;
      else
        DruidInForm=2;
      end
    end
  end
  
  if unit==HealBot_Action_TooltipUnit then
    HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit);
  elseif unit==HealBot_Action_DisableTooltipUnit then
    HealBot_Action_RefreshDisabledTooltip(HealBot_Action_DisableTooltipUnit);
  end
  
  if HealBot_HoT1[Member_Name] then
    local HoTActive=HealBot_CheckForHoT(HealBot_HoT1_Spell[Member_Name], unit)
    if not HoTActive then 
      HealBot_HoT1[Member_Name]=0 
      HealBot_HoT_Update(1, HealBot_HoT1[Member_Name], Member_Name)    
    end
  end

  if HealBot_HoT2[Member_Name] then
    local HoTActive=HealBot_CheckForHoT(HealBot_HoT2_Spell[Member_Name], unit)
    if not HoTActive then 
      HealBot_HoT2[Member_Name]=0 
      HealBot_HoT_Update(2, HealBot_HoT2[Member_Name], Member_Name)    
    end
  end

  if HealBot_HoT3[Member_Name] then
    local HoTActive=HealBot_CheckForHoT(HealBot_HoT3_Spell[Member_Name], unit)
    if not HoTActive then 
      HealBot_HoT3[Member_Name]=0 
      HealBot_HoT_Update(3, HealBot_HoT3[Member_Name], Member_Name)    
    end
  end  

  if HealBot_HoT_Waiting[Member_Name] then
    local HoTActive=HealBot_CheckForHoT(HealBot_HoT_WaitingSpellName[Member_Name], unit)
    if HoTActive then
      HealBot_HoT_Update(nil, HealBot_Spells[HealBot_HoT_WaitingSpell[Member_Name]].Duration, Member_Name, HealBot_HoT_WaitingSpellName[Member_Name])
      HealBot_HoT_Waiting[Member_Name]=nil   
      HealBot_HoT_WaitingSpell[Member_Name]=nil         
      HealBot_HoT_WaitingSpellName[Member_Name]=nil 
    end
  end  
  
end

function HealBot_CheckForInnerFocus()
  local i=1;
  HealBot_InnerFocus=false;
  while true do
    local name, rank, buff, tmp, debuff_type = UnitBuff("player",i)
    i=i+1
    if name then
      if name==HEALBOT_INNER_FOCUS then
        HealBot_InnerFocus=true;
        do break end;
      end
    else
      do break end;
    end
  end
end

function HealBot_CheckForHoT(HoTname, unit)
  local i=1;
  local retValue=false;
  while true do
    local name, rank, buff, tmp, debuff_type = UnitBuff(unit,i,1)
    i=i+1
    if name then
      if name==HoTname then
        return true;
      end
    else
      do break end;
    end
  end
  return retValue
end

function HealBot_CheckAllBuffs()
  if HealBot_Config.BuffWatch==1 then 
    HealBot_DelayBuffCheck = {};
    for unit in pairs(HealBot_UnitName) do
       if unit~="target" then
         HealBot_DelayBuffCheck[unit]=true;
       end
    end
  end
end

function HealBot_CheckAllDebuffs()
  if HealBot_Config.DebuffWatch==1 then 
    HealBot_DelayDebuffCheck = {};
    for unit in pairs(HealBot_UnitName) do
       if unit~="target" then
         HealBot_DelayDebuffCheck[unit]=true;
       end
    end
  end
end

function HealBot_CheckUnitDebuffs(unit)
  local i = 1;
  local Member_Name=UnitName(unit);
  local DebuffType=nil;
  if not Member_Name then return; end
  if not HealBot_UnitClass[Member_Name] then return; end
  while true do
    local name, rank, debuff, tmp, debuff_type = UnitDebuff(unit,i)
    if name then
      i = i + 1;
      local checkthis=false;
      local WatchTarget=HealBot_DebuffWatchTarget[debuff_type];
      if WatchTarget then 
        if WatchTarget["Self"] and Member_Name==HealBot_PlayerName then
          checkthis=true;
        elseif WatchTarget["Raid"] then
          checkthis=true;
        elseif WatchTarget["Party"] and (UnitInParty(unit) or Member_Name==HealBot_PlayerName) then
          checkthis=true;
        elseif WatchTarget[HealBot_UnitClass[Member_Name]]  then
          checkthis=true;
        end
       
        if checkthis then
          local ProcessThis=true;
          if HealBot_Config.IgnoreMovementDebuffs==1 then
            if HealBot_Ignore_Movement_Debuffs[name] then
              ProcessThis=false;
            end
          end
          if HealBot_Config.IgnoreFastDurDebuffs==1 and ProcessThis then
            if HealBot_Ignore_FastDur_Debuffs[name] then
              ProcessThis=false;
            end
          end
          if HealBot_Config.IgnoreNonHarmfulDebuffs==1 and ProcessThis then
            if HealBot_Ignore_NonHarmful_Debuffs[name] then
              ProcessThis=false;
            end
          end
          if HealBot_Config.IgnoreClassDebuffs==1 and ProcessThis then
            local HealBot_Ignore_Debuffs_Class=HealBot_Ignore_Class_Debuffs[HealBot_UnitClass[Member_Name]];
            if HealBot_Ignore_Debuffs_Class[name] then
              ProcessThis=false;
            end
          end
          if ProcessThis then
            HealBot_UnitDebuff[Member_Name]=debuff_type
            HealBot_UnitDebuff[Member_Name.."_debuff_name"]=name
            DebuffType=debuff_type;
            if HealBot_DebuffPriority==debuff_type then
              do break end
            end
          end
        end
      end
    else
      if not DebuffType then 
       if HealBot_UnitDebuff[Member_Name] then
		  HealBot_UnitDebuff[Member_Name] = nil; 
		  HealBot_RecalcHeals(unit);
	    end
      end
      do break end
    end 
  end

  if HealBot_UnitDebuff[Member_Name] then
    if DebuffType and (IsSpellInRange(HealBot_DebuffSpell[HealBot_UnitDebuff[Member_Name]], unit)==1 or Member_Name==HealBot_PlayerName) then
      if HealBot_Config.ShowDebuffWarning==1 then
        UIErrorsFrame:AddMessage(Member_Name.." suffers from "..HealBot_UnitDebuff[Member_Name.."_debuff_name"], 
                                 HealBot_Config.CDCBarColour[DebuffType].R,
                                 HealBot_Config.CDCBarColour[DebuffType].G,
                                 HealBot_Config.CDCBarColour[DebuffType].B,
                                 1, UIERRORS_HOLD_TIME);
      end
      if HealBot_Config.SoundDebuffWarning==1 then HealBot_PlaySound(HealBot_Config.SoundDebuffPlay); end
    end
    HealBot_RecalcHeals(unit);
  end
end

function HealBot_CheckUnitBuffs(unit)

    local buffname;
    local Member_Name=UnitName(unit);
    if not Member_Name then return; end
    if not HealBot_UnitClass[Member_Name] then return; end
    local PlayerBuffs = {};
    local i = 1;

    while true do
      local name, rank, icon, count, type = UnitBuff(unit,i) 
      if name then
        PlayerBuffs[name]=true
        i = i + 1;
      else
        do break end
      end
    end 
     
     for k in pairs(HealBot_BuffWatch) do
       local checkthis=false;
       local WatchTarget=HealBot_BuffWatchTarget[HealBot_BuffWatch[k]];
       if WatchTarget["Self"] and Member_Name==HealBot_PlayerName then
         checkthis=true;
       elseif WatchTarget["Raid"] then
         checkthis=true;
       elseif WatchTarget["Party"] and (UnitInParty(unit) or Member_Name==HealBot_PlayerName) then
         checkthis=true;
       elseif WatchTarget[HealBot_UnitClass[Member_Name]]  then
         checkthis=true;
       end
       if checkthis then
         if not PlayerBuffs[HealBot_BuffWatch[k]] then
           checkthis=false;
           if HealBot_BuffNameSwap[HealBot_BuffWatch[k]] then
             checkthis=HealBot_BuffNameSwap[HealBot_BuffWatch[k]];
             if not PlayerBuffs[checkthis] then
               buffname=HealBot_BuffWatch[k];
               do break end
             end
           else
             buffname=HealBot_BuffWatch[k];
             do break end
           end
         end
       end
     end
     if buffname then
       HealBot_UnitBuff[Member_Name]=buffname;
       HealBot_RecalcHeals(unit);
     elseif HealBot_UnitBuff[Member_Name] then 
       HealBot_UnitBuff[Member_Name]=nil;
	   HealBot_RecalcHeals(unit);
     end
     
end


function HealBot_OnEvent_PlayerRegenDisabled(this)
--  if HealBot_Config.AutoClose==1 and HealBot_Config.ActionVisible~=0 then HideUIPanel(HealBot_Action); end;
  ShowUIPanel(HealBot_Action);
  HealBot_RecalcParty(true);
end

function HealBot_OnEvent_PlayerControlLost(this)
  HealBot_PlayerCanCast=false;
end

function HealBot_OnEvent_PlayerControlGained(this)
  HealBot_PlayerCanCast=true;
end

function HealBot_OnEvent_PlayerRegenEnabled(this)
  HealBot_IsFighting = false;
--  Delay_RecalcParty=3;
end

function HealBot_OnEvent_PlayerTargetChanged(this)
  if HealBot_Config.TargetHeals==1 then
    HealBot_RecalcParty();
  end
end

function HealBot_OnEvent_UnitNameUpdate(this,unit)
  HealBot_Action_ResetUnitStatus(unit)
end

function HealBot_OnEvent_PartyMembersChanged(this)
  Delay_RecalcParty=3;
end

function HealBot_OnEvent_PartyPetChanged(this)
  if HealBot_Config.TargetHeals==1 or HealBot_Config.PetHeals==1 then
    Delay_RecalcParty=3;
  end
end


function HealBot_OnEvent_SystemMsg(this,msg)
  if type(msg)=="string" then
    local tmpTest, tmpTest, deserter = string.find(msg, HB_HASLEFTRAID);
    if not deserter then
      local tmpTest, tmpTest, deserter = string.find(msg, HB_HASLEFTPARTY);
    end
    if deserter then
      if (HealBot_Healers[deserter]) then
        local tmpTest, unitname, heal_val, heal_valn
        tmpTest,tmpTest,unitname,heal_val = string.find(HealBot_Healers[deserter], ">> (.%d+) <<=>> (.+)$" );
        heal_valn=tonumber(heal_val)
        HealBot_Healers[deserter]=nil;
        HealBot_AddDebug("Healer "..deserter.." left the group - Last known activity was heal "..unitname.." for "..heal_val.." << trapped in event SystemMsg");
        if heal_valn>0 and HealBot_HealsIn[unitname] then
          HealBot_HealsIn[unitname] = HealBot_HealsIn[unitname] - heal_valn;
          if HealBot_HealsIn[unitname] < 0 then
	        HealBot_HealsIn[unitname]=0;
          end
        end
      end
    elseif msg==HB_YOULEAVETHEGROUP or msg==HB_YOULEAVETHERAID then
        Delay_RecalcParty=2;
    else
      -- find other messges
    end
  end
end

function HealBot_OnEvent_PlayerEquipmentChanged(this)
  FlagEquipUpdate1=1;
end

function HealBot_OnEvent_PlayerEquipmentChanged2(this,unit)
  if UnitName(unit)==HealBot_PlayerName then
    FlagEquipUpdate2=1;
  end
end

function HealBot_OnEvent_SpellsChanged(this, arg1)
  if arg1 then return; end
  if HealBot_TalentsChanged then
    InitSpells=true;
  end
end

function HealBot_OnEvent_TalentsChanged(this, arg1)
  HealBot_TalentsChanged=true;
  InitSpells=true;
  if HealBot_PlayerClassEN=="PRIEST" then HealBot_HasInnerFocus(); end
end

function HealBot_OnEvent_PlayerEnteringWorld(this)
  if HealBot_Loaded then
    HealBot_Register_Events();
  end
  if InCombatLockdown() then
    if not HealBot_Loaded then
      local cnt=HealBot_InitSpells();
      HealBot_RecalcSpells();
    end
    HealBot_DelayData=1;
    HealBot_RecalcParty(true);
  else
    if HealBot_IsFighting then 
      HealBot_IsFighting = false; 
    end
    HealBot_DelayData=1;
    Delay_RecalcParty=1;
  end
end

function HealBot_OnEvent_PlayerLeavingWorld(this)
  HealBot_PlayerCanCast=false;
  HealBot_RecalcHeals();
  HealBot_UnRegister_Events()
end

function HealBot_OnEvent_UnitSpellcastSent(this,caster,spellname,rank,target)
  if caster=="player" then
    local spell=spellname.."("..rank..")"
    if spellname==HEALBOT_RESURRECTION or spellname==HEALBOT_ANCESTRALSPIRIT or spellname==HEALBOT_REBIRTH or spellname==HEALBOT_REDEMPTION then
      HealBot_IamRessing = target;
      HealBot_ClearIncHeal();
      HealBot_IsCasting = true;
      if HealBot_IamRessing then
        HealBot_SendAddonMsg("CTRA", "RES "..HealBot_IamRessing)
      end
      HealBot_CastingSpell  = spell;
      HealBot_CastingTarget = HealBot_UnitID[target];
      if not HealBot_CastingTarget then HealBot_CastingTarget="target"; end
    elseif HealBot_Spells[spell] then
      HealBot_ClearIncHeal();
      HealBot_IsCasting = true;
      if HealBot_Spells[spell].CastTime>1 then
        HealBot_HealValue=HealBot_Spells[spell].HealsDur;
        if spellname==HEALBOT_BINDING_HEAL then
          HealBot_IamHealing[HealBot_UnitName["player"]]=HealBot_UnitName["player"];
          HealBot_IamHealing[target]=target;
        elseif spellname==HEALBOT_PRAYER_OF_HEALING then
          HealBot_IamHealing[HealBot_UnitName["player"]]=HealBot_UnitName["player"];
          if HealBot_UnitName["party1"] then
            if IsSpellInRange(HEALBOT_CURE_DISEASE, "party1")==1 then
              HealBot_IamHealing[HealBot_UnitName["party1"]]=HealBot_UnitName["party1"];
            end
          end
          if HealBot_UnitName["party2"] then
            if IsSpellInRange(HEALBOT_CURE_DISEASE, "party2")==1 then
              HealBot_IamHealing[HealBot_UnitName["party2"]]=HealBot_UnitName["party2"];
            end
          end
          if HealBot_UnitName["party3"] then
            if IsSpellInRange(HEALBOT_CURE_DISEASE, "party3")==1 then
              HealBot_IamHealing[HealBot_UnitName["party3"]]=HealBot_UnitName["party3"];
            end
          end
          if HealBot_UnitName["party4"] then
            if IsSpellInRange(HEALBOT_CURE_DISEASE, "party4")==1 then 
              HealBot_IamHealing[HealBot_UnitName["party4"]]=HealBot_UnitName["party4"];
            end
          end
          if HealBot_UnitName["partypet1"] then
            if IsSpellInRange(HEALBOT_CURE_DISEASE, "partypet1")==1 then
              HealBot_IamHealing[HealBot_UnitName["partypet1"]]=HealBot_UnitName["partypet1"];
            end
          end
          if HealBot_UnitName["partypet2"] then
            if IsSpellInRange(HEALBOT_CURE_DISEASE, "partypet2")==1 then
              HealBot_IamHealing[HealBot_UnitName["partypet2"]]=HealBot_UnitName["partypet2"];
            end
          end
          if HealBot_UnitName["partypet3"] then
            if IsSpellInRange(HEALBOT_CURE_DISEASE, "partypet3")==1 then
              HealBot_IamHealing[HealBot_UnitName["partypet3"]]=HealBot_UnitName["partypet3"];
            end
          end
          if HealBot_UnitName["partypet4"] then
            if IsSpellInRange(HEALBOT_CURE_DISEASE, "partypet4")==1 then
              HealBot_IamHealing[HealBot_UnitName["partypet4"]]=HealBot_UnitName["partypet4"];
            end
          end
        elseif target then
          HealBot_IamHealing[target]=target;
        end
        for j in pairs(HealBot_IamHealing) do
          HealBot_SendAddonMsg(HEALBOT_ADDON_ID, ">> "..HealBot_HealValue.." <<=>> "..HealBot_IamHealing[j])
--          HealBot_Test_InComingMsg(HEALBOT_ADDON_ID,">> "..HealBot_HealValue.." <<=>> "..HealBot_IamHealing[j],"RAID",HealBot_PlayerName)
    --      HealBot_AddDebug("I am also healing "..HealBot_IamHealing[j])
        end
      end
      if HealBot_Spells[spell].Duration>0 and HealBot_Config.ShowHoTicons==1 and HealBot_Unit_Button[target] then

        if HealBot_HoT1_Spell[target]==spellname then
          HealBot_HoT_Update(nil, HealBot_Spells[spell].Duration, target, spellname)
        elseif HealBot_HoT2_Spell[target]==spellname then
          HealBot_HoT_Update(nil, HealBot_Spells[spell].Duration, target, spellname)
        elseif HealBot_HoT3_Spell[target]==spellname then
          HealBot_HoT_Update(nil, HealBot_Spells[spell].Duration, target, spellname)
        else
          HealBot_HoT_Waiting[target]=HealBot_Spells[spell].CastTime+2;
          HealBot_HoT_WaitingSpell[target]=spell;
          HealBot_HoT_WaitingSpellName[target]=spellname;
        end
      end
      HealBot_CastingSpell  = spell;
      HealBot_CastingTarget = HealBot_UnitID[target];
      if not HealBot_CastingTarget then HealBot_CastingTarget="target"; end

      if HealBot_Config.CastNotify>1 then
        local Notify = HealBot_Config.CastNotify;
        local chanid=nil;
        if Notify==6 then
          chanid=HealBot_GetChan(HealBot_Config.NotifyChan) 
          if not chanid then Notify=2 end
        end
        if Notify==5 and GetNumRaidMembers()==0 then Notify = 4 end
        if Notify==4 and GetNumPartyMembers()==0 then Notify = 2 end
        if Notify==3 and not (UnitPlayerControlled(HealBot_CastingTarget) and HealBot_CastingTarget~='player' and HealBot_CastingTarget~='pet') then Notify = 2 end
        if Notify==3 then
          SendChatMessage(string.format(HEALBOT_CASTINGSPELLONYOU,spell),"WHISPER",nil,target);
        elseif Notify==4 then
          SendChatMessage(string.format(HEALBOT_CASTINGSPELLONUNIT,spell,target),"PARTY",nil,nil);
        elseif Notify==5 then
          SendChatMessage(string.format(HEALBOT_CASTINGSPELLONUNIT,spell,target),"RAID",nil,nil);
        elseif Notify==6 then
          SendChatMessage(string.format(HEALBOT_CASTINGSPELLONUNIT,spell,target),"CHANNEL",nil,chanid);
        else
          HealBot_AddChat(string.format(HEALBOT_CASTINGSPELLONUNIT,spell,target));
        end
      end
    end
    if HealBot_IsCasting then HealBot_RecalcHeals(); end
  end
end

function HealBot_Titan_Check()
  if HealBot_HealValue and HealBot_CastingTarget then
    return UnitName(HealBot_CastingTarget), HealBot_HealValue
  else
    return nil
  end
end

function HealBot_OnEvent_UnitSpellcastStart(this,unit)
  if UnitName(unit)==HealBot_PlayerName and HealBot_IsCasting then
--    HealBot_PlayerCanCast=false;
  end
end

function HealBot_OnEvent_UnitSpellcastStop(this,unit)
  if HealBot_IsCasting and UnitName(unit)==HealBot_PlayerName then
    HealBot_IsCasting = false;
    HealBot_StopCasting();
    HealBot_RecalcHeals();
    if HealBot_IamRessing then
      HealBot_SendAddonMsg("CTRA", "RESNO")
      HealBot_IamRessing=nil;
    end
--    HealBot_PlayerCanCast=true;
  end
end

function HealBot_HoT_Update(index, secLeft, memberName, spellName)
  if index then
    if secLeft==0 then
      HealBot_HoT_UpdateIcon(HealBot_Unit_Button[memberName], index, 0)
      if index==1 then     
        if HealBot_HoT2[memberName] then
          HealBot_HoT1[memberName]=HealBot_HoT2[memberName];
          HealBot_HoT2[memberName]=nil;
          HealBot_HoT_iconTexture1[memberName]=HealBot_HoT_iconTexture2[memberName];
          HealBot_HoT1_Spell[memberName]=HealBot_HoT2_Spell[memberName];
          HealBot_HoT2_Spell[memberName]=nil;
          HealBot_HoT_ChangeIcon(HealBot_Unit_Button[memberName], 1, HealBot_HoT_AlphaValue(HealBot_HoT1[memberName]), HealBot_HoT_iconTexture1[memberName])
          if HealBot_HoT3[memberName] then
            HealBot_HoT2[memberName]=HealBot_HoT3[memberName];
            HealBot_HoT3[memberName]=nil;
            HealBot_HoT_iconTexture2[memberName]=HealBot_HoT_iconTexture3[memberName];
            HealBot_HoT2_Spell[memberName]=HealBot_HoT3_Spell[memberName];
            HealBot_HoT31_Spell[memberName]=nil;
            HealBot_HoT_ChangeIcon(HealBot_Unit_Button[memberName], 2, HealBot_HoT_AlphaValue(HealBot_HoT2[memberName]), HealBot_HoT_iconTexture2[memberName])
            HealBot_HoT_UpdateIcon(HealBot_Unit_Button[memberName], 3, 0)
          else
            HealBot_HoT_UpdateIcon(HealBot_Unit_Button[memberName], 2, 0)
          end
        else
          HealBot_HoT1[memberName]=nil;
          HealBot_HoT1_Spell[memberName]=nil;
        end
      elseif index==2 then
        if HealBot_HoT3[memberName] then
          HealBot_HoT2[memberName]=HealBot_HoT3[memberName];
          HealBot_HoT3[memberName]=nil;
          HealBot_HoT_iconTexture2[memberName]=HealBot_HoT_iconTexture3[memberName];
          HealBot_HoT2_Spell[memberName]=HealBot_HoT3_Spell[memberName];
          HealBot_HoT3_Spell[memberName]=nil;
          HealBot_HoT_ChangeIcon(HealBot_Unit_Button[memberName], 2, HealBot_HoT_AlphaValue(HealBot_HoT2[memberName]), HealBot_HoT_iconTexture2[memberName])
          HealBot_HoT_UpdateIcon(HealBot_Unit_Button[memberName], 3, 0)
        else
          HealBot_HoT2[memberName]=nil;
          HealBot_HoT2_Spell[memberName]=nil;
        end
      else
        HealBot_HoT3[memberName]=nil;
        HealBot_HoT3_Spell[memberName]=nil;
      end           
    else
      HealBot_HoT_UpdateIcon(HealBot_Unit_Button[memberName], index, HealBot_HoT_AlphaValue(secLeft))
    end
  else
    local addIcon=true
    secLeft=secLeft+2;
    if HealBot_HoT1[memberName] then
      if HealBot_HoT_iconTexture1[memberName]==HealBot_HoT_Texture[spellName] then
        HealBot_HoT1[memberName]=secLeft;
        addIcon=false;
        HealBot_HoT_UpdateIcon(HealBot_Unit_Button[memberName], 1, 1)
      end
    end
    if HealBot_HoT2[memberName] then
      if HealBot_HoT_iconTexture2[memberName]==HealBot_HoT_Texture[spellName] then
        HealBot_HoT2[memberName]=secLeft;
        addIcon=false;
        HealBot_HoT_UpdateIcon(HealBot_Unit_Button[memberName], 2, 1)
      end
    end
    if HealBot_HoT3[memberName] then
      if HealBot_HoT_iconTexture3[memberName]==HealBot_HoT_Texture[spellName] then
        HealBot_HoT3[memberName]=secLeft;
        addIcon=false;
        HealBot_HoT_UpdateIcon(HealBot_Unit_Button[memberName], 3, 1)
      end
    end
    if addIcon then
      if not HealBot_HoT1[memberName] then
        HealBot_HoT1[memberName]=secLeft;
        HealBot_HoT_iconTexture1[memberName]=HealBot_HoT_Texture[spellName];
        HealBot_HoT1_Spell[memberName]=spellName;
        HealBot_HoT_ChangeIcon(HealBot_Unit_Button[memberName], 1, HealBot_HoT_AlphaValue(HealBot_HoT1[memberName]), HealBot_HoT_iconTexture1[memberName])
      elseif not HealBot_HoT2[memberName] then
        HealBot_HoT2[memberName]=secLeft;
        HealBot_HoT_iconTexture2[memberName]=HealBot_HoT_Texture[spellName];
        HealBot_HoT2_Spell[memberName]=spellName;
        HealBot_HoT_ChangeIcon(HealBot_Unit_Button[memberName], 2, HealBot_HoT_AlphaValue(HealBot_HoT2[memberName]), HealBot_HoT_iconTexture2[memberName])
      elseif not HealBot_HoT3[memberName] then
        HealBot_HoT3[memberName]=secLeft;
        HealBot_HoT3_Spell[memberName]=spellName;
        HealBot_HoT_iconTexture3[memberName]=HealBot_HoT_Texture[spellName];
        HealBot_HoT_ChangeIcon(HealBot_Unit_Button[memberName], 3, HealBot_HoT_AlphaValue(HealBot_HoT3[memberName]), HealBot_HoT_iconTexture3[memberName])
      end
    end
  end
end

function HealBot_HoT_ChangeIcon(name, index, a, Texture)
  local b=getglobal(name);
  local bar = HealBot_Action_HealthBar(b);
  local iconName = getglobal(bar:GetName().."Icon"..index);
  iconName:SetTexture(Texture);
  iconName:SetAlpha(a);
end

function HealBot_HoT_UpdateIcon(name, index, a)
  local b=getglobal(name);
  local bar = HealBot_Action_HealthBar(b);
  local iconName = getglobal(bar:GetName().."Icon"..index);
  iconName:SetAlpha(a);
end

function HealBot_HoT_AlphaValue(secLeft)
  local a=1;
  if secLeft>0 and secLeft<10 then
    a=secLeft/10;
  end
  return a
end

function HealBot_PlaySound(id)
  if id==1 then
    PlaySoundFile("Sound\\Doodad\\BellTollTribal.wav");
  elseif id==2 then
    PlaySoundFile("Sound\\Spells\\Thorns.wav");
  elseif id==3 then
    PlaySoundFile("Sound\\Doodad\\BellTollNightElf.wav");
  end
end

function HealBot_SendAddonMsg(addon_id, msg)
  if 1==0 then
    SendAddonMessage(addon_id, msg, "BATTLEGROUND" );
  elseif GetNumRaidMembers()>0 then
    SendAddonMessage(addon_id, msg, "RAID" );
  else
    SendAddonMessage(addon_id, msg, "PARTY" );
  end
end

function HealBot_InitSpells()
  local id = 1
  local cnt = 0;
  HealBot_CurrentSpells = {};
  HealBot_Spells_Defaults(HealBot_PlayerClassEN);
  
  for j in pairs(HealBot_Spells) do
    if not HealBot_Spells[j].HealsExt then
      HealBot_Spells[j].HealsExt=0;
    end
    if not HealBot_Spells[j].RealHealing then
      HealBot_Spells[j].RealHealing=0;
    end
    if not HealBot_Spells[j].HealsDur then
      if HealBot_Spells[j].HealsMax then
        HealBot_Spells[j].HealsDur=HealBot_Spells[j].HealsMax;
      else
        HealBot_Spells[j].HealsDur=0;
      end
    end
  end

  while true do
    local spellname, spellrank = HealBot_GetSpellName(id);
    local spell=nil;
    if not spellname then
      do break end
    end
    if spellrank then
      spell=spellname .. "(" .. spellrank .. ")";
    end
    if (HealBot_Spells[spell]) then
      HealBot_Spells[spell].id = id;
      HealBot_InitGetSpellData(spell, id, HealBot_PlayerClassEN, spellname);
      table.insert(HealBot_CurrentSpells,spell);
      cnt = cnt + 1;
    end
    id = id + 1;
  end
  HealBot_AddDebug("Initiated HealBot_CurrentSpells with ".. cnt .." Spells");
  HealBot_RecalcParty();
  HealBot_Options_CheckCombos();
  HealBot_Init_SmartCast();
  return cnt;
end

function HealBot_InitData() 
  HealBot_Skins = HealBot_Config.Skins;
  if(CT_RegisterMod) then
    CT_RegisterMod(HEALBOT_ADDON,"HealBot Options",5,"Interface\\AddOns\\HealBot\\Images\\HealBot","Opens HealBot Options","off",nil,HealBot_ToggleOptions);
  end
end

function HealBot_ToggleOptions()
  HealBot_TogglePanel(HealBot_Options)
end
  
  
function HealBot_InitGetSpellData(spell, id, class, spellname)

  if ( not spell ) then return; end
 
  local i, HB_mana, HB_cast, HB_HealsMin, HB_HealsMax, HB_HealsExt, HB_duration, HB_range, HB_shield, HB_channel;
  local tmpText, line, tmpTest
    
  HealBot_TooltipInit();
  HealBot_ScanTooltip:SetSpell( id, BOOKTYPE_SPELL );
  tmpText = getglobal("HealBot_ScanTooltipTextLeft2");
  if (tmpText:GetText()) then
    line = tmpText:GetText();
    tmpTest,tmpTest,HB_mana = string.find(line, HB_TOOLTIP_MANA ); 
  else
    HealBot_Report_Error( "================================" );
    HealBot_Report_Error( "ERROR: HB_mana is NIL" );
    HealBot_Report_Error( "ERROR: Spell: "..spell );
    if HealBot_ScanTooltipTextLeft2:GetText() then
      HealBot_Report_Error( "ERROR: Tooltip = >> "..HealBot_ScanTooltipTextLeft2:GetText().." <<" );
    end
    HealBot_Report_Error( "ERROR: Patten = >> "..HB_TOOLTIP_MANA.." <<" );
  end

  tmpText = getglobal("HealBot_ScanTooltipTextRight2");
  if (tmpText:GetText()) then
    line = tmpText:GetText();
    tmpTest,tmpTest,HB_range = string.find(line, HB_TOOLTIP_RANGE ); 
  elseif class=="PRIEST" and spellname==HEALBOT_PRAYER_OF_HEALING then
    HB_range="30";
  else
    HealBot_Report_Error( "================================" );
    HealBot_Report_Error( "ERROR: HB_range is NIL" );
    HealBot_Report_Error( "ERROR: Spell: "..spell );
	if HealBot_ScanTooltipTextRight2:GetText() then
      HealBot_Report_Error( "ERROR: Tooltip = >> "..HealBot_ScanTooltipTextRight2:GetText().." <<" );
    end
    HealBot_Report_Error( "ERROR: Patten = >> "..HB_TOOLTIP_RANGE.." <<" );
  end  

  tmpText = getglobal("HealBot_ScanTooltipTextLeft3");
  if (tmpText:GetText()) then
    line = tmpText:GetText();
    if ( line == HB_TOOLTIP_INSTANT_CAST ) then
      HB_cast = 0;
    elseif line == HB_TOOLTIP_CHANNELED then
	  HB_cast = 0;
	elseif ( tmpText ) then
      tmpTest,tmpTest,HB_cast = string.find(line, HB_TOOLTIP_CAST_TIME ); 
    end
  else
    HealBot_Report_Error( "================================" );
    HealBot_Report_Error( "ERROR: HB_cast is NIL" );
    HealBot_Report_Error( "ERROR: Spell: "..spell );
	if HealBot_ScanTooltipTextLeft3:GetText() then
      HealBot_Report_Error( "ERROR: Tooltip = >> "..HealBot_ScanTooltipTextLeft3:GetText().." <<" );
    end
    HealBot_Report_Error( "ERROR: Patten = >> "..HB_TOOLTIP_CAST_TIME.." <<" );
  end  

  tmpText = getglobal("HealBot_ScanTooltipTextLeft4");
  tmpTest = nil;
  if (tmpText:GetText()) then
    line = tmpText:GetText();
	if class == "PRIEST" then
      if spellname==HEALBOT_POWER_WORD_SHIELD then
        tmpTest,tmpTest,HB_HealsMin,HB_shield = string.find(line, HB_SPELL_PATTERN_SHIELD );    
        HB_HealsExt=0;
        HB_duration = 15;
	    HB_HealsMax=HB_HealsMin;
      elseif spellname==HEALBOT_RENEW then
        tmpTest,tmpTest,HB_HealsExt,tmpTest,HB_duration = string.find(line, HB_SPELL_PATTERN_RENEW );  
        HB_HealsMin=0;
        HB_HealsMax=0;
        if ( HB_HealsExt == nil ) then
          tmpTest,tmpTest,HB_HealsExt,HB_duration = string.find(line, HB_SPELL_PATTERN_RENEW1 );
        end
        if ( HB_HealsExt == nil ) then
          tmpTest,tmpTest,HB_duration,HB_HealsExt = string.find(line, HB_SPELL_PATTERN_RENEW2 );
        end
        if ( HB_HealsExt == nil ) then
          tmpTest,tmpTest,HB_duration,HB_HealsExt = string.find(line, HB_SPELL_PATTERN_RENEW3 );
        end
      elseif spellname==HEALBOT_LESSER_HEAL then
        tmpTest,HB_HealsMin,HB_HealsMax = HealBot_Generic_Patten(line,HB_SPELL_PATTERN_LESSER_HEAL); 
      elseif spellname==HEALBOT_GREATER_HEAL then
        tmpTest,HB_HealsMin,HB_HealsMax = HealBot_Generic_Patten(line, HB_SPELL_PATTERN_GREATER_HEAL ); 
      elseif spellname==HEALBOT_FLASH_HEAL then
        tmpTest,HB_HealsMin,HB_HealsMax = HealBot_Generic_Patten(line, HB_SPELL_PATTERN_FLASH_HEAL ); 
      elseif spellname==HEALBOT_HEAL then
        tmpTest,HB_HealsMin,HB_HealsMax = HealBot_Generic_Patten(line, HB_SPELL_PATTERN_HEAL ); 
      end
    elseif class=="DRUID" then
      if spellname==HEALBOT_REGROWTH then
        tmpTest,tmpTest,HB_HealsMin,HB_HealsMax,HB_HealsExt = string.find(line, HB_SPELL_PATTERN_REGROWTH );
        if ( tmpTest == nil ) then
          tmpTest,tmpTest,HB_HealsMin,HB_HealsMax,tmpTest,HB_HealsExt = string.find(line, HB_SPELL_PATTERN_REGROWTH1 );
        end
      elseif spellname==HEALBOT_REJUVENATION then
        tmpTest,tmpTest,HB_HealsExt,HB_duration = string.find(line, HB_SPELL_PATTERN_REJUVENATION );  
        HB_HealsMin=0;
        HB_HealsMax=0;
        if ( HB_HealsExt == nil ) then
          tmpTest,tmpTest,HB_HealsExt,tmpTest,HB_duration = string.find(line, HB_SPELL_PATTERN_REJUVENATION1 );
        end
        if ( HB_HealsExt == nil ) then
          tmpTest,tmpTest,HB_duration,HB_HealsExt = string.find(line, HB_SPELL_PATTERN_REJUVENATION2 );
        end
      elseif spellname==HEALBOT_HEALING_TOUCH then
        tmpTest,HB_HealsMin,HB_HealsMax = HealBot_Generic_Patten(line, HB_SPELL_PATTERN_HEALING_TOUCH ); 
      end
	elseif class=="PALADIN" then
      if spellname==HEALBOT_HOLY_LIGHT then
        tmpTest,HB_HealsMin,HB_HealsMax = HealBot_Generic_Patten(line, HB_SPELL_PATTERN_HOLY_LIGHT ); 
      elseif spellname==HEALBOT_FLASH_OF_LIGHT then
        tmpTest,HB_HealsMin,HB_HealsMax = HealBot_Generic_Patten(line, HB_SPELL_PATTERN_FLASH_OF_LIGHT ); 
      end
	elseif class=="SHAMAN" then
      if spellname==HEALBOT_HEALING_WAVE then
        tmpTest,HB_HealsMin,HB_HealsMax = HealBot_Generic_Patten(line, HB_SPELL_PATTERN_HEALING_WAVE ); 
      elseif spellname==HEALBOT_LESSER_HEALING_WAVE then
        tmpTest,HB_HealsMin,HB_HealsMax = HealBot_Generic_Patten(line, HB_SPELL_PATTERN_LESSER_HEALING_WAVE ); 
      end
	end
  else
    HealBot_Report_Error( "================================" );
    HealBot_Report_Error( "ERROR: tmpTest == nil" );
    HealBot_Report_Error( "ERROR: spell = "..spell );
    if line then
      HealBot_Report_Error( "ERROR: Tooltip = >> "..line.." <<" );
    end
  end  


  if HB_cast then
    HealBot_Spells[spell].CastTime=tonumber(HB_cast);
  end
  if HB_mana then
    HealBot_Spells[spell].Mana=tonumber(HB_mana);
  end
  if HB_range then
    HealBot_Spells[spell].Range=tonumber(HB_range);
  end
  if HB_HealsMin then
    HealBot_Spells[spell].HealsMin=tonumber(HB_HealsMin);
  end
  if HB_HealsMax then
    HealBot_Spells[spell].HealsMax=tonumber(HB_HealsMax);
  end
  if HB_HealsExt then
    HealBot_Spells[spell].HealsExt=tonumber(HB_HealsExt);
  end
  if HB_duration then
    HealBot_Spells[spell].Duration=tonumber(HB_duration);
  end
  if HB_shield then
    HealBot_Spells[spell].Shield=tonumber(HB_shield);
  end
  if HB_channel then
    HealBot_Spells[spell].Channel=tonumber(HB_channel);
  end
  
  if not HealBot_Spells[spell].CastTime then
    HealBot_Spells[spell].CastTime=0;
    HealBot_Spells[spell].Cast=0;
  end
  if not HealBot_Spells[spell].Cast then 
    HealBot_Report_Error( "================================" );
    HealBot_Report_Error( "ERROR: Cast == nil" );
    HealBot_Report_Error( "ERROR: spell = "..spell );
    HealBot_Spells[spell].Cast=0;
  end
  if not HealBot_Spells[spell].Mana then
    HealBot_Spells[spell].Mana=10*UnitLevel("player");
  end
  if not HealBot_Spells[spell].Range then
    HealBot_Spells[spell].Range=40;
  end
  if not HealBot_Spells[spell].HealsMin then
    HealBot_Spells[spell].HealsMin=0;
  end
  if not HealBot_Spells[spell].HealsMax then
    HealBot_Spells[spell].HealsMax=0;
  end
  if not HealBot_Spells[spell].HealsExt then
    HealBot_Spells[spell].HealsExt = 0;
  end
  if not HealBot_Spells[spell].Channel then
    HealBot_Spells[spell].Channel = HealBot_Spells[spell].CastTime;
  end
  if not HealBot_Spells[spell].Duration then
    HealBot_Spells[spell].Duration = 0;
  end
  if not HealBot_Spells[spell].Target then
    HealBot_Spells[spell].Target = {"player","party","pet"};
  end
  if not HealBot_Spells[spell].Price then
    HealBot_Spells[spell].Price = 0;
  end

  if not HealBot_Spells[spell].RealHealing then
    HealBot_Spells[spell].RealHealing=0;
  end
  HealBot_Spells[spell].HealsCast = (HealBot_Spells[spell].HealsMin+HealBot_Spells[spell].HealsMax)/2;
  HealBot_Spells[spell].HealsDur = floor((HealBot_Spells[spell].HealsCast+HealBot_Spells[spell].HealsExt) + HealBot_Spells[spell].RealHealing);
end

function HealBot_FindSpellRangeCast(id, class)

  if ( not id ) then return; end
  
  spell,spellrank = HealBot_GetSpellName(id);
  if spellrank then spell=spell.."("..spellrank..")"; end
  
  local i, HB_mana, HB_cast, HB_range;
  local tmpText, line1, line2, line3, tmpTest

  HealBot_TooltipInit();
  HealBot_ScanTooltip:SetSpell( id, BOOKTYPE_SPELL );
 
  if HealBot_ScanTooltipTextLeft2:GetText() then
    line1=HealBot_ScanTooltipTextLeft2:GetText();
  end
  if HealBot_ScanTooltipTextRight2:GetText() then
    line2 = HealBot_ScanTooltipTextRight2:GetText()
  end
  if HealBot_ScanTooltipTextLeft3:GetText() then
    line3 = HealBot_ScanTooltipTextLeft3:GetText();
  end
  
  if line1 then
    tmpTest,tmpTest,HB_mana = string.find(line1, HB_TOOLTIP_MANA ); 
  end

  if line2 then
    tmpTest,tmpTest,HB_range = string.find(line2, HB_TOOLTIP_RANGE ); 
  end  

  if line3 then
    if ( line3 == HB_TOOLTIP_INSTANT_CAST ) then
      HB_cast = 0;
    elseif line3 == HB_TOOLTIP_CHANNELED then
	  HB_cast = 0;
	elseif ( line3 ) then
      tmpTest,tmpTest,HB_cast = string.find(line3, HB_TOOLTIP_CAST_TIME ); 
    end
  end  

  HealBot_OtherSpells[spell] = {spell = {}};
  if not HB_cast then
    HealBot_OtherSpells[spell].CastTime=0;
  else
    HealBot_OtherSpells[spell].CastTime=tonumber(HB_cast);
  end
  if not HB_mana then
    HealBot_OtherSpells[spell].Mana=10*UnitLevel("player");
  else
    HealBot_OtherSpells[spell].Mana=tonumber(HB_mana);
  end
  if not HB_range then
    HealBot_OtherSpells[spell].Range=40;
  else
    HealBot_OtherSpells[spell].Range=tonumber(HB_range);
  end

end

function HealBot_Generic_Patten(matchStr,matchPattern)
  local tmpTest,HB_HealsMin,HB_HealsMax,HB_HealsExt,HB_duration
    tmpTest,tmpTest,HB_HealsMin,HB_HealsMax = string.find(matchStr, matchPattern ); 
  if ( tmpTest == nil ) then
    HealBot_Report_Error( "================================" );
    HealBot_Report_Error( "ERROR: tmpTest == nil" );
    HealBot_Report_Error( "ERROR: pattern = "..matchPattern );
    HealBot_Report_Error( "ERROR: Tooltip = >> "..matchStr.." <<" );
  end
  return tmpTest,HB_HealsMin,HB_HealsMax;
end

function HealBot_GetChan(chan)
	local index = GetChannelName(chan);
	if (index>0) then
		return index;
	else
		return nil;
	end
end

function HealBot_SpiBonus()
	local heals_modifer = 0;
    local base, stat, posBuff, negBuff = UnitStat("player",5);
	local nameTalent, icon, tier, column, currRank, maxRank = GetTalentInfo(2,14);
    if (GetLocale() == "enUS") and nameTalent then
      if nameTalent~="Spiritual Guidance" then
        HealBot_Report_Error( "================================" );
        HealBot_Report_Error( "ERROR: in function HealBot_SpiBonus" );
        HealBot_Report_Error( "ERROR: found talent "..nameTalent.." when expecting Spiritual Guidance" );
      end
    end
	spiGuideBonus = stat * 0.05;
	heals_modifer = heals_modifer + (currRank * spiGuideBonus);
  	return heals_modifer;
end

function HealBot_HasInnerFocus()
	local nameTalent, icon, tier, column, currRank, maxRank = GetTalentInfo(1,8);
    if nameTalent then
      if nameTalent~=HEALBOT_INNER_FOCUS then
        HealBot_Report_Error( "================================" );
        HealBot_Report_Error( "ERROR: in function HealBot_InnerFocus" );
        HealBot_Report_Error( "ERROR: found talent "..nameTalent.." when expecting "..HEALBOT_INNER_FOCUS );
      end
    end
    if currRank>0 then
      HealBot_InnerFocusTalent=true;
    else
      HealBot_InnerFocusTalent=false;
    end
end

function HealBot_MMButton_UpdatePosition()
	HealBot_ButtonFrame:SetPoint(
		"TOPLEFT",
		"Minimap",
		"TOPLEFT",
		54 - (HealBot_Config.HealBot_ButtonRadius * cos(HealBot_Config.HealBot_ButtonPosition)),
		(HealBot_Config.HealBot_ButtonRadius * sin(HealBot_Config.HealBot_ButtonPosition)) - 55
	);
end

function HealBot_MMButton_Init()
	if(HealBot_Config.ButtonShown==1) then
		HealBot_ButtonFrame:Show();
	else
		HealBot_ButtonFrame:Hide();
	end
end

function HealBot_MMButton_OnEnter()
    GameTooltip:SetOwner(this, "ANCHOR_LEFT");
    GameTooltip:SetText(HEALBOT_BUTTON_TOOLTIP);
	GameTooltipTextLeft1:SetTextColor(1, 1, 1);
    GameTooltip:Show();
end

function HealBot_MMButton_OnClick(this,button)
  if button~="RightButton" then
    HealBot_ToggleOptions()
  else
    HealBot_AddDebug("right click")
  end
end

function HealBot_MMButton_BeingDragged()
    -- Thanks to Gello for this code
    local xpos,ypos = GetCursorPosition() 
    local xmin,ymin = Minimap:GetLeft(), Minimap:GetBottom() 

    xpos = xmin-xpos/UIParent:GetScale()+70 
    ypos = ypos/UIParent:GetScale()-ymin-70 

    HealBot_MMButton_SetPosition(math.deg(math.atan2(ypos,xpos)));
end

function HealBot_MMButton_SetPosition(v)
    if(v < 0) then
        v = v + 360;
    end

    HealBot_Config.HealBot_ButtonPosition = v;
    HealBot_MMButton_UpdatePosition();
end



function HealBot_Spells_Defaults(class)

if class=="PALADIN" then
HealBot_Spells = {
-- PALADIN

  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_1] = {
    CastTime = 2.5, Cast = 2.5, Mana =  35, HealsMin =   39, HealsMax =   47, Level = 1 },
  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_2] = { 
    CastTime = 2.5, Cast = 2.5, Mana =  60, HealsMin =   76, HealsMax =   90, Level = 6 },
  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_3] = { 
    CastTime = 2.5, Cast = 2.5, Mana = 110, HealsMin =  159, HealsMax =  187, Level = 14 },
  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_4] = { 
    CastTime = 2.5, Cast = 2.5, Mana = 190, HealsMin =  310, HealsMax =  356, Level = 22 },
  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_5] = { 
    CastTime = 2.5, Cast = 2.5, Mana = 275, HealsMin =  491, HealsMax =  553, Level = 30 },
  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_6] = { 
    CastTime = 2.5, Cast = 2.5, Mana = 365, HealsMin =  698, HealsMax =  780, Level = 38 },
  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_7] = { 
    CastTime = 2.5, Cast = 2.5, Mana = 465, HealsMin =  945, HealsMax = 1053, Level = 46 },
  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_8] = { 
    CastTime = 2.5, Cast = 2.5, Mana = 580, HealsMin = 1246, HealsMax = 1388, Level = 54 },
  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_9] = { 
    CastTime = 2.5, Cast = 2.5, Mana = 660, HealsMin = 1590, HealsMax = 1770, Level = 60 },
  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_10] = { 
    CastTime = 2.5, Cast = 2.5, Mana = 710, HealsMin = 1741, HealsMax = 1939, Level = 62 },
  [HEALBOT_HOLY_LIGHT .. HEALBOT_RANK_11] = { 
    CastTime = 2.5, Cast = 2.5, Mana = 840, HealsMin = 2196, HealsMax = 2446, Level = 70 },
    
  [HEALBOT_FLASH_OF_LIGHT .. HEALBOT_RANK_1] = {
    CastTime = 1.5, Cast = 1.5, Mana =  35, HealsMin =   62, HealsMax =   72, Level = 20 },
  [HEALBOT_FLASH_OF_LIGHT .. HEALBOT_RANK_2] = {
    CastTime = 1.5, Cast = 1.5, Mana =  50, HealsMin =   96, HealsMax =  110, Level = 26 },
  [HEALBOT_FLASH_OF_LIGHT .. HEALBOT_RANK_3] = {
    CastTime = 1.5, Cast = 1.5, Mana =  70, HealsMin =  145, HealsMax =  163, Level = 34 },
  [HEALBOT_FLASH_OF_LIGHT .. HEALBOT_RANK_4] = {
    CastTime = 1.5, Cast = 1.5, Mana =  90, HealsMin =  197, HealsMax =  221, Level = 42 },
  [HEALBOT_FLASH_OF_LIGHT .. HEALBOT_RANK_5] = {
    CastTime = 1.5, Cast = 1.5, Mana = 115, HealsMin =  267, HealsMax =  299, Level = 50 },
  [HEALBOT_FLASH_OF_LIGHT .. HEALBOT_RANK_6] = {
    CastTime = 1.5, Cast = 1.5, Mana = 140, HealsMin =  343, HealsMax =  383, Level = 58 },
  [HEALBOT_FLASH_OF_LIGHT .. HEALBOT_RANK_7] = {
    CastTime = 1.5, Cast = 1.5, Mana = 180, HealsMin =  448, HealsMax =  502, Level = 66 },
};

elseif class=="DRUID" then
HealBot_Spells = {
-- DRUID

  [HEALBOT_REJUVENATION .. HEALBOT_RANK_1 ] = { 
    CastTime = 0, Cast = 0, Duration = 12, Mana =  25, HealsMin = 0, HealsMax = 0, HealsExt =   32, Level =  4, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_2 ] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana =  40, HealsMin = 0, HealsMax = 0, HealsExt =   56, Level = 10, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_3 ] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana =  75, HealsMin = 0, HealsMax = 0, HealsExt =  116, Level = 16, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_4 ] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana = 105, HealsMin = 0, HealsMax = 0, HealsExt =  180, Level = 22, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_5 ] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana = 135, HealsMin = 0, HealsMax = 0, HealsExt =  244, Level = 28, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_6 ] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana = 160, HealsMin = 0, HealsMax = 0, HealsExt =  304, Level = 34, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_7 ] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana = 195, HealsMin = 0, HealsMax = 0, HealsExt =  388, Level = 40, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_8 ] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana = 235, HealsMin = 0, HealsMax = 0, HealsExt =  488, Level = 46, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_9 ] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana = 280, HealsMin = 0, HealsMax = 0, HealsExt =  608, Level = 52, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_10] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana = 335, HealsMin = 0, HealsMax = 0, HealsExt =  756, Level = 58, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_11] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana = 360, HealsMin = 0, HealsMax = 0, HealsExt =  888, Level = 60, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_12] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana = 370, HealsMin = 0, HealsMax = 0, HealsExt =  932, Level = 63, Buff = HEALBOT_REJUVENATION },
  [HEALBOT_REJUVENATION .. HEALBOT_RANK_13] = {
    CastTime = 0, Cast = 0, Duration = 12, Mana = 415, HealsMin = 0, HealsMax = 0, HealsExt = 1060, Level = 69, Buff = HEALBOT_REJUVENATION },

  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_1 ] = {
    CastTime = 1.5, Cast = 1.5, Mana =  25, HealsMin =   37, HealsMax =   51, Level  = 1 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_2 ] = {
    CastTime = 2.0, Cast = 2.0, Mana =  55, HealsMin =   88, HealsMax =  112, Level =  8 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_3 ] = {
    CastTime = 2.5, Cast = 2.5, Mana = 110, HealsMin =  195, HealsMax =  243, Level = 14 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_4 ] = {
    CastTime = 3.0, Cast = 3.0, Mana = 180, HealsMin =  363, HealsMax =  445, Level = 20 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_5 ] = {
    CastTime = 3.5, Cast = 3.5, Mana = 300, HealsMin =  572, HealsMax =  694, Level = 26 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_6 ] = {
    CastTime = 3.5, Cast = 3.5, Mana = 370, HealsMin =  742, HealsMax =  894, Level = 32 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_7 ] = {
    CastTime = 3.5, Cast = 3.5, Mana = 445, HealsMin =  935, HealsMax = 1120, Level = 38 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_8 ] = {
    CastTime = 3.5, Cast = 3.5, Mana = 545, HealsMin = 1199, HealsMax = 1427, Level = 44 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_9 ] = {
    CastTime = 3.5, Cast = 3.5, Mana = 660, HealsMin = 1516, HealsMax = 1796, Level = 50 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_10] = {
    CastTime = 3.5, Cast = 3.5, Mana = 790, HealsMin = 1890, HealsMax = 2230, Level = 56 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_11] = {
    CastTime = 3.5, Cast = 3.5, Mana = 840, HealsMin = 2267, HealsMax = 2677, Level = 60 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_12] = {
    CastTime = 3.5, Cast = 3.5, Mana = 890, HealsMin = 2364, HealsMax = 2790, Level = 62 },
  [HEALBOT_HEALING_TOUCH .. HEALBOT_RANK_13] = {
    CastTime = 3.5, Cast = 3.5, Mana = 935, HealsMin = 2707, HealsMax = 3197, Level = 69 },
    
  [HEALBOT_REGROWTH .. HEALBOT_RANK_1] = {
    CastTime = 2, Cast = 2.0, Duration = 21, Mana =  120, HealsMin =   84, HealsMax =   98, HealsExt =   98, Level = 12, Buff = HEALBOT_REGROWTH },
  [HEALBOT_REGROWTH .. HEALBOT_RANK_2] = {
    CastTime = 2, Cast = 2.0, Duration = 21, Mana =  205, HealsMin =  164, HealsMax =  188, HealsExt =  175, Level = 18, Buff = HEALBOT_REGROWTH },
  [HEALBOT_REGROWTH .. HEALBOT_RANK_3] = {
    CastTime = 2, Cast = 2.0, Duration = 21, Mana =  280, HealsMin =  240, HealsMax =  274, HealsExt =  259, Level = 24, Buff = HEALBOT_REGROWTH },
  [HEALBOT_REGROWTH .. HEALBOT_RANK_4] = { 
    CastTime = 2, Cast = 2.0, Duration = 21, Mana =  350, HealsMin =  318, HealsMax =  360, HealsExt =  343, Level = 30, Buff = HEALBOT_REGROWTH },
  [HEALBOT_REGROWTH .. HEALBOT_RANK_5] = {
    CastTime = 2, Cast = 2.0, Duration = 21, Mana =  420, HealsMin =  405, HealsMax =  457, HealsExt =  427, Level = 36, Buff = HEALBOT_REGROWTH },
  [HEALBOT_REGROWTH .. HEALBOT_RANK_6] = {
    CastTime = 2, Cast = 2.0, Duration = 21, Mana =  510, HealsMin =  511, HealsMax =  576, HealsExt =  546, Level = 42, Buff = HEALBOT_REGROWTH },
  [HEALBOT_REGROWTH .. HEALBOT_RANK_7] = {
    CastTime = 2, Cast = 2.0, Duration = 21, Mana =  615, HealsMin =  646, HealsMax =  724, HealsExt =  686, Level = 48, Buff = HEALBOT_REGROWTH },
  [HEALBOT_REGROWTH .. HEALBOT_RANK_8] = {
    CastTime = 2, Cast = 2.0, Duration = 21, Mana =  740, HealsMin =  809, HealsMax =  905, HealsExt =  861, Level = 54, Buff = HEALBOT_REGROWTH },
  [HEALBOT_REGROWTH .. HEALBOT_RANK_9] = {
    CastTime = 2, Cast = 2.0, Duration = 21, Mana =  880, HealsMin = 1003, HealsMax = 1119, HealsExt = 1064, Level = 60, Buff = HEALBOT_REGROWTH },
  [HEALBOT_REGROWTH .. HEALBOT_RANK_10] = {
    CastTime = 2, Cast = 2.0, Duration = 21, Mana = 1030, HealsMin = 1215, HealsMax = 1355, HealsExt = 1274, Level = 65, Buff = HEALBOT_REGROWTH },
    
  [HEALBOT_LIFEBLOOM .. HEALBOT_RANK_1] = {
    CastTime = 0, Cast = 0, Duration = 7, Mana = 220, HealsMin = 600, HealsMax = 600, HealsExt = 273, Level = 64, Buff = HEALBOT_LIFEBLOOM },

};

elseif class=="PRIEST" then
HealBot_Spells = {
-- PRIEST

  [HEALBOT_LESSER_HEAL .. HEALBOT_RANK_1] = {
    CastTime = 1.5, Cast = 1.5, Mana =  35, HealsMin =   43, HealsMax =   53, Level =  1 }, 
  [HEALBOT_LESSER_HEAL .. HEALBOT_RANK_2] = {
    CastTime = 2.0, Cast = 2.0, Mana =  50, HealsMin =   71, HealsMax =   85, Level =  4 }, 
  [HEALBOT_LESSER_HEAL .. HEALBOT_RANK_3] = {
    CastTime = 2.5, Cast = 2.5, Mana =  85, HealsMin =  135, HealsMax =  157, Level = 10 }, 

  [HEALBOT_HEAL .. HEALBOT_RANK_1] = {
    CastTime = 3.0, Cast = 3.0, Mana = 155, HealsMin =  295, HealsMax =  341, Level = 16 }, 
  [HEALBOT_HEAL .. HEALBOT_RANK_2] = {
    CastTime = 3.0, Cast = 3.0, Mana = 205, HealsMin =  429, HealsMax =  491, Level = 22 }, 
  [HEALBOT_HEAL .. HEALBOT_RANK_3] = {
    CastTime = 3.0, Cast = 3.0, Mana = 255, HealsMin =  566, HealsMax =  642, Level = 28 }, 
  [HEALBOT_HEAL .. HEALBOT_RANK_4] = {
    CastTime = 3.0, Cast = 3.0, Mana = 305, HealsMin =  712, HealsMax = 804, Level = 34 }, 

  [HEALBOT_GREATER_HEAL .. HEALBOT_RANK_1] = {
    CastTime = 3.0, Cast = 3.0, Mana =  370, HealsMin = 899, HealsMax = 1013, Level = 40 }, 
  [HEALBOT_GREATER_HEAL .. HEALBOT_RANK_2] = {
    CastTime = 3.0, Cast = 3.0, Mana =  455, HealsMin = 1149, HealsMax = 1289, Level = 46 }, 
  [HEALBOT_GREATER_HEAL .. HEALBOT_RANK_3] = {
    CastTime = 3.0, Cast = 3.0, Mana =  545, HealsMin = 1473, HealsMax = 1609, Level = 52 }, 
  [HEALBOT_GREATER_HEAL .. HEALBOT_RANK_4] = {
    CastTime = 3.0, Cast = 3.0, Mana =  655, HealsMin = 1798, HealsMax = 2006, Level = 58 }, 
  [HEALBOT_GREATER_HEAL .. HEALBOT_RANK_5] = {
    CastTime = 3.0, Cast = 3.0, Mana = 710, HealsMin = 1966, HealsMax = 2194, Level = 60 }, 
  [HEALBOT_GREATER_HEAL .. HEALBOT_RANK_6] = {
    CastTime = 3.0, Cast = 3.0, Mana = 750, HealsMin = 2074, HealsMax = 2410, Level = 63 }, 
  [HEALBOT_GREATER_HEAL .. HEALBOT_RANK_7] = {
    CastTime = 3.0, Cast = 3.0, Mana = 825, HealsMin = 2396, HealsMax = 2784, Level = 68 }, 
    
  [HEALBOT_BINDING_HEAL .. HEALBOT_RANK_1] = {
    CastTime = 1.5, Cast = 1.5, Mana =  1034, HealsMin = 1042, HealsMax = 1338, Level = 64 }, 

  [HEALBOT_PRAYER_OF_MENDING .. HEALBOT_RANK_1] = {
    CastTime = 0, Cast = 0, Mana =  390, HealsMin = 800, HealsMax = 800, Level = 68, 
    Buff=HEALBOT_PRAYER_OF_MENDING, NoBonus=true,}, -- Duration = 30}, 
    
  [HEALBOT_PRAYER_OF_HEALING .. HEALBOT_RANK_1] = {
    CastTime = 3.0, Cast = 3.0, Mana =  410, HealsMin = 312, HealsMax = 333, Level = 30 }, 
  [HEALBOT_PRAYER_OF_HEALING .. HEALBOT_RANK_2] = {
    CastTime = 3.0, Cast = 3.0, Mana =  560, HealsMin = 458, HealsMax = 487, Level = 40 }, 
  [HEALBOT_PRAYER_OF_HEALING .. HEALBOT_RANK_3] = {
    CastTime = 3.0, Cast = 3.0, Mana =  770, HealsMin = 675, HealsMax = 713, Level = 50 }, 
  [HEALBOT_PRAYER_OF_HEALING .. HEALBOT_RANK_4] = {
    CastTime = 3.0, Cast = 3.0, Mana =  1030, HealsMin = 948, HealsMax = 1001, Level = 60 }, 
  [HEALBOT_PRAYER_OF_HEALING .. HEALBOT_RANK_5] = {
    CastTime = 3.0, Cast = 3.0, Mana = 1070, HealsMin = 1007, HealsMax = 1063, Level = 60 }, 
  [HEALBOT_PRAYER_OF_HEALING .. HEALBOT_RANK_6] = {
    CastTime = 3.0, Cast = 3.0, Mana = 1255, HealsMin = 1246, HealsMax = 1316, Level = 68 }, 

    
  [HEALBOT_RENEW .. HEALBOT_RANK_1] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana =  30, HealsMin = 0, HealsMax = 0, HealsExt =   45, Level =  8, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_2] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana =  65, HealsMin = 0, HealsMax = 0, HealsExt =  100, Level = 14, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_3] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana = 105, HealsMin = 0, HealsMax = 0, HealsExt =  175, Level = 20, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_4] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana = 140, HealsMin = 0, HealsMax = 0, HealsExt =  245, Level = 26, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_5] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana = 170, HealsMin = 0, HealsMax = 0, HealsExt =  315, Level = 32, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_6] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana = 205, HealsMin = 0, HealsMax = 0, HealsExt =  400, Level = 38, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_7] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana = 250, HealsMin = 0, HealsMax = 0, HealsExt =  510, Level = 44, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_8] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana = 305, HealsMin = 0, HealsMax = 0, HealsExt =  650, Level = 50, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_9] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana = 365, HealsMin = 0, HealsMax = 0, HealsExt =  810, Level = 56, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_10] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana = 410, HealsMin = 0, HealsMax = 0, HealsExt =  970, Level = 60, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_11] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana = 430, HealsMin = 0, HealsMax = 0, HealsExt = 1010, Level = 65, Buff = HEALBOT_RENEW }, 
  [HEALBOT_RENEW .. HEALBOT_RANK_12] = {
    CastTime = 0, Cast = 0, Duration = 15, Mana = 450, HealsMin = 0, HealsMax = 0, HealsExt = 1110, Level = 70, Buff = HEALBOT_RENEW }, 

  [HEALBOT_FLASH_HEAL .. HEALBOT_RANK_1] = {
    CastTime = 1.5, Cast = 1.5, Mana = 125, HealsMin = 193, HealsMax = 237, Level = 20 }, 
  [HEALBOT_FLASH_HEAL .. HEALBOT_RANK_2] = {
    CastTime = 1.5, Cast = 1.5, Mana = 155, HealsMin = 258, HealsMax = 314, Level = 26 }, 
  [HEALBOT_FLASH_HEAL .. HEALBOT_RANK_3] = {
    CastTime = 1.5, Cast = 1.5, Mana = 185, HealsMin = 327, HealsMax = 393, Level = 32 }, 
  [HEALBOT_FLASH_HEAL .. HEALBOT_RANK_4] = {
    CastTime = 1.5, Cast = 1.5, Mana = 215, HealsMin = 400, HealsMax = 478, Level = 38 }, 
  [HEALBOT_FLASH_HEAL .. HEALBOT_RANK_5] = {
    CastTime = 1.5, Cast = 1.5, Mana = 265, HealsMin = 518, HealsMax = 616, Level = 44 }, 
  [HEALBOT_FLASH_HEAL .. HEALBOT_RANK_6] = {
    CastTime = 1.5, Cast = 1.5, Mana = 315, HealsMin = 644, HealsMax = 764, Level = 50 }, 
  [HEALBOT_FLASH_HEAL .. HEALBOT_RANK_7] = { 
    CastTime = 1.5, Cast = 1.5, Mana = 380, HealsMin = 812, HealsMax = 958, Level = 56 }, 
  [HEALBOT_FLASH_HEAL .. HEALBOT_RANK_8] = { 
    CastTime = 1.5, Cast = 1.5, Mana = 450, HealsMin = 913, HealsMax = 1059, Level = 61 }, 
  [HEALBOT_FLASH_HEAL .. HEALBOT_RANK_9] = { 
    CastTime = 1.5, Cast = 1.5, Mana = 470, HealsMin = 1101, HealsMax = 1279, Level = 67 }, 

  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_1] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana =  45, HealsMin =  44, HealsMax =  44, Level =  6,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15  }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_2] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana =  80, HealsMin =  88, HealsMax =  88, Level = 12,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15 }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_3] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana = 130, HealsMin = 158, HealsMax = 158, Level = 18,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15 }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_4] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana = 175, HealsMin = 234, HealsMax = 234, Level = 24,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15 }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_5] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana = 210, HealsMin = 301, HealsMax = 301, Level = 30,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15 }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_6] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana = 250, HealsMin = 381, HealsMax = 381, Level = 36,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15 }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_7] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana = 300, HealsMin = 484, HealsMax = 484, Level = 42,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15 }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_8] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana = 355, HealsMin = 605, HealsMax = 605, Level = 48,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15 }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_9] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana = 425, HealsMin = 763, HealsMax = 763, Level = 54,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15 }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_10] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana = 500, HealsMin = 942, HealsMax = 942, Level = 60,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15 }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_11] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana = 540, HealsMin = 1147, HealsMax = 1147, Level = 65,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15 }, 
  [HEALBOT_POWER_WORD_SHIELD .. HEALBOT_RANK_12] = {
    CastTime = 0, Cast = 0, Shield = 30, Mana = 600, HealsMin = 1315, HealsMax = 1315, Level = 70,
    Buff= HEALBOT_POWER_WORD_SHIELD, Duration = 15}, 
};

elseif class=="SHAMAN" then
HealBot_Spells = {
-- SHAMAN

  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_1] = {
    CastTime = 1.5, Cast = 1.5, Mana =  25, HealsMin =   36, HealsMax =   47, Level =  1 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_2] = {
    CastTime = 2.0, Cast = 2.0, Mana =  45, HealsMin =   67, HealsMax =   78, Level =  6 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_3] = {
    CastTime = 2.5, Cast = 2.5, Mana =  80, HealsMin =  129, HealsMax =  155, Level = 12 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_4] = {
    CastTime = 3.0, Cast = 3.0, Mana = 155, HealsMin =  268, HealsMax =  316, Level = 18 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_5] = {
    CastTime = 3.0, Cast = 3.0, Mana = 200, HealsMin =  376, HealsMax =  440, Level = 24 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_6] = {
    CastTime = 3.0, Cast = 3.0, Mana = 265, HealsMin =  536, HealsMax =  622, Level = 32 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_7] = {
    CastTime = 3.0, Cast = 3.0, Mana = 340, HealsMin =  740, HealsMax =  854, Level = 40 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_8] = {
    CastTime = 3.0, Cast = 3.0, Mana = 440, HealsMin = 1017, HealsMax = 1167, Level = 48 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_9] = {
    CastTime = 3.0, Cast = 3.0, Mana = 560, HealsMin = 1367, HealsMax = 1561, Level = 56 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_10] = {
    CastTime = 3.0, Cast = 3.0, Mana = 620, HealsMin = 1620, HealsMax = 1850, Level = 60 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_11] = {
    CastTime = 3.0, Cast = 3.0, Mana = 655, HealsMin = 1725, HealsMax = 1969, Level = 63 }, 
  [HEALBOT_HEALING_WAVE .. HEALBOT_RANK_12] = {
    CastTime = 3.0, Cast = 3.0, Mana = 720, HealsMin = 2134, HealsMax = 2436, Level = 70 }, 

  [HEALBOT_LESSER_HEALING_WAVE .. HEALBOT_RANK_1] = {
    CastTime = 1.5, Cast = 1.5, Mana = 105, HealsMin = 162, HealsMax = 186, Level = 20 }, 
  [HEALBOT_LESSER_HEALING_WAVE .. HEALBOT_RANK_2] = {
    CastTime = 1.5, Cast = 1.5, Mana = 145, HealsMin = 247, HealsMax = 281, Level = 28 }, 
  [HEALBOT_LESSER_HEALING_WAVE .. HEALBOT_RANK_3] = {
    CastTime = 1.5, Cast = 1.5, Mana = 185, HealsMin = 337, HealsMax = 381, Level = 36 }, 
  [HEALBOT_LESSER_HEALING_WAVE .. HEALBOT_RANK_4] = {
    CastTime = 1.5, Cast = 1.5, Mana = 235, HealsMin = 458, HealsMax = 514, Level = 44 }, 
  [HEALBOT_LESSER_HEALING_WAVE .. HEALBOT_RANK_5] = {
    CastTime = 1.5, Cast = 1.5, Mana = 305, HealsMin = 631, HealsMax = 705, Level = 52 }, 
  [HEALBOT_LESSER_HEALING_WAVE .. HEALBOT_RANK_6] = {
    CastTime = 1.5, Cast = 1.5, Mana = 380, HealsMin = 832, HealsMax = 928, Level = 60 }, 
  [HEALBOT_LESSER_HEALING_WAVE .. HEALBOT_RANK_7] = {
    CastTime = 1.5, Cast = 1.5, Mana = 440, HealsMin = 1039, HealsMax = 1185, Level = 66 }, 
    
};

end

end

function HealBot_Init_SmartCast()

  local target=0;
  local score=0;
  local lastscore=0;
  for k=1,7 do
    if k==1 then target=250
    elseif k==2 then target=500
    elseif k==3 then target=750
    elseif k==4 then target=1100
    elseif k==5 then target=1500
    elseif k==6 then target=2200
    elseif k==7 then target=4000
    end
    lastscore=0;
    score=0;
    table.foreach(HealBot_CurrentSpells, function (index,spell)
      if (HealBot_Spells[spell]) then
        if HealBot_Spells[spell].HealsDur<target and HealBot_Spells[spell].HealsDur>0 and HealBot_Spells[spell].CastTime>0 then
          score=(HealBot_Spells[spell].HealsDur/target)*200;
          score=score-(HealBot_Spells[spell].CastTime*15);
          score=score-(HealBot_Spells[spell].Mana/20);
          if score>lastscore then
            lastscore=score;
            SmartCast_Heal[k]=spell;
          end
        end
      end
    end)
  end
  
  if HealBot_PlayerClassEN=="PRIEST" then
    SmartCast_Res=HEALBOT_RESURRECTION;
  elseif HealBot_PlayerClassEN=="DRUID" then
    SmartCast_Res=HEALBOT_REBIRTH;
  elseif HealBot_PlayerClassEN=="PALADIN" then
    SmartCast_Res=HEALBOT_REDEMPTION;
  elseif HealBot_PlayerClassEN=="SHAMAN" then
    SmartCast_Res=HEALBOT_ANCESTRALSPIRIT;
  end
end
