--[[
Предполагается мультиклассовая игра Mage + Warlock + Priest + Druid + Shaman до
примерно L60 с множителем талантов x5, с прохождением подземелий, но не рейдов.
Затем, если будет слишком сложно, можно переключиться на множитель x10. Затем,
когда снова станет слишком сложно - разрешить остающиеся WotLK классы:
Warrior, Rogue, Hunter, Paladin, Death Knight.
]]

function AAL_GetTracking()
  for i = 1, GetNumTrackingTypes() do
    local name,texture,active,category = GetTrackingInfo(i)
    if active then return name end 
  end
  return nil
end

function AAL_FindResourceSwitcher()

  local list = {"Find Treasure", "Find Minerals", "Find Herbs",  "Track Humanoids","Track Beasts","Find Fish"}
  local tracker = AAL_GetTracking();
  if tracker == nil then
  elseif tracker == "Find Treasure" then list = {"Find Minerals", "Find Herbs",  "Track Humanoids","Track Beasts","Find Fish"}
  elseif tracker == "Find Minerals" then list = {"Find Herbs", "Find Treasure",  "Track Humanoids","Track Beasts","Find Fish"}
  end

  AAL_Cast(unpack(list))
end


function AAL_Fishing()
  local poles = {
"Arcanite Fishing Pole",
"Jeweled Fishing Pole",
"Bone Fishing Pole",
"Mastercraft Kalu'ak Fishing Pole",
"Nat's Lucky Fishing Pole",
"Nat Pagle's Extreme Angler FC-5000",
"Seth's Graphite Fishing Pole",
"Big Iron Fishing Pole",
"Darkwood Fishing Pole",
"Strong Fishing Pole",
"Blump Family Fishing Pole",
"Basic Fishing Pole",
"Fishing Pole",
  }
  for i=1,table.getn(poles) do
    if AAL_EquippedFishingPole() then break end

    -- local off = GetItemInfo(GetInventoryItemID(INVSLOT_OFFHAND))
    RunMacroText("/equip "..poles[i])
  end
  CastSpellByName("Fishing")
end




function AAL_MeleeAttack()
  if not UnitExists("target") then RunMacroText("/targetenemy [nodead]") end
  RunMacroText("/startattack")
end


function AAL_Shoot()
  StopAttack()
  AAL_Cast("Throw", "Shoot", "Auto Shot")
end


function AAL_SpellAttack()
  -- NB! Если у игрока нет ничего, кроме Fireball, то применение будет блокироваться пока на цели остаётся DoT debuff
  AAL_Cast("Frostbolt", "Fireball", "Shadowbolt", "Lightning Bolt", "Wrath", 0, "Smite")
end


function AAL_SpellInstant()

  local HP = UnitHealth("target")
  local family = UnitCreatureType("target")
  local useExorcism = (family == "Undead" or family == "Demon")

  -- ???[1.12] у Fire Blast и Exorcism общий CD; Exorcism эффективнее, но CD не 8s, а 15s
  if     HP <=  24 and AAL_Cast("Fire Blast(Rank 1)") then return
  elseif HP <=  57 and AAL_Cast("Fire Blast(Rank 2)") then return
  elseif useExorcism and HP <= 84 and AAL_Cast("Exorcism(Rank 1)") then return
  elseif HP <= 103 and AAL_Cast(".Fire Blast(Rank 3)") then return
  elseif useExorcism and HP <= 152 and AAL_Cast("Exorcism(Rank 2)") then return
  elseif HP <= 170 and AAL_Cast(".Fire Blast(Rank 4)") then return
  elseif useExorcism and HP <= 217 and AAL_Cast("Exorcism(Rank 3)") then return
  elseif HP <= 242 and AAL_Cast(".Fire Blast(Rank 5)") then return
  elseif useExorcism and HP <= 304 and AAL_Cast("Exorcism(Rank 4)") then return
  elseif HP <= 350 and AAL_Cast("Fire Blast(Rank 6)") then return
  end

  local LevDiff = UnitLevel("target")
  if LevDiff == nil or LevDiff < 0 then LevDiff = 10
  else LevDiff = LevDiff - UnitLevel("player")
  end

  local isFat
  local rank = UnitClassification("target")
  if LevDiff > -20 and (rank == "elite" or rank == "rareelite") or rank == "worldboss" then
     isFat = true
  else
     isFat = (LevDiff >= 5) or HP > 20000
  end

  local percentHP = UnitHealthMax("target")
  if percentHP > 0 then percentHP = HP*100 / percentHP end

  if isFat and percentHP > 15 or LevDiff >= 0 and percentHP > 65 or LevDiff >= -2 and percentHP > 75 then
     if AAL_Cast("Corruption", "Curse of Agony", "Shadow Word: Pain", "Devouring Plague") then return end
  end

  -- Далее идут способности, требующие ориентации игрока лицом к врагу
  AAL_Cast("Moonfire", "Frost Shock", "Earth Shock", "Flame Shock", "Fire Blast")
end


function AAL_HinderEnemy()
  if GetUnitSpeed("player") == 0 and AAL_Cast("War Stomp") then return end
  AAL_Cast("-Kick", "*Pummel", "*Shield Bash", ".Wind Shear", ".Counterspell", ".Earthbind Totem")
end

function AAL_DisableEnemy()
  local family = UnitCreatureType("target")
  if family ~= "Not specified" and family ~= "Undead" and family ~= "Demon" and family ~= "Elemental" and family ~= "Giant" then
     if AAL_Cast("Polymorph") then return end
  end
  if AAL_Cast("Entangling Roots") then return end
end


function AAL_ScareEnemy()
  local family = UnitCreatureType("target")
  if family == "Undead" and AAL_Cast(".Turn Undead") then return end
  if family == "Beast" and AAL_Cast(".Scare Beast") then return end
  AAL_Cast("Fear") -- работает и без маны
end


function AAL_PetAttackOrSummon()
  if not UnitExists("pet") then
     CastSpellByName("Call Pet")
     return
  end
  if not UnitCanAttack("player", "target") then
     if UnitIsDead("target") then ClearTarget() end -- иначе макрос /targetenemy [nodead] не срабатывает
     RunMacroText("/targetenemy [nodead]")
     return -- можно атаковать и сразу, но лучше видеть, на кого сработал выбор цели
  end
  if IsPetAttackActive() then
     if AAL_CheckPetAction("Prowl", "Vanish") and AAL_PetCast("Prowl") then return end
     return
  end
  PetAttack()
end

function AAL_PetReviveOrFeedOrTauntOrTame()
  if PetHasActionBar() then
     if UnitAffectingCombat("pet") then
        AAL_PetCast("Growl","Torment")
        -- if AAL_Cast(3, "-20 Feint", ".Disengage") or AAL_Cast(".Fade") then end
        -- У Feint, Disengage и Fade общий CD; по идее вблизи надо применять сперва Feint, но минимальное проверяемое расстояние 10, а Feint и Disengage действуют в пределах 5
     elseif UnitAffectingCombat("player") then PetAttack()
     else
        OpenAllBags(true)
        CastSpellByName("Feed Pet")
     end
  elseif UnitIsEnemy("player", "target") then CastSpellByName("Tame Beast")
  else CastSpellByName("Revive Pet")
  end
end


function AAL_Protection()
  AAL_Cast(true, "Power Word: Shield")
end


function AAL_Heal(tar, instant)
  -- Возвращает false если лечение не нужно, nil если не удалось, true если удалось
  local HP = UnitHealth(tar)
  local maxHP = UnitHealthMax(tar)
  if maxHP <= 0 then return false end
  local H = maxHP - HP
  local percentHP = HP*100 / maxHP

  if H <= 0 then return false end

  if instant then 
     if AAL_Cast(tar, "Rejuvenation", "Renew") then return end

     if tar ~= "player" then return end
     if percentHP > 40 or not UnitAffectingCombat(tar) then return end

     if AAL_Cast("Aquarius Belt", "Lifeblood") then return end
     if H > 1000 and AAL_Cast("Major Healthstone", "Superior Healing Potion", "Major Healing Potion", "Major Rejuvenation Potion") then return end
     if H > 600 and AAL_Cast("Greater Healthstone", "Combat Healing Potion", "Superior Healing Potion") then return end
     if H > 400 and AAL_Cast("Healthstone", "Greater Healing Potion", "Heavy Stone Statue") then return end
     if H > 200 and AAL_Cast("Lesser Healthstone", "Healing Potion", "Coarse Stone Statue") then return end
     if H > 140 and AAL_Cast("Minor Healthstone", "Discolored Healing Potion", "Lesser Healing Potion") then return end
     if H > 80  and AAL_Cast("Minor Healing Potion", "Rough Stone Statue") then return end

     return
  end

  -- Приоритет у быстрых заклинаний
  -- Не учитывается влияние талантов на скорости заклинаний и на прибавку к лечению
  if AAL_CastHealRank(tar, H - GetSpellBonusHealing(),
      -- 1.5 sec
      "Flash of Light", 93, 144, 211, 288, 390, 499, 658, 764, 879, -- 7% of Base Mana
      "Healing Wave", 44, -- 13%
      "Lesser Healing Wave", 186, 281, 381, 514, 705, 928, 1185, 1578, 1834, -- 15%
      "Lesser Heal", 56, -- 16%
      "Healing Touch", 51, -- 17%
      "Flash Heal", 237, 314, 393, 478, 616, 764, 958, 1059, 1279, 1832, 2193, -- 18%
      -- 2 sec
      "Healing Wave", 0, 78, -- 17%
      "Lesser Heal", 0, 85, -- 21%
      "Healing Touch", 0, 112, -- 22%
      -- 2.5 sec
      "Healing Wave", 0, 0, 155, -- 21%
      "Lesser Heal", 0, 157, -- 27%
      "Healing Touch", 0, 0, 243, -- 28%
      "Holy Light", 60, 116, 239, 455, 708, 998, 1349, 1777, 2266, 2486, 3138, 4677, 5444, -- 29%
      -- 3 sec
      "Healing Wave", 0, 0, 0, 316, 440, 622, 854, 1167, 1561, 1850, 1969, 2436, 2996, 3466, -- 25%
      "Heal", 341, 491, 642, 804, -- 32%
      "Greater Heal", 1013, 1289, 1609, 2006, 2194, 2410, 2784, 3945, 4590 -- 32%
      -- 3.5 sec
      -- "Healing Touch", 0, 0, 0, 445, 694, 894, 1120, 1427, 1796, 2230, 2677, 2790, 3197, 3805, 4428 -- 33%
  ) then return end

  if UnitAffectingCombat(tar) and AAL_Cast(tar, "Regrowth"--[[2 sec/29%]], "Lesser Healing Wave", "Flash Heal", "Flash of Light", "Holy Light", "Greater Heal", "Healing Wave", "Healing Touch", "Heal", "Lesser Heal") then return end
  AAL_Cast(tar, "Holy Light", "Greater Heal", "Healing Touch", "Healing Wave", "Flash Heal", "Lesser Healing Wave", "Flash of Light", "Heal", "Lesser Heal")
end 

                      
function AAL_SmartHeal(instant)
  local pet = UnitExists("pet") and not UnitIsDead("pet")
  local petTank
  if pet then
     --+ local _; _, _,_,_,_,_,_,petTank--[[autoCastEnabled]] = AAL_GetPetAction("Growl")
  end

  if not UnitCanAttack("player", "target") and (not petTank or not UnitAffectingCombat("player")) and AAL_Heal("target", instant) ~= false then return true end

  if (not petTank or instant) and AAL_Heal("player", instant) ~= false then return true end
  if pet then
     local result = AAL_Heal("pet", instant)
     if result ~= false then return result end
  end
  if (petTank and not instant) and AAL_Heal("player", instant) ~= false then return true end

  if not UnitAffectingCombat("player") then
     UIErrorsFrame:AddMessage("No need to Heal",1,0,0)
  end
  return false
end


function AAL_ReplenishMana()
  local manaPercent = UnitMana("player")*100 / UnitManaMax("player")

  if manaPercent >= 100 then
     UIErrorsFrame:AddMessage("No need to Replenish Power",1,0,0)
     return
  end
  local inCombat = UnitAffectingCombat("player")

  if inCombat and AAL_Cast(true, "Arcane Torrent") then return end

  if (not inCombat or UnitHealth("player") > 0.70 * UnitHealthMax("player")) and AAL_Cast("Life Tap") then return end
  if not inCombat then return end
  if manaPercent > 70 then
     UIErrorsFrame:AddMessage("Won't spend potions while Mana > 70%",1,0,0)
     return
  end

  if AAL_Cast("Combat Mana Potion", "Superior Mana Potion","Major Mana Potion","Major Rejuvenation Potion","Greater Mana Potion","Mana Potion","Lesser Mana Potion","Minor Mana Potion", "Life Tap") then return end
end


function AAL_BuffPet()
  local BuffSpells = {"Thorns", "Mark of the Wild", "Arcane Intellect", "Power Word: Fortitude"}
  local t = UnitCanCooperate("target","player") and not UnitIsUnit("player", "target") and not UnitIsEnemy("player", "target") and not UnitIsDead("target") and "target"
            or "pet"
  for i=1, #BuffSpells do
    if UnitBuff(t, BuffSpells[i]) == nil then
       if AAL_Cast(t, BuffSpells[i]) then break end
    end
  end
end


function AAL_AutoBuff()
  if GetMirrorTimerInfo(2) == "BREATH" and AAL_Cast(".Unending Breath") then return end
  if UnitAffectingCombat("player") then
     if AAL_SmartHeal(true) then return end
     if AAL_Cast(true, "Nature's Grasp") then return end
     return
  end
  if AAL_Cast(true, --[[".Dampen Magic",]] ".Mark of the Wild", ".Thorns", IsUsableSpell("Demon Armor") and ".Demon Armor" or ".Demon Skin", ".Arcane Intellect", IsUsableSpell("Ice Armor") and ".Ice Armor" or ".Frost Armor", ".Inner Fire", ".Power Word: Fortitude", "Lightning Shield") then return end
  local hasMainEnch,_,_,hasOffEnch = GetWeaponEnchantInfo()
  if (not hasMainEnch and AAL_MainHandHasWeapon() and not AAL_EquippedFishingPole()  or  not hasOffEnch and OffhandHasWeapon())  and AAL_Cast(".Flametongue Weapon", ".Flametongue Weapon", ".Rockbiter Weapon") then return end
end

