--[[

  HealBot Contined
	
]]

local HealBot_CalcEquipBonus=false;
local HealBot_HasDivineSpirit=2;
local HealBot_CheckForDivineSpirit=false;
local HealBot_FlagEquipUpdate1=1;
local HealBot_FlagEquipUpdate2=1;
local HealBot_NeedEquipUpdate=0;
local HealBot_CastingSpell  = nil;
local HealBot_HealValue = 0;
local HealBot_IamRessing = nil;
local HB_InitSpells=false;
local HealBot_RequestVer=nil;
local HealBot_IamHealing = {};
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_HoT_Mending=0;
local HealBot_HoT_MendingWith="nil";
local HealBot_HoT_MendingWatch=0;
local HealBot_CheckZoneFlag=0
local HealBot_InCombatUpdate=false
local HealBot_SmartCast_Spells={};
local HealBot_TargetBuffCheck=false;
local HealBot_AddonMsgType=3;
local HealBot_InBG=false;
local HealBot_DelayData=-1;
local HealBot_pCheck={};
local HealBot_HealingBonus=0;
local HealBot_OthersHealingBonus=0
local HealBot_HoT_Texture={};
local HealBot_SpamCnt=0;
local HealBot_ErrorCnt=0;
local HealBot_Healers = {};
local HealBot_HealsIn = {};
local HealBot_CurrentSpells = {};
local HealBot_Ressing = {};
local HealBot_DelayBuffCheck = {};
local HealBot_DelayDebuffCheck = {};
local HealBot_HealersBonus={}
local HealBot_HealersIncCnt={}
local HealBot_Vers={}
local xpos=nil
local ypos=nil
local xmin=nil
local ymin=nil
local sid=nil
local sidd=nil
local gidspellName=nil
local gidsubSpellName=nil
local retSpell=nil
local score=0
local lastscore=0
local Process=false
local target=8
local strfind=strfind
local strsub=strsub
local strlen=strlen
local gsub=gsub
local format=format
local tonumber=tonumber
local strlen=strlen
local HealBot_hSpell="Heal"
local HealBot_bSpell="Power Word: Fortitude"
local HealBot_dSpell="Cure Disease"
local HealBot_rSpell="Resurrection"
local HealBot_ThrottleCnt=7
local HealBot_Aggro={}
local HealBot_Reset_flag=false
local HB_Timer1=0.2
local HB_Timer2=200
local HealBot_UpUnitInCombat={}
local HealBot_InCombatUpdCnt=0
local b=nil
local HealBot_Comms_Blacklist={}
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,
                       }
					   

local HealBot_Ignore_Class_Debuffs = {
    [HEALBOT_WARRIOR] = { [HEALBOT_DEBUFF_ANCIENT_HYSTERIA] = true,	
                          [HEALBOT_DEBUFF_IGNITE_MANA] = true, 
                          [HEALBOT_DEBUFF_TAINTED_MIND] = true, 
                          [HEALBOT_DEBUFF_VIPER_STING] = true,
                          [HEALBOT_DEBUFF_IMPOTENCE] = true,
                          [HEALBOT_DEBUFF_DECAYED_INT] = true,
                          [HEALBOT_DEBUFF_UNSTABLE_AFFL] = true,},
    [HEALBOT_ROGUE] = {   [HEALBOT_DEBUFF_SILENCE] = true,	
                          [HEALBOT_DEBUFF_ANCIENT_HYSTERIA] = true, 
                          [HEALBOT_DEBUFF_IGNITE_MANA] = true, 
                          [HEALBOT_DEBUFF_TAINTED_MIND] = true, 
                          [HEALBOT_DEBUFF_VIPER_STING] = true,
                          [HEALBOT_DEBUFF_IMPOTENCE] = true,
                          [HEALBOT_DEBUFF_DECAYED_INT] = true,
                          [HEALBOT_DEBUFF_UNSTABLE_AFFL] = true,},
    [HEALBOT_HUNTER] = {  [HEALBOT_DEBUFF_MAGMA_SHACKLES] = true, 
                          [HEALBOT_DEBUFF_UNSTABLE_AFFL] = true,},
    [HEALBOT_MAGE] = {    [HEALBOT_DEBUFF_MAGMA_SHACKLES] = true, 
                          [HEALBOT_DEBUFF_DECAYED_STR] = true,
                          [HEALBOT_DEBUFF_CRIPPLE] = true,
                          [HEALBOT_DEBUFF_UNSTABLE_AFFL] = true,},
    [HEALBOT_DRUID] = {   [HEALBOT_DEBUFF_UNSTABLE_AFFL] = true,},
    [HEALBOT_PALADIN] = { [HEALBOT_DEBUFF_UNSTABLE_AFFL] = true,},
    [HEALBOT_PRIEST] = {  [HEALBOT_DEBUFF_DECAYED_STR] = true,
                          [HEALBOT_DEBUFF_CRIPPLE] = true,
                          [HEALBOT_DEBUFF_UNSTABLE_AFFL] = true,},
    [HEALBOT_SHAMAN] = {  [HEALBOT_DEBUFF_UNSTABLE_AFFL] = true,},
    [HEALBOT_WARLOCK] = { [HEALBOT_DEBUFF_DECAYED_STR] = true,
                          [HEALBOT_DEBUFF_CRIPPLE] = true,
                          [HEALBOT_DEBUFF_UNSTABLE_AFFL] = true,},
};

local HealBot_Ignore_Movement_Debuffs = {
                                  [HEALBOT_DEBUFF_FROSTBOLT] = true,
                                  [HEALBOT_DEBUFF_MAGMA_SHACKLES] = true,
                                  [HEALBOT_DEBUFF_SLOW] = true,
                                  [HEALBOT_DEBUFF_CHILLED] = true,
                                  [HEALBOT_DEBUFF_CONEOFCOLD] = true,
                                  [HEALBOT_DEBUFF_CONCUSSIVESHOT] = true,
                                  [HEALBOT_DEBUFF_THUNDERCLAP] = true,
                                  [HEALBOT_DEBUFF_HOWLINGSCREECH] = true,
                                  [HEALBOT_DEBUFF_DAZED] = true,
								  [HEALBOT_DEBUFF_FROST_SHOCK] = true,
};

local HealBot_Ignore_FastDur_Debuffs = {
                                  [HEALBOT_DEBUFF_PSYCHIC_HORROR] = true,
                                  [HEALBOT_DEBUFF_CHILLED] = true,
                                  [HEALBOT_DEBUFF_CONEOFCOLD] = true,
                                  [HEALBOT_DEBUFF_CONCUSSIVESHOT] = true,
                                  [HEALBOT_DEBUFF_FALTER] = true,
};

local HealBot_Ignore_NonHarmful_Debuffs = {
                                  [HEALBOT_DEBUFF_HUNTERS_MARK] = true,
                                  [HEALBOT_DEBUFF_ARCANE_BLAST] = true,
                                  [HEALBOT_DEBUFF_MAJOR_DREAMLESS] = true,
                                  [HEALBOT_DEBUFF_GREATER_DREAMLESS] = true,
                                  [HEALBOT_DEBUFF_DREAMLESS_SLEEP] = true,
};

local HBchanid=nil
local HBhour=nil
local HBminute=nil
local HBleft=nil
local HBbottom=nil
local HBright=nil
local HBtop=nil
local gsnspellName=nil
local gsnsubSpellName=nil
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,
}
local Current=nil
local Desired=nil
local healingbonus_penalty=nil
local temp_Spell_cast=nil
local tmp=nil
local RealHealing=nil
local dforms=nil
local dactive=nil
local ghid=nil
local ghspellname=nil
local ghuName=nil
local ghspell=nil
local ghspellrank=nil
local usable=nil
local noMana=nil
local HealBot_Timer1,HealBot_Timer2 = 0,0;
local Ti=nil
local Tcnt=nil
local Tname=nil
local runit=nil
local inc_msg=nil
local datatype=nil
local datamsg=nil
local sender=nil
local pName=nil
local arr=nil
local unitname=nil
local arrg = {}
local iStart=nil
local iEnd=nil
local num=nil
local punitname=nil
local umuName=nil
local zone=nil
local HoTActive=nil
local uauName=nil
local hbi=nil
local hbName=nil
local DebuffType=nil
local cduName=nil
local icd=nil
local checkthis=nil
local WatchTarget=nil
local debuff_type=nil
local dName=nil
local HealBot_Ignore_Debuffs_Class=nil
local bName=nil
local icb=nil
local cbuName=nil
local buffname=nil
local PlayerBuffs = {}
local deserter=nil
local unitname=nil
local heal_val=nil
local heal_valn=nil
local tUnit=nil
local scsspell=nil
local Notify=nil
local chanid=nil
local addIcon=true
local button=nil
local bar=nil
local iconName=nil
local id=0
local cnt=0
local spellname=nil
local spellrank=nil
local ispell=nil
local nameTalent=nil
local currRank=nil
local HealBotPerf_BuffRefresh=0

function HealBot_GetHealingBonus()
  return HealBot_HealingBonus;
end

function HealBot_SetResetFlag(mode)
  if mode=="HARD" and not HealBot_InCombat then
    ReloadUI()
  else
    HealBot_Reset_flag=true
  end
end

function HealBot_GetHealBot_AddonMsgType()
  return HealBot_AddonMsgType;
end

function HealBot_RetHealBot_Ressing(uName)
  return HealBot_Ressing[uName];
end

function HealBot_RetNumCurrentSpells()
  return table.getn(HealBot_CurrentSpells)
end

function HealBot_UnsetHealBot_Ressing(uName)
  HealBot_Ressing[uName]=nil;
end

function HealBot_SetrSpells(hs,bs,ds,rs)
  HealBot_hSpell=hs
  HealBot_bSpell=bs
  HealBot_dSpell=ds
  HealBot_rSpell=rs
end

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

function HealBot_AddChat(HBmsg)
  HBchanid=HealBot_Comms_GetChan("HBmsg");
  if HBchanid and HealBot_SpamCnt < 7 then
    HealBot_SpamCnt=HealBot_SpamCnt+1;
    HBhour,HBminute = GetGameTime();
	if HBminute==0 then
      HBmsg="["..HBhour..":00] "..HBmsg;
    elseif HBminute<10 then
      HBmsg="["..HBhour..":0"..HBminute.."] "..HBmsg; 
    else
      HBmsg="["..HBhour..":"..HBminute.."] "..HBmsg; 
    end
    SendChatMessage(HBmsg , "CHANNEL", nil, HBchanid); 
  elseif ( DEFAULT_CHAT_FRAME ) then
    DEFAULT_CHAT_FRAME:AddMessage(HBmsg);
  end
end

function HealBot_AddDebug(HBmsg)
  HBchanid=HealBot_Comms_GetChan("HBmsg");
  if HBchanid and HealBot_SpamCnt < 7 then
    HealBot_SpamCnt=HealBot_SpamCnt+1;
    HBhour,HBminute = GetGameTime();
	if HBminute==0 then
      HBmsg="["..HBhour..":00] DEBUG: "..HBmsg;
    elseif HBminute<10 then
      HBmsg="["..HBhour..":0"..HBminute.."] DEBUG: "..HBmsg; 
    else
      HBmsg="["..HBhour..":"..HBminute.."] DEBUG: "..HBmsg; 
    end
    SendChatMessage(HBmsg , "CHANNEL", nil, HBchanid);
  end
end

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

function HealBot_ErrorCntReset()
  HealBot_ErrorCnt=0;
end

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

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

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

function HealBot_StopMoving(HBframe)
  if ( HBframe.isMoving ) then
    HBframe:StopMovingOrSizing();
    HBframe.isMoving = false;
  end
  if HealBot_Config.Panel_Anchor==1 then
    HBtop = HealBot_Action:GetTop();
	HBleft = HealBot_Action:GetLeft()
    if HBleft and HBtop then
      HealBot_Config.PanelAnchorY=HBtop;
	  HealBot_Config.PanelAnchorX=HBleft
    end
  elseif HealBot_Config.Panel_Anchor==2 then
    HBbottom = HealBot_Action:GetBottom();
	HBleft = HealBot_Action:GetLeft()
    if HBleft and HBbottom then
      HealBot_Config.PanelAnchorY=HBbottom;
	  HealBot_Config.PanelAnchorX=HBleft
    end
  elseif HealBot_Config.Panel_Anchor==3 then
    HBtop = HealBot_Action:GetTop();
	HBright = HealBot_Action:GetRight()
    if HBright and HBtop then
      HealBot_Config.PanelAnchorY=HBtop;
	  HealBot_Config.PanelAnchorX=HBright
    end
  elseif HealBot_Config.Panel_Anchor==4 then
    HBbottom = HealBot_Action:GetBottom();
	HBright = HealBot_Action:GetRight()
    if HBright and HBbottom then
      HealBot_Config.PanelAnchorY=HBbottom;
	  HealBot_Config.PanelAnchorX=HBright
    end
  end
end

function HealBot_SlashCmd(HBcmd)
  if (HBcmd=="") then
    HealBot_TogglePanel(HealBot_Action);
  end
  if (HBcmd=="o" or HBcmd=="options" or HBcmd=="opt" or HBcmd=="config" or HBcmd=="cfg") then
    HealBot_TogglePanel(HealBot_Options);
  end
  if HBcmd=="defaults" then
    HealBot_Options_Defaults_OnClick(HealBot_Options_Defaults);
  end
  if (HBcmd=="ui") then
    HealBot_SetResetFlag("HARD")
  end
  if (HBcmd=="ri" or HBcmd=="reset" or HBcmd=="x") then
    HealBot_SetResetFlag("SOFT")
  end
  if (HBcmd=="info" or HBcmd=="ver") then
    HealBot_Comms_Info()
  end
  if (HBcmd=="chan") then
    HealBot_AddDebug( "Channel active" );
  end
  if (HBcmd=="status") then
    HealBot_Comms_DebugStatus();
  end
  if (HBcmd=="show") then
    HealBot_Action_Reset()
  end
end

function HealBot_Reset()
    HealBot_Loaded=false
	HB_Timer2=2000
    HB_InitSpells=true
	HealBot_NeedEquipUpdate=5
    HealBot_UnRegister_Events()
	HealBot_Action_SetAllBars()
	HealBot_Action_SetAllAttribs()
	HealBot_LoadHealBot()
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 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
    if (UnitInRaid("target")) then 
      for i=1,40 do
        if UnitIsUnit("target","raid"..i) then return "raid"..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
  gsnspellName, gsnsubSpellName = GetSpellName(id,BOOKTYPE_SPELL);
  if (not gsnspellName) then
    return nil;
  end
  if (not gsnsubSpellName or gsnsubSpellName=="") then
    return gsnspellName;
  end
  return gsnspellName, gsnsubSpellName;
end

function HealBot_GetSpellId(spell)
  sid,sidd = 1,0;
  if HealBot_Spells[spell] then   
    if HealBot_Spells[spell].sid then return HealBot_Spells[spell].sid; end
  end
  while true do 
    gidspellName, gidsubSpellName = GetSpellName(sid,BOOKTYPE_SPELL);
    if (gidspellName) then
      if (spell == gidspellName .. " (" .. gidsubSpellName .. ")") or (spell == gidspellName .. "(" .. gidsubSpellName .. ")") then
       return sid;
      end
      if (spell == gidspellName) then
        sidd=sid;
      end   
    else
      do break end
    end
    sid = sid + 1;
  end
  if sidd>0 then
    return sidd
  else
    return nil;
  end
end

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

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

function HealBot_UnitHealth(unit)
  Current,Desired = UnitHealth(unit),UnitHealthMax(unit);
  if unit=='target' and Desired==100 then
    if HealBot_Health60[UnitClass(unit)] and UnitLevel(unit)>0 then
      Desired = math.floor(HealBot_Health60[UnitClass(unit)]/60*UnitLevel(unit)+0.5)
    else
      Desired = UnitHealthMax('player');
    end
    Current = Desired/100*Current;
  end
  return Current,Desired;
end

function HealBot_FindHealSpells()
  if HB_InitSpells then HealBot_NeedEquipUpdate=1; return; end
  
  HealBot_HealingBonus=GetSpellBonusHealing();
        
  table.foreach(HealBot_CurrentSpells, function (index,spell)
    if (HealBot_Spells[spell]) then
      if HealBot_CalcEquipBonus then
        if HealBot_Spells[spell].NoBonus then
          HealBot_Spells[spell].RealHealing = 0
        else
          healingbonus_penalty=1;
          if HealBot_Spells[spell].Level < 20 then
            healingbonus_penalty=(1-((20-HealBot_Spells[spell].Level)*0.0375));
          end
          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));
          tmp = ((HealBot_Spells[spell].Level)+6)/(UnitLevel("player"))
          if tmp<1 then RealHealing=RealHealing*tmp; end
          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 HealBot_CalcEquipBonus then
	HealBot_Comms_SendAddonMsg("HealBot", ">> HealerBonus <<=>> "..HealBot_PlayerName.." <<=>> "..HealBot_HealingBonus, HealBot_AddonMsgType, HealBot_PlayerName)
  end
  HealBot_CalcEquipBonus=false;
end

function HealBot_GetShapeshiftForm()
  dforms = GetNumShapeshiftForms();
  if dforms then
    for i=1,dforms do
      _,_,dactive = GetShapeshiftFormInfo(i);
      if dactive then return i; end
    end
  end
  return 0;
end

function HealBot_GetHealSpell(unit,pattern)
  ghuName=UnitName(unit);
  
  if HealBot_PlayerDead then return nil end;
 
  if not HealBot_Spells[pattern] then
    ghid = HealBot_GetSpellId(pattern);
  elseif HealBot_Spells[pattern].id then
    ghid = HealBot_Spells[pattern].id
  else
    ghid = HealBot_GetSpellId(pattern);
  end
  ghspell, ghspellrank = HealBot_GetSpellName(ghid)
  if not ghspell then 
    if pattern then
      if ghuName~=HealBot_PlayerName then
        if IsItemInRange(pattern,unit)~=1 then
          return nil
        else
          return pattern;
        end
      else
        usable, noMana = IsUsableItem(pattern, unit)
        if not usable then 
          return nil
        else
          return pattern;
        end
      end
    else
      return nil
    end
  end

  if ghspellrank then
    ghspellname=ghspell;
    ghspell=ghspell .. "(" .. ghspellrank .. ")";
  end
  
  if ghuName~=HealBot_PlayerName then
    if ghspellname==HEALBOT_PRAYER_OF_HEALING then
      if UnitInParty(unit) then
        if IsSpellInRange(HealBot_dSpell, unit)~=1 then return nil end;
      else
        return nil;
      end
    else
      if IsSpellInRange(HealBot_hSpell, unit)~=1 then return nil end;
    end
  end
 
  return ghspell;
end

function HealBot_RecalcHeals(unit)
  if not HealBot_Loaded or HealBot_Config.DisableHealBot==1 then return end
  HealBot_Action_Refresh(unit);
end

function HealBot_RecalcParty(HealBot_PreCombat)
  HealBot_Action_PartyChanged(HealBot_PreCombat);
end

function HealBot_RecalcSpells()
  if not HealBot_Loaded or HealBot_Config.DisableHealBot==1 then return end
  HealBot_FindHealSpells();
end

function HealBot_OnLoad(this)
    HealBot_PlayerClass, HealBot_PlayerClassEN=UnitClass("player")
    HealBot_PlayerName=UnitName("player")
    this:RegisterEvent("VARIABLES_LOADED");
    SLASH_HEALBOT1 = "/healbot";
    SLASH_HEALBOT2 = "/hb";
    SlashCmdList["HEALBOT"] = function(msg)
      HealBot_SlashCmd(msg);
    end
    HealBot_AddError(HEALBOT_ADDON .. HEALBOT_LOADED);
end

local ouName=nil
local aSwitch=0

function HealBot_Set_Timers()
  if HealBot_Config.DisableHealBot==0 then
    HB_Timer1=1
	HB_Timer2=HealBot_Config.RangeCheckFreq
  else
    HB_Timer1=5
	HB_Timer2=2000
  end
end
  
function HealBot_OnUpdate(this,arg1)
  HealBot_Timer1 = HealBot_Timer1+arg1;
  HealBot_Timer2 = HealBot_Timer2+arg1;
  if HealBot_Timer2>HB_Timer2 then
    HealBot_Timer2=0
	if not HealBot_Loaded or HealBot_Config.DisableHealBot==1 then return end
	if HealBot_Config.ShowAggro==1 then aSwitch=aSwitch+1 end
	if aSwitch>2 then
	  HealBot_CheckAggro()
	  aSwitch=0
	else
	  HealBot_Action_RefreshButtons()
	end
  end
  if HealBot_Timer1>=HB_Timer1 then
    HealBot_Timer1 = 0;
	Ti=0;
	
    if not HealBot_IsFighting then
      for unit,_ in pairs(HealBot_DelayDebuffCheck) do
		ouName=UnitName(unit)
		if not HealBot_UnitDebuff[ouName] then
           HealBot_CheckUnitDebuffs(unit)
		   Ti=Ti+1
		end
        HealBot_DelayDebuffCheck[unit] = nil;
        if Ti>9 then 
	      do break end;
	    end
      end
      for unit,_ in pairs(HealBot_DelayBuffCheck) do
        if Ti>7 then 
		  do break end;
		end
		ouName=UnitName(unit)
		if not HealBot_UnitBuff[ouName] then
          HealBot_DelayBuffCheck[unit] = nil;
          Ti=Ti+1
        end        
		HealBot_CheckUnitBuffs(unit)
      end
      if HealBot_Reset_flag then
		HealBot_Reset_flag=false
        HealBot_Reset()
	  elseif HB_InitSpells then
          HB_InitSpells=false;
          Tcnt=HealBot_InitSpells();
          HealBot_NeedEquipUpdate=1;
      elseif Delay_RecalcParty>0 and not HealBot_InCombatUpdate then
        Delay_RecalcParty=Delay_RecalcParty+1
        if Delay_RecalcParty>3 then
          Delay_RecalcParty=0;
          HealBot_RecalcParty();
		  HealBot_InCombatUpdCnt=0
        end
      elseif HealBot_FlagEquipUpdate1>0 and HealBot_FlagEquipUpdate2>0 then
	    HealBot_FlagEquipUpdate1=0;
	    HealBot_FlagEquipUpdate2=0;
	    HealBot_NeedEquipUpdate=1;
	  elseif HealBot_FlagEquipUpdate1>0 then
	    HealBot_FlagEquipUpdate1=HealBot_FlagEquipUpdate1+1;
        if HealBot_FlagEquipUpdate1>3 then
	      HealBot_FlagEquipUpdate1=0;
	    end
      elseif HealBot_FlagEquipUpdate2>0 then
	    HealBot_FlagEquipUpdate2=HealBot_FlagEquipUpdate2+1;
        if HealBot_FlagEquipUpdate2>3 then
	      HealBot_FlagEquipUpdate2=0;
          HealBot_Options_Debuff_Reset();
	    end
      elseif HealBot_CheckZoneFlag>0 then
        HealBot_CheckZoneFlag=HealBot_CheckZoneFlag+1;
        if HealBot_CheckZoneFlag>7 then
          HealBot_CheckZoneFlag=0; 
          HealBot_CheckZone();
        end          
      elseif HealBot_NeedEquipUpdate>0 then
        HealBot_NeedEquipUpdate=HealBot_NeedEquipUpdate+1;
        if HealBot_NeedEquipUpdate>5 then
          HealBot_CalcEquipBonus=true;
          HealBot_NeedEquipUpdate=0; 
          HealBot_RecalcSpells();
        end          
      elseif HealBot_CheckForDivineSpirit then
        HealBot_CheckForDivineSpirit=false
        Tcnt=0;
        Ti=1;
        while true do
          Tname,_,_,_,_,_ = UnitBuff("player",Ti) 
          if Tname then
            if Tname==HEALBOT_DIVINE_SPIRIT or Tname==HEALBOT_PRAYER_OF_SPIRIT then
              Tcnt=1;
              do break end;
            end
            Ti = Ti + 1;
          else
            do break end
          end
        end
        if Tcnt~=HealBot_HasDivineSpirit then
          HealBot_HasDivineSpirit=Tcnt;
          HealBot_NeedEquipUpdate=1;
        end
      end
    else
	  HealsIn_Timer=0;
    end
    HealBot_SpamCnt = 0;
    if HealBot_RequestVer then
      HealBot_Comms_SendAddonMsg("HealBot", ">> SendVersion <<=>> "..HealBot_RequestVer.." <<=>> Version="..HEALBOT_VERSION, HealBot_AddonMsgType, HealBot_PlayerName)
      HealBot_RequestVer=nil;
    end
    
    for j in pairs(HealBot_Ressing) do
      if HealBot_Ressing[j]=="_NIL_" then 
        HealBot_Ressing[j]=nil;
		if HealBot_UnitID[j] then HealBot_Action_ResetUnitStatus(HealBot_UnitID[j]) end
       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

    if HealBot_DelayData>0 then
      if HealBot_DelayData==5 then
	    HealBot_DelayData=-1
        HealBot_Register_Events()
		HealBot_Comms_SendAddonMsg("HealBot", ">> RequestVersion <<=>> "..HealBot_PlayerName.." <<=>> nil <<", HealBot_AddonMsgType, HealBot_PlayerName)
      elseif HealBot_DelayData==4 then
		HealBot_Comms_SendAddonMsg("HealBot", ">> SendVersion <<=>> "..HealBot_PlayerName.." <<=>> Version="..HEALBOT_VERSION, HealBot_AddonMsgType, HealBot_PlayerName)
		HealBot_Loaded=true;
      elseif HealBot_DelayData==3 and HealBot_Config.DisableHealBot==0 then
	    if HealBot_Config.DisableHealBot==0 then HealBot_Action_ResetUnitStatus() end
      elseif HealBot_DelayData==2 then
          if HealBot_Config.BuffWatch==1 then HealBot_CheckAllBuffs(); end
          if HealBot_Config.DebuffWatch==1 then HealBot_CheckAllDebuffs(); end
          if HealBot_PlayerClassEN=="PRIEST" then HealBot_HasInnerFocus(); end
          HealBot_CheckForDivineSpirit=true;
		  if HealBot_Config.AutoClose==0 then HealBot_Config.ActionVisible=1; end
          if HealBot_Config.ActionVisible==1 then HealBot_Action:Show() end
		  HealBot_RecalcParty()
      elseif HealBot_DelayData==1 then
        HealBot_Options_EmergencyFilter_Reset()
        HealBot_Action_ResetSkin()
		HealBot_CheckZoneFlag=7
        HealBot_Options_Buff_Reset()
        HealBot_Options_Debuff_Reset()
      end
	  HealBot_DelayData=HealBot_DelayData+1
	else
	  HealBot_ThrottleCnt=0
    end

    for k in pairs(HealBot_HoT1) do
      HealBot_HoT1[k]=HealBot_HoT1[k]-1; 
      if HealBot_HoT1[k]<15 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]<15 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]<15 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

    if HealBot_HoT_MendingWatch>0 then
      HealBot_HoT_MendingWatch=HealBot_HoT_MendingWatch-1
      if HealBot_HoT_MendingWatch==0 then
        HealBot_HoT_Mending=0;
      end
    end
	
    for k in pairs(HealBot_HealsIn) do
      HealBot_HealersIncCnt[k]=HealBot_HealersIncCnt[k]+1; 
      if HealBot_HealersIncCnt[k]>=4 then
	     HealBot_HealsIn[k]=nil
         HealBot_Action_ResetUnitStatus(HealBot_UnitID[k])
      end
    end
	
	if HealBot_TargetBuffCheck then
        HealBot_TargetBuffCheck=false
        if HealBot_Config.BuffWatch==1 then HealBot_DelayBuffCheck["target"]=true; end
        if HealBot_Config.DebuffWatch==1 then HealBot_DelayDebuffCheck["target"]=true; end
	end
	
	if HealBot_InCombatUpdate then
		HealBot_IC_PartyMembersChanged()
    end
  end
end

function HealBot_RetVersion()
  return HEALBOT_VERSION
end

function HealBot_OnEvent(this, event, arg1,arg2,arg3,arg4)
  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_COMBAT") then
    HealBot_OnEvent_UnitCombat(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_START") then
	HealBot_OnEvent_UnitSpellcastStart(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=="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=="LEARNED_SPELL_IN_TAB") 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);
	HealBot_LoadHealBot();
--	HealBot_Config.TargetHeals = 0
--	HealBot_Options_TargetHeals:Disable()
    this:RegisterEvent("PLAYER_ENTERING_WORLD");
    this:RegisterEvent("PLAYER_LEAVING_WORLD");
end

function HealBot_LoadHealBot()
    HealBot_PlayerClass, HealBot_PlayerClassEN=UnitClass("player")
	HealBot_PlayerName=UnitName("player")
    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
    HB_InitSpells=true;
    HealBot_InitData();
    HealBot_HoT_Texture[HEALBOT_REJUVENATION]      = "Interface\\Icons\\Spell_Nature_Rejuvenation";
    HealBot_HoT_Texture[HEALBOT_REGROWTH]          = "Interface\\Icons\\Spell_Nature_ResistNature";
    HealBot_HoT_Texture[HEALBOT_LIFEBLOOM]          = "Interface\\Icons\\INV_Misc_Herb_Felblossom.jpg";
    HealBot_HoT_Texture[HEALBOT_RENEW]             = "Interface\\Icons\\Spell_Holy_Renew";
    HealBot_HoT_Texture[HEALBOT_POWER_WORD_SHIELD] = "Interface\\Icons\\Spell_Holy_PowerWordShield";
    HealBot_HoT_Texture[HEALBOT_PRAYER_OF_MENDING] = "Interface\\Icons\\Spell_Holy_PrayerOfMendingtga.jpg";
    HealBot_DelayData=1
end

function HealBot_Register_Events()
 if HealBot_Config.DisableHealBot==0 then
    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("LEARNED_SPELL_IN_TAB");
--    this:RegisterEvent("UNIT_SPELLCAST_START");
    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("UNIT_PET");
    this:RegisterEvent("UNIT_NAME_UPDATE");
    this:RegisterEvent("UNIT_COMBAT")
--    this:RegisterEvent("PARTY_MEMBER_DISABLE");
--    this:RegisterEvent("PARTY_MEMBER_ENABLE");
    HealBot_Comms_SendAddonMsg("CTRA", "SR", HealBot_AddonMsgType, HealBot_PlayerName)
  end
  this:RegisterEvent("UNIT_SPELLCAST_SENT");
  this:RegisterEvent("CHAT_MSG_ADDON");
  this:RegisterEvent("ZONE_CHANGED_NEW_AREA");
  this:RegisterEvent("UNIT_SPELLCAST_STOP");
  this:RegisterEvent("UNIT_SPELLCAST_FAILED");
  this:RegisterEvent("UNIT_SPELLCAST_INTERRUPTED");
  this:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED");
  
  HealBot_Set_Timers()
  HealBot_Action_Set_Timers()
  HealBot_Options_Set_Timers()
end

function HealBot_UnRegister_Events()

	HB_Timer2=2000
	HealBot_Action_Set_Timers(true)
	HealBot_Options_Set_Timers(true)
    
    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("LEARNED_SPELL_IN_TAB");
    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("UNIT_PET");
    this:UnregisterEvent("UNIT_NAME_UPDATE");
    this:UnregisterEvent("UNIT_COMBAT")
	
--    this:UnregisterEvent("PARTY_MEMBER_DISABLE");
--    this:UnregisterEvent("PARTY_MEMBER_ENABLE");
end

local tauName=nil
local taUnit=nil
function HealBot_CheckAggro()
  for aUnit,oUnit in pairs(HealBot_Aggro) do 
    if UnitIsEnemy(aUnit, aUnit.."target") then
	  tauName=UnitName(aUnit.."targettarget")
	  if tauName~=UnitName(aUnit) then
	    if UnitIsEnemy(oUnit, oUnit.."target") then
		  tauName=UnitName(oUnit.."targettarget")
		  if tauName~=UnitName(aUnit) then
		    HealBot_SetAggro(oUnit)
            HealBot_Aggro[aUnit]=nil
            HealBot_Action_UpdateAggro(aUnit,false)
		  end
		else
		  HealBot_SetAggro(aUnit)
          HealBot_Aggro[aUnit]=nil
          HealBot_Action_UpdateAggro(aUnit,false)
		end
      end
	elseif UnitIsEnemy(oUnit, oUnit.."target") then
	  tauName=UnitName(oUnit.."targettarget")
	  if tauName~=UnitName(aUnit) then
	    HealBot_SetAggro(oUnit)
        HealBot_Aggro[aUnit]=nil
        HealBot_Action_UpdateAggro(aUnit,false)
	  end
	else
      HealBot_Aggro[aUnit]=nil
      HealBot_Action_UpdateAggro(aUnit,false)
	end
  end
end

function HealBot_SetAggro(unit)
    tauName=UnitName(unit.."targettarget")
	taUnit=HealBot_UnitID[tauName]
	if taUnit then
      HealBot_Aggro[taUnit]=unit
	  HealBot_Action_UpdateAggro(taUnit,true)
	end
end

local tmpn=0
function HealBot_RetSetAggroSize()
  tmpn=0
  for aUnit,oUnit in pairs(HealBot_Aggro) do 
	  tmpn=tmpn+1
  end
  return tmpn
end

function HealBot_ClearAggro()
  for aUnit,oUnit in pairs(HealBot_Aggro) do 
	HealBot_Aggro[aUnit]=nil
	HealBot_Action_UpdateAggro(aUnit,false)
  end
end

function HealBot_OnEvent_AddonMsg(this,addon_id,msg,distribution,sender_id)
  inc_msg = gsub(msg, "%$", "s");
  if addon_id==HEALBOT_ADDON_ID then
	_,_,heal_val,unitname = strfind(inc_msg, ">> (.%d+) <<=>> (.+)$" );
    HealBot_IncHeal(sender_id,unitname,heal_val)
	HealBot_HealersIncCnt[unitname]=0
  elseif addon_id=="HealBot" then
    pName=UnitName("player");
    _,_, datatype, sender, datamsg = strfind(inc_msg, ">> (%a+) <<=>> (%a+) <<=>> (.+)");
    if datatype=="RequestVersion" then
      HealBot_RequestVer=sender;
    elseif datatype=="SendVersion" then
	  HealBot_Vers[sender_id]=datamsg
	  HealBot_Comms_Blacklist[sender_id]=true
      HealBot_AddDebug(sender_id..":  "..datamsg);
	elseif datatype=="HealerBonus" then
	  HealBot_HealersBonus[sender]=datamsg
    end
  elseif addon_id=="CTRA" then
    if ( strfind(inc_msg, "#") ) then
      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)
  elseif addon_id=="VisualHeal" and not HealBot_Comms_Blacklist[sender_id] then
    _, _, unitname, heal_val = string.find(msg, "^%d+:(.+):(%d+):")
	HealBot_IncHeal(sender_id,unitname,heal_val)
	HealBot_HealersIncCnt[unitname]=2
  elseif addon_id=="HealComm" and not HealBot_Comms_Blacklist[sender_id] then
    _, _, unitname, heal_val = string.find(msg, "^(.+):(%d+)")
    HealBot_IncHeal(sender_id,unitname,heal_val)
	HealBot_HealersIncCnt[unitname]=2
  end
end

function HealBot_IncHeal(sender_id,unitname,heal_val)
  if heal_val and unitname then
	  HealBot_HealsInUpdate(unitname,heal_val)
      if tonumber(heal_val)>0 then
        HealBot_Healers[sender_id] = ">> "..heal_val.." <<=>> "..unitname
	  else
	    HealBot_Healers[sender_id] = nil
      end
  end
end

function HealBot_GetInfo()
  return HealBot_Vers, HealBot_HealersBonus
end

function HealBot_Split(msg, char)
  for x,_ in pairs(arrg) do
    arrg[x]=nil;
  end
	while (strfind(msg, char) ) do
		iStart, iEnd = strfind(msg, char);
		tinsert(arrg, strsub(msg, 1, iStart-1));
		msg = strsub(msg, iEnd+1, strlen(msg));
	end
	if ( strlen(msg) > 0 ) then
		tinsert(arrg, msg);
	end
	return arrg;
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
        _,_, punitname = strfind(inc_msg, "^RES (.+)$");
        if ( punitname ) then
          HealBot_Ressing[punitname] = sender_id;
          HealBot_RecalcHeals(HealBot_UnitID[punitname]);
         end
      end
    elseif ( strsub(inc_msg, 1, 4) == "SET " ) then
      _,_, num, punitname = strfind(inc_msg, "^SET (%d+) (.+)$");
      if ( num and punitname ) then
        for k in pairs(HealBot_MainTanks) do
          if ( HealBot_MainTanks[k] == punitname ) then
            HealBot_MainTanks[k] = nil;
          end
        end
        HealBot_MainTanks[tonumber(num)] = punitname;
        Delay_RecalcParty=3;
      end
    elseif ( strsub(inc_msg, 1, 2) == "R " ) then
      _,_, punitname = strfind(inc_msg, "^R (.+)$");
      if ( punitname ) then
        for k in pairs(HealBot_MainTanks) do
          if ( HealBot_MainTanks[k] == punitname ) then
            HealBot_MainTanks[k] = nil;
            Delay_RecalcParty=3;
          end
        end
      end
    end
end

function HealBot_RetHealsIn(uName)
  return HealBot_HealsIn[uName] or 0;
end

function HealBot_ClearHealsIn(uName)
  if HealBot_HealsIn[uName] then HealBot_HealsIn[uName]=nil end
end

function HealBot_OnEvent_UnitHealth(this,unit)
  unit=HealBot_RaidUnit(unit,UnitName(unit))
    if not HealBot_UnitName[unit] then return end
    HealBot_RecalcHeals(unit);
	if HealBot_Config.ShowAggro==1 and UnitAffectingCombat(unit) and UnitIsEnemy(unit, unit.."target") then
	  HealBot_SetAggro(unit)
	end
end

function HealBot_OnEvent_UnitMana(this,unit)
  unit=HealBot_RaidUnit(unit,UnitName(unit))
  if not HealBot_UnitName[unit] then return end
  umuName=HealBot_UnitName[unit]
  if umuName==HealBot_PlayerName then
    if HealBot_Action_TooltipUnit then
       HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit);
    elseif HealBot_Action_DisableTooltipUnit then
       HealBot_Tooltip_RefreshDisabledTooltip(HealBot_Action_DisableTooltipUnit);
    end
  end
  HealBot_Action_RefreshBar3(unit)
  if HealBot_Config.ShowAggro==1 and UnitAffectingCombat(unit) and UnitIsEnemy(unit, unit.."target") then
    HealBot_SetAggro(unit)
  end
end

function HealBot_OnEvent_UnitCombat(this,unit)
  unit=HealBot_RaidUnit(unit,UnitName(unit))
  if not HealBot_UnitName[unit] then return end
  if HealBot_Config.ShowAggro==1 and UnitAffectingCombat(unit) and UnitIsEnemy(unit, unit.."target") then
    HealBot_SetAggro(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_Tooltip_RefreshDisabledTooltip(HealBot_Action_DisableTooltipUnit);
  end
end

function HealBot_OnEvent_ZoneChanged(this)
  HealBot_CheckZoneFlag=5
  HealBot_Action_ResetUnitStatus(HealBot_UnitID[HealBot_PlayerName])
end

function HealBot_CheckZone()
  zone = GetRealZoneText()
  if zone==HEALBOT_ZONE_AB or zone==HEALBOT_ZONE_WG  or zone==HEALBOT_ZONE_AV or zone==HEALBOT_ZONE_ES then
    HealBot_InBG=true;
  else
    HealBot_InBG=false;
  end
  HealBot_SetAddonComms()
  Delay_RecalcParty=1
end

function HealBot_OnEvent_UnitAura(this,unit)
  unit=HealBot_RaidUnit(unit,UnitName(unit))
  if not HealBot_UnitName[unit] then return end
  uauName=HealBot_UnitName[unit]
  
  if HealBot_Config.DebuffWatch==1 and uauName and unit~="target" then
    if HealBot_Config.DebuffWatchInCombat==0 and HealBot_IsFighting then
      HealBot_DelayDebuffCheck[unit]=true;
    else
      HealBot_CheckUnitDebuffs(unit);
    end
  end
  if HealBot_Config.BuffWatch==1 and uauName and unit~="target" then 
    if HealBot_Config.BuffWatchInCombat==0 and HealBot_IsFighting then
      HealBot_DelayBuffCheck[unit]=true;
    else
      HealBot_CheckUnitBuffs(unit);
    end
  end
  
  if uauName==HealBot_PlayerName and HealBot_PlayerClassEN=="PRIEST" then
    HealBot_CheckForDivineSpirit=true;
    if HealBot_InnerFocusTalent then HealBot_CheckForInnerFocus(); end
  end
  
  if unit==HealBot_Action_TooltipUnit then
    HealBot_Action_RefreshTooltip(HealBot_Action_TooltipUnit);
  elseif unit==HealBot_Action_DisableTooltipUnit then
    HealBot_Tooltip_RefreshDisabledTooltip(HealBot_Action_DisableTooltipUnit);
  end
  
  if HealBot_HoT1[uauName] then
    HoTActive=HealBot_HasBuff(HealBot_HoT1_Spell[uauName], unit)
    if not HoTActive then 
      if HealBot_HoT1_Spell[uauName]==HEALBOT_PRAYER_OF_MENDING then
        HealBot_HoT_Mending=HealBot_HoT_Mending-1;
        if HealBot_HoT_MendingWith==uauName then
          HealBot_HoT_MendingWatch=2;
        end
      end;
      HealBot_HoT1[uauName]=0 
      HealBot_HoT_Update(1, HealBot_HoT1[uauName], uauName)    
    end
  end

  if HealBot_HoT2[uauName] then
    HoTActive=HealBot_HasBuff(HealBot_HoT2_Spell[uauName], unit)
    if not HoTActive then 
      if HealBot_HoT2_Spell[uauName]==HEALBOT_PRAYER_OF_MENDING then
        HealBot_HoT_Mending=HealBot_HoT_Mending-1;
        if HealBot_HoT_MendingWith==uauName then
          HealBot_HoT_MendingWatch=2;
        end
      end;
      HealBot_HoT2[uauName]=0 
      HealBot_HoT_Update(2, HealBot_HoT2[uauName], uauName)    
    end
  end

  if HealBot_HoT3[uauName] then
    HoTActive=HealBot_HasBuff(HealBot_HoT3_Spell[uauName], unit)
    if not HoTActive then 
      if HealBot_HoT3_Spell[uauName]==HEALBOT_PRAYER_OF_MENDING then
        HealBot_HoT_Mending=HealBot_HoT_Mending-1;
        if HealBot_HoT_MendingWith==uauName then
          HealBot_HoT_MendingWatch=2;
        end
      end;
      HealBot_HoT3[uauName]=0 
      HealBot_HoT_Update(3, HealBot_HoT3[uauName], uauName)    
    end
  end  
  
  if HealBot_HoT_Waiting[uauName] then
    HoTActive=HealBot_HasBuff(HealBot_HoT_WaitingSpellName[uauName], unit)
    if HoTActive then
      HealBot_HoT_Update(nil, HealBot_Spells[HealBot_HoT_WaitingSpell[uauName]].Duration, uauName, HealBot_HoT_WaitingSpellName[uauName])
      if HealBot_HoT_WaitingSpellName[uauName]==HEALBOT_PRAYER_OF_MENDING then
        HealBot_HoT_MendingWith=uauName;
      end
      HealBot_HoT_Waiting[uauName]=nil   
      HealBot_HoT_WaitingSpell[uauName]=nil         
      HealBot_HoT_WaitingSpellName[uauName]=nil 
    end
  end  

  if HealBot_HoT_Mending>0 then
    HoTActive=HealBot_HasBuff(HEALBOT_PRAYER_OF_MENDING, unit)
    if HoTActive then
      if HealBot_HoT_MendingWith~=Member_Name  then
        HealBot_HoT_Update(nil, HealBot_Spells[HEALBOT_PRAYER_OF_MENDING..HEALBOT_RANK_1].Duration, uauName, HEALBOT_PRAYER_OF_MENDING)
        HealBot_HoT_MendingWith=uauName;
        HealBot_HoT_MendingWatch=0;
      end
    end
  end
  
end

function HealBot_CheckForInnerFocus()
  HealBot_InnerFocus=HealBot_HasBuff(HEALBOT_INNER_FOCUS,"player")
end

function HealBot_HasBuff(buffName, unit)
  hbi=1;
  while true do
    hbName,_,_,_,_,_ = UnitBuff(unit,hbi)
    hbi=hbi+1
    if hbName then
      if hbName==buffName then
        return true;
      end
    else
      do break end;
    end
  end
  return false;
end

function HealBot_CheckAllBuffs(unit)
  if HealBot_Config.BuffWatch==1 then 
    if unit then
	  HealBot_DelayBuffCheck[unit]=true
	else
      for x,_ in pairs(HealBot_DelayBuffCheck) do
        HealBot_DelayBuffCheck[x]=nil;
      end
      for unit,_ in pairs(HealBot_UnitName) do
         if unit~="target" then
           HealBot_DelayBuffCheck[unit]=true;
         end
      end
	end
  end
end

function HealBot_ClearAllBuffs()
    for x,_ in pairs(HealBot_DelayBuffCheck) do
      HealBot_DelayBuffCheck[x]=nil;
    end
end

function HealBot_CheckAllDebuffs(unit)
  if HealBot_Config.DebuffWatch==1 then 
    if unit then
	  HealBot_DelayDebuffCheck[unit]=true
	else
      for x,_ in pairs(HealBot_DelayDebuffCheck) do
        HealBot_DelayDebuffCheck[x]=nil;
      end
      for unit,_ in pairs(HealBot_UnitName) do
         if unit~="target" then
           HealBot_DelayDebuffCheck[unit]=true;
         end
      end
	end
  end
end

function HealBot_ClearAllDebuffs()
    for x,_ in pairs(HealBot_DelayDebuffCheck) do
      HealBot_DelayDebuffCheck[x]=nil;
    end
end

local DebuffIn=nil
local DebuffClass=nil
function HealBot_CheckUnitDebuffs(unit)
  unit=HealBot_RaidUnit(unit,UnitName(unit))
  if not HealBot_Unit_Button[unit] then return; end
  cduName=UnitName(unit);
  DebuffClass=UnitClass(unit) or HEALBOT_WARRIOR
  DebuffType=nil;
  icd = 1;
  DebuffIn=HealBot_UnitDebuff[cduName] or "x"
  while true do
    dName,_,_,_,debuff_type = UnitDebuff(unit,icd)
    if dName then
      icd = icd + 1;
      checkthis=false;
      WatchTarget=HealBot_DebuffWatchTarget[debuff_type];
      if WatchTarget then 
        if WatchTarget["Raid"] then
          checkthis=true;
        elseif WatchTarget["Party"] and (UnitInParty(unit) or cduName==HealBot_PlayerName) then
          checkthis=true;
        elseif WatchTarget["Self"] and cduName==HealBot_PlayerName then
		  checkthis=true
		elseif WatchTarget[DebuffClass] then
          checkthis=true;
		elseif WatchTarget["PvP"] and UnitIsPVP("player") then
		  checkthis=true;
        end
       
        if checkthis then
          if HealBot_Config.IgnoreMovementDebuffs==1 and HealBot_Ignore_Movement_Debuffs[dName] then
            checkthis=false;
          elseif HealBot_Config.IgnoreFastDurDebuffs==1 and HealBot_Ignore_FastDur_Debuffs[dName] then
            checkthis=false;
          elseif HealBot_Config.IgnoreNonHarmfulDebuffs==1 and HealBot_Ignore_NonHarmful_Debuffs[dName] then
            checkthis=false;
          elseif HealBot_Config.IgnoreClassDebuffs==1 then
            HealBot_Ignore_Debuffs_Class=HealBot_Ignore_Class_Debuffs[DebuffClass];
            if HealBot_Ignore_Debuffs_Class[dName] then
              checkthis=false;
            end
          end
          if checkthis then
            HealBot_UnitDebuff[cduName]=debuff_type
            HealBot_UnitDebuff[cduName.."_debuff_name"]=dName
            DebuffType=debuff_type;
            if HealBot_DebuffPriority==debuff_type then
              do break end
            end
          end
        end
      end
    else
      if not DebuffType then 
       if HealBot_UnitDebuff[cduName] then
		  HealBot_UnitDebuff[cduName] = nil;
	      if HealBot_ThrottleCnt>5 then
	        HealBot_Action_ResetUnitStatus(unit)
	      else
	        HealBot_RecalcHeals(unit)
	    	HealBot_ThrottleCnt=HealBot_ThrottleCnt+1
	      end
	    end
      end
      do break end
    end 
  end

  if HealBot_UnitDebuff[cduName] and HealBot_UnitDebuff[cduName]~=DebuffIn then
    if IsSpellInRange(HealBot_dSpell, unit)==1 or cduName==HealBot_PlayerName then
      if HealBot_Config.ShowDebuffWarning==1 then
        UIErrorsFrame:AddMessage(cduName.." suffers from "..HealBot_UnitDebuff[cduName.."_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
	  if HealBot_ThrottleCnt>5 then
	    HealBot_Action_ResetUnitStatus(unit)
	  else
	    HealBot_RecalcHeals(unit)
		HealBot_ThrottleCnt=HealBot_ThrottleCnt+1
	  end
	else
	  HealBot_Action_ResetUnitStatus(unit)
    end
  end
end

local BuffClass=nil
function HealBot_CheckUnitBuffs(unit)
  unit=HealBot_RaidUnit(unit,UnitName(unit))
  if not HealBot_Unit_Button[unit] then return; end
    cbuName=UnitName(unit);
	if not cbuName then return end
	BuffClass=UnitClass(unit) or HEALBOT_WARRIOR
	buffname=nil;
    icb = 1;

  for x,_ in pairs(PlayerBuffs) do
    PlayerBuffs[x]=nil;
  end

    while true do
	  bName,_,_,_,_,_ = UnitBuff(unit,icb) 
      if bName then
        PlayerBuffs[bName]=true
        icb = icb + 1;
      else
        do break end
      end
    end 
     
     for k in pairs(HealBot_BuffWatch) do
       checkthis=false;
       WatchTarget=HealBot_BuffWatchTarget[HealBot_BuffWatch[k]];
       if WatchTarget["Raid"] then
         checkthis=true;
       elseif WatchTarget["Party"] and (UnitInParty(unit) or cbuName==HealBot_PlayerName) then
         checkthis=true;
       elseif WatchTarget["Self"] and cbuName==HealBot_PlayerName then 
	     checkthis=true
	   elseif WatchTarget[BuffClass] then
         checkthis=true
	   elseif WatchTarget["PvP"] and UnitIsPVP("player") 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
	   if HealBot_UnitBuff[cbuName] and HealBot_UnitBuff[cbuName]==buffname then
	     return
	   else
         HealBot_UnitBuff[cbuName]=buffname;
	    if HealBot_ThrottleCnt>4 then
	      HealBot_Action_ResetUnitStatus(unit)
	    else
		  HealBot_RecalcHeals(unit)
		  HealBot_ThrottleCnt=HealBot_ThrottleCnt+1
	    end
	   end
     elseif HealBot_UnitBuff[cbuName] then 
	    HealBot_UnitBuff[cbuName]=nil
	    if HealBot_ThrottleCnt>4 then
	      HealBot_Action_ResetUnitStatus(unit)
	    else
		  HealBot_RecalcHeals(unit)
		  HealBot_ThrottleCnt=HealBot_ThrottleCnt+1
	    end
     end
     
end

function HealBot_OnEvent_PlayerRegenDisabled(this)
--  if HealBot_Config.AutoClose==1 and HealBot_Config.ActionVisible~=0 then HideUIPanel(HealBot_Action); end;
  if HealBot_Config.BuffWatch==1 and HealBot_Config.BuffWatchInCombat==0 then
    for member,_ in pairs(HealBot_UnitBuff) do
	  HealBot_UnitBuff[member]=nil
	  if HealBot_UnitID[member] and HealBot_Unit_Button[HealBot_UnitID[member]] then
        HealBot_RecalcHeals(HealBot_UnitID[member])
        HealBot_DelayBuffCheck[HealBot_UnitID[member]]=true
      end
    end
    HealBot_DelayBuffCheck[HealBot_UnitID[HealBot_PlayerName]]=true;
  end
    
  if HealBot_Config.DebuffWatch==1 and HealBot_Config.DebuffWatchInCombat==0 then
    for member,_ in pairs(HealBot_UnitDebuff) do
	  HealBot_UnitDebuff[member]=nil
	  if HealBot_UnitID[member] and HealBot_Unit_Button[HealBot_UnitID[member]] then
	    HealBot_RecalcHeals(HealBot_UnitID[member])
        HealBot_DelayDebuffCheck[HealBot_UnitID[member]]=true
      end
    end
    HealBot_DelayDebuffCheck[HealBot_UnitID[HealBot_PlayerName]]=true;
  end
  if HealBot_Config.AutoClose==1 and HealBot_Config.ActionVisible==0 then HealBot_TogglePanel(HealBot_Action) end
  if HealBot_Config.TargetHeals==1 then
    HealBot_RecalcParty(true);
  else
    HealBot_IsFighting = true;
  end
end

function HealBot_OnEvent_PlayerRegenEnabled(this)
  HealBot_IsFighting = false;
end

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

local unUnit=nil
function HealBot_OnEvent_UnitNameUpdate(this,unit)
  unUnit=HealBot_RaidUnit(unit,UnitName(unit))
  if not HealBot_Unit_Button[unUnit] then return end
  if HealBot_UnitName[unUnit] then
    if HealBot_UnitID[UnitName(unUnit)]~=unit then		
	  HealBot_Action_ResetUnitStatus(HealBot_UnitID[UnitName(unUnit)])
    end
    HealBot_UnitName[unUnit]=UnitName(unUnit)
    HealBot_UnitID[UnitName(unUnit)]=unUnit
    HealBot_CheckAllDebuffs(unUnit)
    HealBot_CheckAllBuffs(unUnit)
	b=HealBot_Unit_Button[unUnit]
	b.name=UnitName(unUnit)
	if HealBot_HoT_Active_Button[UnitName(unUnit)] then
	  if HealBot_HoT_Active_Button[UnitName(unUnit)]~=b then
		HealBot_HoT_MoveIcon(HealBot_HoT_Active_Button[UnitName(unUnit)], b, UnitName(unUnit))
		HealBot_HoT_Active_Button[UnitName(unUnit)]=b
      end
    end	
    HealBot_Action_ResetUnitStatus(unUnit)	
  end
end

local ruUnit=nil
function HealBot_RaidUnit(unit,uName)
  if GetNumRaidMembers()>0 then
    if uName==HealBot_PlayerName then
	  unit="player"
	elseif unit=="party1" or unit=="party2" or unit=="party3" or unit=="party4" then
      if HealBot_UnitID[uName] and UnitName(HealBot_UnitID[uName])==uName then
        unit=HealBot_UnitID[uName]
	  else
        for j=1,GetNumRaidMembers() do
          ruUnit = "raid"..j
	      if UnitName(ruUnit)==uName then
	        unit=ruUnit
		    do break end
          end
        end
	  end
    end
  end
  return unit
end

local icpmc=false
function HealBot_IC_PartyMembersChanged()
  icpmc=false
  HealBot_InCombatUpdCnt=HealBot_InCombatUpdCnt+1
  if HealBot_InCombatUpdCnt<5 then
    for unit,_ in pairs(HealBot_UpUnitInCombat) do
	  HealBot_UpUnitInCombat[unit]=nil
    end
    for unit,name in pairs(HealBot_UnitName) do
	  if not UnitName(unit) then 
	    HealBot_Action_ResetUnitStatus(unit)
      elseif name~=UnitName(unit) then
	    table.insert(HealBot_UpUnitInCombat,unit)
      end
    end
    table.foreach(HealBot_UpUnitInCombat, function (index,unit)
      HealBot_OnEvent_UnitNameUpdate(nil,unit)
	  icpmc=true
    end)
  end
  if icpmc then
    HealBot_AddDebug("ReVisit HealBot_IC_PartyMembersChanged")
	HealBot_InCombatUpdCnt=HealBot_InCombatUpdCnt+1
  else
	HealBot_InCombatUpdate=false
	if Delay_RecalcParty==0 then Delay_RecalcParty=2 end
	HealBot_InCombatUpdCnt=0
  end
end

function HealBot_OnEvent_PartyMembersChanged(this)
  if HealBot_Loaded then
    if HealBot_IsFighting then
      HealBot_InCombatUpdate=true
    else
      Delay_RecalcParty=3
      if HealBot_CheckZoneFlag==0 then HealBot_CheckZoneFlag=1 end
    end
  end
end

local HealBot_PrevComm=0
function HealBot_SetAddonComms()
  if not HealBot_InBG then
    if GetNumRaidMembers()>0 then
      HealBot_AddonMsgType=2;
    elseif GetNumPartyMembers()>0 then
      HealBot_AddonMsgType=3;
    else
      HealBot_AddonMsgType=4;
    end
  else
    HealBot_AddonMsgType=1;
  end
  if HealBot_PrevComm~=HealBot_AddonMsgType then
    HealBot_PrevComm=HealBot_AddonMsgType
    HealBot_Comms_SendAddonMsg("HealBot", ">> RequestVersion <<=>> "..HealBot_PlayerName.." <<=>> nil <<", HealBot_AddonMsgType, HealBot_PlayerName)
  end
end

function HealBot_OnEvent_PartyPetChanged(this)
  if HealBot_Config.PetHeals==1 and HealBot_Loaded and Delay_RecalcParty==0 then
    Delay_RecalcParty=3
  end
end

function HealBot_OnEvent_SystemMsg(this,msg)
  if type(msg)=="string" then
    _,_, deserter = strfind(msg, HB_HASLEFTRAID);
    if not deserter then
      _,_, deserter = strfind(msg, HB_HASLEFTPARTY);
    end
    if msg==HB_YOULEAVETHEGROUP or msg==HB_YOULEAVETHERAID or msg==HB_YOUJOINTHERAID or msg==HB_YOUJOINTHEGROUP then
        Delay_RecalcParty=2;
		HealBot_CheckZoneFlag=5
--    else
      -- find other messges
    end
  end
end

function HealBot_OnEvent_PlayerEquipmentChanged(this)
  HealBot_FlagEquipUpdate1=1;
end

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

function HealBot_OnEvent_SpellsChanged(this, arg1)
  if arg1==0 then return; end
  HB_InitSpells=true;
end

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

function HealBot_OnEvent_PlayerEnteringWorld(this)
  HealBot_Register_Events()
  HealBot_CheckZoneFlag=1
end

function HealBot_OnEvent_PlayerLeavingWorld(this)
  HealBot_UnRegister_Events();
  HB_Timer1=0.8
end

function HealBot_OnEvent_UnitSpellcastSent(this,caster,spellname,rank,target)
  tUnit = HealBot_UnitID[target];
  if not tUnit then
    for j=1,4 do
      if UnitName("party"..j) and UnitName("party"..j)==target then
        tUnit="party"..j
		do break end
	  end
	  if UnitName("partypet"..j) and UnitName("partypet"..j)==target then
		tUnit="partypet"..j
		do break end
	  end
	end
    if GetNumRaidMembers()>0 and not tUnit then
	  for j=1,GetNumRaidMembers() do
	    if UnitName("raid"..j) and UnitName("raid"..j)==target then
		  tUnit="raid"..j
		  do break end
		end
	    if UnitName("raidpet"..j) and UnitName("raidpet"..j)==target then
		  tUnit="raidpet"..j
		  do break end
		end
	  end
	end
  end
  if not tUnit then tUnit="target" end
  scsspell=spellname.."("..rank..")"
  if caster=="player" then
    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_Comms_SendAddonMsg("CTRA", "RES "..HealBot_IamRessing, HealBot_AddonMsgType, HealBot_PlayerName)
      end
      HealBot_CastingSpell  = scsspell;
      HealBot_CastingTarget = tUnit;
      if HealBot_Config.CastNotify>1 then
        HealBot_CastNotify(scsspell,target)
      end
    elseif HealBot_Spells[scsspell] then
      HealBot_ClearIncHeal();
      HealBot_IsCasting = true;
      if HealBot_Spells[scsspell].CastTime>1 then
        HealBot_HealValue=HealBot_Spells[scsspell].HealsDur;
        if spellname==HEALBOT_BINDING_HEAL then
          HealBot_IamHealing[HealBot_PlayerName]=HealBot_PlayerName
          HealBot_IamHealing[target]=target;
        elseif spellname==HEALBOT_PRAYER_OF_HEALING then
          HealBot_IamHealing[HealBot_PlayerName]=HealBot_PlayerName;
          if UnitName("party1") and IsSpellInRange(HealBot_dSpell, "party1")==1 then
            HealBot_IamHealing[UnitName("party1")]=UnitName("party1");
          end
          if UnitName("party2") and IsSpellInRange(HealBot_dSpell, "party2")==1 then
            HealBot_IamHealing[UnitName("party2")]=UnitName("party2");
          end
          if UnitName("party3") and IsSpellInRange(HealBot_dSpell, "party3")==1 then
            HealBot_IamHealing[UnitName("party3")]=UnitName("party3");
          end
          if UnitName("party4") and IsSpellInRange(HealBot_dSpell, "party4")==1 then 
            HealBot_IamHealing[UnitName("party4")]=UnitName("party4");
          end
          if UnitName("partypet1") and IsSpellInRange(HealBot_dSpell, "partypet1")==1 then
            HealBot_IamHealing[UnitName("partypet1")]=UnitName("partypet1");
          end
          if UnitName("partypet2") and IsSpellInRange(HealBot_dSpell, "partypet2")==1 then
            HealBot_IamHealing[UnitName("partypet2")]=UnitName("partypet2");
          end
          if UnitName("partypet3") and IsSpellInRange(HealBot_dSpell, "partypet3")==1 then
            HealBot_IamHealing[UnitName("partypet3")]=UnitName("partypet3");
          end
          if UnitName("partypet4") and IsSpellInRange(HealBot_dSpell, "partypet4")==1 then
            HealBot_IamHealing[UnitName("partypet4")]=UnitName("partypet4");
          end
        elseif target then
          HealBot_IamHealing[target]=target
        end
		for j in pairs(HealBot_IamHealing) do
          HealBot_Comms_SendAddonMsg(HEALBOT_ADDON_ID, ">> "..HealBot_HealValue.." <<=>> "..HealBot_IamHealing[j], HealBot_AddonMsgType, HealBot_PlayerName)
        end
      end
      if HealBot_Spells[scsspell].Duration>0 and HealBot_Config.ShowHoTicons==1 and HealBot_Unit_Button[HealBot_UnitID[target]] then

        if HealBot_HoT1_Spell[target]==spellname then
          HealBot_HoT_Update(nil, HealBot_Spells[scsspell].Duration, target, spellname)
        elseif HealBot_HoT2_Spell[target]==spellname then
          HealBot_HoT_Update(nil, HealBot_Spells[scsspell].Duration, target, spellname)
        elseif HealBot_HoT3_Spell[target]==spellname then
          HealBot_HoT_Update(nil, HealBot_Spells[scsspell].Duration, target, spellname)
        else
          HealBot_HoT_Waiting[target]=HealBot_Spells[scsspell].CastTime+3;
          HealBot_HoT_WaitingSpell[target]=scsspell;
          HealBot_HoT_WaitingSpellName[target]=spellname;
          if spellname==HEALBOT_PRAYER_OF_MENDING then
            HealBot_HoT_Mending=5;
          end;
        end
      end
      HealBot_CastingSpell  = scsspell;
      HealBot_CastingTarget = tUnit;
      if HealBot_Config.CastNotify>1 and HealBot_Config.CastNotifyResOnly==0 then
        HealBot_CastNotify(scsspell,target)
      end
    end
    if HealBot_IsCasting then HealBot_RecalcHeals(); end
	  
    if tUnit=="target" and HealBot_Config.TargetHeals==1 then
	  if (UnitIsFriend("player","target")) then
        HealBot_TargetBuffCheck=true
	  end
	end
  end
end

local hVal=0
function HealBot_HealsInUpdate(target,healVal)
  hVal=tonumber(healVal)
  if not HealBot_HealsIn[target] then HealBot_HealsIn[target]=0 end
  HealBot_HealsIn[target] = HealBot_HealsIn[target] + hVal
  if HealBot_HealsIn[target]<0 then HealBot_HealsIn[target]=0 end
  if HealBot_Unit_Button[HealBot_UnitID[target]] then
    if HealBot_HealsIn[target]>0 then
	  HealBot_RecalcHeals(HealBot_UnitID[target])
	else
	  HealBot_HealsIn[target]=nil
      HealBot_Action_ResetUnitStatus(HealBot_UnitID[target])
	end
  end
end

function HealBot_CastNotify(spell,target)
  Notify = HealBot_Config.CastNotify;
  chanid=nil;
    if Notify==6 then
      chanid=HealBot_Comms_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(format(HEALBOT_CASTINGSPELLONYOU,spell),"WHISPER",nil,target);
    elseif Notify==4 then
      SendChatMessage(format(HEALBOT_CASTINGSPELLONUNIT,spell,target),"PARTY",nil,nil);
    elseif Notify==5 then
      SendChatMessage(format(HEALBOT_CASTINGSPELLONUNIT,spell,target),"RAID",nil,nil);
    elseif Notify==6 then
      SendChatMessage(format(HEALBOT_CASTINGSPELLONUNIT,spell,target),"CHANNEL",nil,chanid);
    else
      HealBot_AddChat(format(HEALBOT_CASTINGSPELLONUNIT,spell,target));
    end
end

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

local uscSpell=nil
local uscRank=nil
local uscTarget=nil
function HealBot_OnEvent_UnitSpellcastStart(this,caster)
--  if not HealBot_UnitName[caster] then return end
end

local uscsuName=nil
function HealBot_OnEvent_UnitSpellcastStop(this,unit)
  uscsuName=UnitName(unit)
  if uscsuName==HealBot_PlayerName then
    if HealBot_IsCasting then
      HealBot_IsCasting = false;
      HealBot_StopCasting();
      HealBot_RecalcHeals();
      if HealBot_IamRessing then
        HealBot_Comms_SendAddonMsg("CTRA", "RESNO", HealBot_AddonMsgType, HealBot_PlayerName)
        HealBot_IamRessing=nil;
      end
	end
  end
end

local huUnit=nil
function HealBot_HoT_Update(index, secLeft, memberName, spellName)
  huUnit=HealBot_UnitID[memberName]
  if index then
    if secLeft==0 then
      HealBot_HoT_UpdateIcon(HealBot_Unit_Button[huUnit], 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[huUnit], 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_HoT3_Spell[memberName]=nil;
            HealBot_HoT_ChangeIcon(HealBot_Unit_Button[huUnit], 2, HealBot_HoT_AlphaValue(HealBot_HoT2[memberName]), HealBot_HoT_iconTexture2[memberName])
            HealBot_HoT_UpdateIcon(HealBot_Unit_Button[huUnit], 3, 0)
          else
            HealBot_HoT_UpdateIcon(HealBot_Unit_Button[huUnit], 2, 0)
          end
        else
          HealBot_HoT1[memberName]=nil;
          HealBot_HoT1_Spell[memberName]=nil;
          HealBot_HoT_Active_Button[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[huUnit], 2, HealBot_HoT_AlphaValue(HealBot_HoT2[memberName]), HealBot_HoT_iconTexture2[memberName])
          HealBot_HoT_UpdateIcon(HealBot_Unit_Button[huUnit], 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[huUnit], index, HealBot_HoT_AlphaValue(secLeft))
    end
  else
    addIcon=true
    secLeft=secLeft+4;
    if HealBot_HoT1[memberName] and HealBot_HoT_iconTexture1[memberName]==HealBot_HoT_Texture[spellName] then
        HealBot_HoT1[memberName]=secLeft;
        addIcon=false;
        HealBot_HoT_UpdateIcon(HealBot_Unit_Button[huUnit], 1, 1)
    elseif HealBot_HoT2[memberName] and HealBot_HoT_iconTexture2[memberName]==HealBot_HoT_Texture[spellName] then
        HealBot_HoT2[memberName]=secLeft;
        addIcon=false;
        HealBot_HoT_UpdateIcon(HealBot_Unit_Button[huUnit], 2, 1)
    elseif HealBot_HoT3[memberName] and HealBot_HoT_iconTexture3[memberName]==HealBot_HoT_Texture[spellName] then
        HealBot_HoT3[memberName]=secLeft;
        addIcon=false;
        HealBot_HoT_UpdateIcon(HealBot_Unit_Button[huUnit], 3, 1)
    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[huUnit], 1, HealBot_HoT_AlphaValue(HealBot_HoT1[memberName]), HealBot_HoT_iconTexture1[memberName])
        HealBot_HoT_Active_Button[memberName]=HealBot_Unit_Button[huUnit];
      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[huUnit], 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[huUnit], 3, HealBot_HoT_AlphaValue(HealBot_HoT3[memberName]), HealBot_HoT_iconTexture3[memberName])
      end
    end
  end
end

function HealBot_HoT_MoveIcon(oldButton, newButton, memberName)
  if HealBot_HoT1[memberName] then
    HealBot_HoT_UpdateIcon(oldButton, 1, 0)
    HealBot_HoT_ChangeIcon(newButton, 1, HealBot_HoT_AlphaValue(HealBot_HoT1[memberName]), HealBot_HoT_iconTexture1[memberName])
  end
  if HealBot_HoT2[memberName] then
    HealBot_HoT_UpdateIcon(oldButton, 2, 0)
    HealBot_HoT_ChangeIcon(newButton, 2, HealBot_HoT_AlphaValue(HealBot_HoT2[memberName]), HealBot_HoT_iconTexture2[memberName])
  end
  if HealBot_HoT3[memberName] then
    HealBot_HoT_UpdateIcon(oldButton, 3, 0)
    HealBot_HoT_ChangeIcon(newButton, 3, HealBot_HoT_AlphaValue(HealBot_HoT3[memberName]), HealBot_HoT_iconTexture3[memberName])
  end
end

function HealBot_HoT_RemoveIcon(memberName)
  button=HealBot_HoT_Active_Button[memberName];
  if HealBot_HoT1[memberName] then
    HealBot_HoT_UpdateIcon(button, 1, 0)
  end
  if HealBot_HoT2[memberName] then
    HealBot_HoT_UpdateIcon(button, 2, 0)
  end
  if HealBot_HoT3[memberName] then
    HealBot_HoT_UpdateIcon(button, 3, 0)
  end
  HealBot_HoT_Active_Button[memberName]=nil;
end

function HealBot_HoT_ChangeIcon(name, index, a, Texture)
  if not name then return; end;
  bar = HealBot_Action_HealthBar(name);
  iconName = getglobal(bar:GetName().."Icon"..index);
  iconName:SetTexture(Texture);
  iconName:SetAlpha(a);
end

function HealBot_HoT_UpdateIcon(name, index, a)
  if not name then return; end;
  bar = HealBot_Action_HealthBar(name);
  iconName = getglobal(bar:GetName().."Icon"..index);
  iconName:SetAlpha(a);
end

function HealBot_HoT_AlphaValue(secLeft)
  if secLeft>0 and secLeft<15 then
    return secLeft/15
  else
    return 1
  end
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

local isRange=0
local isMana=1000
local isSpell="Heal"
function HealBot_InitSpells()
  
  for x,_ in pairs(HealBot_CurrentSpells) do
    HealBot_CurrentSpells[x]=nil;
  end
  
  HealBot_Init_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

  id = 1
  cnt = 0;  
  while true do
    spellname, spellrank = HealBot_GetSpellName(id);
    ispell=nil;
    if not spellname then
      do break end
    end
    if spellrank then
      ispell=spellname .. "(" .. spellrank .. ")";
    end
    if (HealBot_Spells[ispell]) then
      HealBot_Spells[ispell].id = id;
      HealBot_InitGetSpellData(ispell, id, HealBot_PlayerClassEN, spellname);
      table.insert(HealBot_CurrentSpells,ispell);
      if HealBot_Spells[ispell].HealsDur>0 and spellname~=HEALBOT_BINDING_HEAL 
                                          and spellname~=HEALBOT_POWER_WORD_SHIELD 
                                          and spellname~=HEALBOT_PRAYER_OF_MENDING then
        table.insert(HealBot_SmartCast_Spells,ispell);
		if HealBot_Spells[ispell].Range>isRange and HealBot_Spells[ispell].Mana<isMana then
		  isRange=HealBot_Spells[ispell].Range
		  isMana=HealBot_Spells[ispell].Mana
		  isSpell=ispell
		end
      end
      cnt = cnt + 1;
    end
    id = id + 1;
  end
  HealBot_Action_SetrSpell(isSpell)
  HealBot_AddDebug("Initiated HealBot_CurrentSpells with ".. cnt .." Spells");
  HealBot_Options_CheckCombos();
  HealBot_Init_SmartCast();
  return cnt;
end

function HealBot_InitData() 
  HealBot_Options_SetSkins();
--  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_HasInnerFocus()
	nameTalent,_,_,_,currRank,_ = 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
    xpos,ypos = GetCursorPosition() 
    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_SmartCast(unit,hdelta)
  retSpell=nil;
  score=0;
  lastscore=0;
  Process=false;
  target=(hdelta-200)*0.88
    table.foreach(HealBot_SmartCast_Spells, function (index,spell)
      if (HealBot_Spells[spell]) then
        if HealBot_Spells[spell].HealsDur<target then
          if HealBot_Spells[spell].Buff then
            if HealBot_HasBuff(HealBot_Spells[spell].Buff,unit) then 
              Process=false;  
            else
              Process=true;
            end;  
          else
            Process=true
          end
          if Process then
            score=(HealBot_Spells[spell].HealsDur/target)*800;
            score=score-(HealBot_Spells[spell].Mana/25);
            score=score/(HealBot_Spells[spell].CastTime+1);
            if score>lastscore then
              lastscore=score;
              retSpell=spell;
            end
          end
        end
      end
    end)
  return retSpell;
end
