-- @release $Id: Priority.lua 230 2012-11-29 23:30:07Z flawless101 $

if not SlamAndAwe then return end

local L = LibStub("AceLocale-3.0"):GetLocale("SlamAndAwe")
local media = LibStub:GetLibrary("LibSharedMedia-3.0");
if not C then 
	SlamAndAwe:SetConstants()
end
local LBF = LibStub("LibButtonFacade", true)
local LBFgroup = nil
local _, _, _, clientVersion = GetBuildInfo()

--if LBF then
--	local LBFgroup = LBF:Group("SlamAndAwe")
--end
SlamAndAwe.PriorityFrame = CreateFrame("Button", "SAA_PriorityFrame", UIParent)
SlamAndAwe.PriorityFrame.cooldown = CreateFrame("Cooldown", "SAA_PriorityFrameCooldown", SlamAndAwe.PriorityFrame)

---------------------------
-- Local Variables
---------------------------

SlamAndAwe.priorityTable = {}
SlamAndAwe.priorityTable.name = {}
SlamAndAwe.priorityTable.icon = {}
SlamAndAwe.priorityTable.test = {}

--------------------------
--  Helper Functions
--------------------------
-- returns : true if spellname is available in less than priority.cooldown
--                 or if spellname is currently activated
--           , remaining cooldown, 0 if ready to be cast
function SlamAndAwe:SpellAvailable(spellname)
	if SlamAndAwe.db.char.priority.hideImmune and self:IsTargetImmune(spellname) then
		return false
	end
	local start, duration = GetSpellCooldown(spellname)
	if start then
		local timeleft = start + duration - GetTime()
		return timeleft <= SlamAndAwe.db.char.priority.cooldown, duration, timeleft
	end
	return false, 999
end

function SlamAndAwe:PrintPriorities()
  for index = 1, 20 do
    SlamAndAwe:Print(SlamAndAwe.db.char.priority.prOption[index])
  end
end

function SlamAndAwe:IsBoss()
  local mylevel = UnitLevel("player")
  local bosslevel = mylevel + 3
    if UnitLevel("target") >= bosslevel or UnitClassification("target") == "worldboss" then
      return true
    end
end

function SlamAndAwe:GCDAvailable()
	local startTime, gcdDuration = GetSpellCooldown(SlamAndAwe.constants["Execute"])
	local gcdTime = startTime + gcdDuration - GetTime()
	return gcdTime <= SlamAndAwe.db.char.priority.cooldown 
end

function SlamAndAwe:IsOffGCD()
	local startTime, gcdDuration = GetSpellCooldown(SlamAndAwe.constants["Execute"])
	local gcdTime = startTime + gcdDuration - GetTime()
	if gcdTime > 0 then
    return true
	else
    return false
	end
end

function SlamAndAwe:GetDebuffInfo(debuff)
	local index = 1
	while UnitDebuff("target", index) do
		local name, _, _, count, _, _, debuffExpires, unitCaster = UnitDebuff("target", index)
		local isMine = unitCaster == "player" 
		if name == debuff and isMine then 
			local duration = debuffExpires - GetTime()
			return duration > SlamAndAwe.db.char.priority.cooldown, duration, count, debuffExpires
		end
		index = index + 1
	end
	return false, 0, 0, 0
end

function SlamAndAwe:GetBuffInfo(buff)
	local index = 1
	while UnitBuff("player", index) do
		local name, _, _, count, _, _, buffExpires = UnitBuff("player", index)
		if name == buff then 
			local duration = buffExpires - GetTime()
			return duration > SlamAndAwe.db.char.priority.cooldown, duration, count
		end
		index = index + 1
	end
	return false, 0, 0
end

function SlamAndAwe:IsTargetImmune(spell)
	target = UnitName("target") or ""
	if spell and SlamAndAwe.db.char.immuneTargets[target.."_"..spell] then
		return true
	end
	return false
end

---------------------------
-- glyph related functions
---------------------------

function SlamAndAwe:GetGlyphInfo()
for i = 1, 6 do
 local enabled, glyphType, glyphTooltipIndex, glyphSpellID, icon = GetGlyphSocketInfo(i);
 if ( enabled ) then
  local link = GetGlyphLink(i);-- Retrieves the Glyph's link ("" if no glyph in Socket);
  if ( link ~= "") then
   DEFAULT_CHAT_FRAME:AddMessage("Glyph Socket "..i.." contains "..link.." or ID "..glyphSpellID);
  else
   DEFAULT_CHAT_FRAME:AddMessage("Glyph Socket "..i.." is unlocked and empty!");
  end
 else
  DEFAULT_CHAT_FRAME:AddMessage("Glyph Socket "..i.." is locked!");
 end
end
end

function SlamAndAwe:HasGlyph(thisglyphid)
  for i = 1, 6 do
  local enabled, glyphType, glyphTooltipIndex, glyphSpellID, icon = GetGlyphSocketInfo(i);
    if glyphSpellID == thisglyphid then
      return true
    end
  end
end

------------------
-- Misc Functions
------------------

function SlamAndAwe:EstimateShieldBarrier()
    local curRage = UnitPower("player", "rage")
    if curRage >= 20 then
      local _, STR, _, _ = UnitStat("player", 1)
      local _, STA, _, _ = UnitStat("player", 3)
      local APbase, APposBuff, APnegBuff = UnitAttackPower("player")
      local APfinal = APbase + APposBuff + APnegBuff
      local sbMaxRage = 60
    
      return floor(max((2*(APfinal - STR * 2)), ((2.5 * STA)*(min(curRage,60)/sbMaxRage))))
     else
      return 0
     end  
end

------------------
-- Priorities
------------------

function SlamAndAwe:SetPriorityTable()
		SlamAndAwe.priorityTable.name["none"] = L["None"]
	_, _, SlamAndAwe.priorityTable.icon["none"] = "Interface/Tooltips/UI-Tooltip-Background"
	SlamAndAwe.priorityTable.test["none"] = function () return false end
end

--SlamAndAwe

	SlamAndAwe.priorityTable.name["cs"] = SlamAndAwe.constants["Colossus Smash"]
	SlamAndAwe.priorityTable.icon["cs"] = SlamAndAwe.constants["Colossus Smash Icon"]
	SlamAndAwe.priorityTable.test["cs"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Colossus Smash"]);     
       if usable then
          return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Colossus Smash"])     
        end
      end   
      
  SlamAndAwe.priorityTable.name["cs_re"] = "Colossus Smash (if=debuff.colossus_smash.remains<=2)"
	SlamAndAwe.priorityTable.icon["cs_re"] = SlamAndAwe.constants["Colossus Smash Icon"]
	SlamAndAwe.priorityTable.test["cs_re"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Colossus Smash"]);     
       if usable then
          local CS, CSduration = SlamAndAwe:GetDebuffInfo(SlamAndAwe.constants["Colossus Smash"])
          if (not CS or CSduration <= 2) then
            return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Colossus Smash"]) 
          end    
        end
      end       
     
	SlamAndAwe.priorityTable.name["bt"] = SlamAndAwe.constants["Bloodthirst"]
	SlamAndAwe.priorityTable.icon["bt"] = SlamAndAwe.constants["Bloodthirst Icon"]
	SlamAndAwe.priorityTable.test["bt"] =  
			function () 	
        local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Bloodthirst"]); 
        if usable then      
          return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Bloodthirst"])
        end
      end
      
  SlamAndAwe.priorityTable.name["bt_r"] = "Bloodthirst (if=!(target.health.pct<20&debuff.colossus_smash.up&rage>=30))"
	SlamAndAwe.priorityTable.icon["bt_r"] = SlamAndAwe.constants["Bloodthirst Icon"]
	SlamAndAwe.priorityTable.test["bt_r"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Bloodthirst"]);       
        if usable then
        local rage = UnitPower("player", "rage")
        local SubTwenty = SlamAndAwe:SubTwenty()
        local CS = SlamAndAwe:GetDebuffInfo(SlamAndAwe.constants["Colossus Smash"])
          if not (rage > 30 and SubTwenty and CS) then
            return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Bloodthirst"])     
          end
        end
      end
		
	SlamAndAwe.priorityTable.name["rb"] = SlamAndAwe.constants["Raging Blow"]
	SlamAndAwe.priorityTable.icon["rb"] = SlamAndAwe.constants["Raging Blow Icon"]
	SlamAndAwe.priorityTable.test["rb"] =  
			function () 	
        local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Raging Blow"]);
        if (usable and not nomana) then
          return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Raging Blow"])     
        end
      end
      
	SlamAndAwe.priorityTable.name["sl"] = "Slam (if=health.pct>=20"
	SlamAndAwe.priorityTable.icon["sl"] = SlamAndAwe.constants["Slam Icon"]
	SlamAndAwe.priorityTable.test["sl"] =  
			function () 	
        local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Slam"]);
        SubTwenty = SlamAndAwe:SubTwenty()
        if usable and not SubTwenty then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Slam"])
        end
      end
      
  SlamAndAwe.priorityTable.name["sl_cs"] = "Slam (if=rage>=70|debuff.colossus_smash.up)&health.pct>=20)"
	SlamAndAwe.priorityTable.icon["sl_cs"] = SlamAndAwe.constants["Slam Icon"]
	SlamAndAwe.priorityTable.test["sl_cs"] =  
			function () 	
        local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Slam"]);
        if usable then
        			if not SlamAndAwe:SubTwenty() then
                local CS = SlamAndAwe:GetDebuffInfo(SlamAndAwe.constants["Colossus Smash"])
                local rage = UnitPower("player", "rage")
                if (rage >= 70 and CS) then
                  return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Slam"])
                end
              end
        end
      end
      
  SlamAndAwe.priorityTable.name["wis"] = SlamAndAwe.constants["Wild Strike"]
	SlamAndAwe.priorityTable.icon["wis"] = SlamAndAwe.constants["Wild Strike Icon"]
	SlamAndAwe.priorityTable.test["wis"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Wild Strike"]);
       if (usable and not nomana) then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Wild Strike"])
       end
      end      
          
	SlamAndAwe.priorityTable.name["wis_bs"] = "Wild Strike (if=buff.bloodsurge.react&health.pct>=20)"
	SlamAndAwe.priorityTable.icon["wis_bs"] = SlamAndAwe.constants["Wild Strike Icon"]
	SlamAndAwe.priorityTable.test["wis_bs"] =  
			function ()
			if not SlamAndAwe:SubTwenty() then
					local BS = SlamAndAwe:GetBuffInfo(SlamAndAwe.constants["Bloodsurge"])
          if BS == true then
            local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Wild Strike"]);
            if (usable and not nomana) then
              return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Wild Strike"])
            end
          end
        end
      end
      
  SlamAndAwe.priorityTable.name["wis_cs"] = "Wild Strike (if=buff.colossus_smash&health.pct>=20)"
	SlamAndAwe.priorityTable.icon["wis_cs"] = SlamAndAwe.constants["Wild Strike Icon"]
	SlamAndAwe.priorityTable.test["wis_cs"] =  
			function ()
			if not SlamAndAwe:SubTwenty() then
			local CS = SlamAndAwe:GetDebuffInfo(SlamAndAwe.constants["Colossus Smash"])
			if CS then
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Wild Strike"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Wild Strike"])
       end
      end
      end
      end
  
  SlamAndAwe.priorityTable.name["dw"] = SlamAndAwe.constants["Death Wish"]
	SlamAndAwe.priorityTable.icon["dw"] = SlamAndAwe.constants["Death Wish Icon"]
	SlamAndAwe.priorityTable.test["dw"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Death Wish"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Death Wish"])
       end
      end
      
  SlamAndAwe.priorityTable.name["re"] = SlamAndAwe.constants["Recklessness"]
	SlamAndAwe.priorityTable.icon["re"] = SlamAndAwe.constants["Recklessness Icon"]
	SlamAndAwe.priorityTable.test["re"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Recklessness"]);
       if usable and SlamAndAwe:IsOffGCD() then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Recklessness"])
       end
      end
      
  SlamAndAwe.priorityTable.name["re_boss"] = "Recklessness on Boss (if=boss&off.gcd)"
	SlamAndAwe.priorityTable.icon["re_boss"] = SlamAndAwe.constants["Recklessness Icon"]
	SlamAndAwe.priorityTable.test["re_boss"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Recklessness"]);
       if usable and SlamAndAwe:IsOffGCD() and SlamAndAwe:IsBoss() then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Recklessness"])
       end
      end          
      
  SlamAndAwe.priorityTable.name["br"] = "Berserker Rage (if=!buff.enrage&off.gcd)"
	SlamAndAwe.priorityTable.icon["br"] = SlamAndAwe.constants["Berserker Rage Icon"]
	SlamAndAwe.priorityTable.test["br"] =  
			function () 	
        local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Berserker Rage"]);
        if usable and SlamAndAwe:IsOffGCD() then
           --Check for enrage and no raging blow buff
           local Enraged = SlamAndAwe:GetBuffInfo(SlamAndAwe.constants["Enrage"])
           if not Enraged then
                  return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Berserker Rage"])
           end
        end
      end   
      
  SlamAndAwe.priorityTable.name["cosh"] = SlamAndAwe.constants["Commanding Shout"]
	SlamAndAwe.priorityTable.icon["cosh"] = SlamAndAwe.constants["Commanding Shout Icon"]
	SlamAndAwe.priorityTable.test["cosh"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Commanding Shout"]);
       if usable then
            return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Commanding Shout"])
       end
      end

  SlamAndAwe.priorityTable.name["bsh"] = SlamAndAwe.constants["Battle Shout"]
	SlamAndAwe.priorityTable.icon["bsh"] = SlamAndAwe.constants["Battle Shout Icon"]
	SlamAndAwe.priorityTable.test["bsh"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Battle Shout"]);
       if usable then
            return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Battle Shout"])
       end
      end
      
  SlamAndAwe.priorityTable.name["bsh_noCS"] = "Battle Shout (if=rage<70&!debuff.colossus_smash.up)"
	SlamAndAwe.priorityTable.icon["bsh_noCS"] = SlamAndAwe.constants["Battle Shout Icon"]
	SlamAndAwe.priorityTable.test["bsh_noCS"] =  
			function ()
			 local CS = SlamAndAwe:GetDebuffInfo(SlamAndAwe.constants["Colossus Smash"])
			 if not CS then
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Battle Shout"]);
       if usable then
           local rage = UnitPower("player", "rage")
           if rage < 70 then
            return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Battle Shout"])
           end
       end
       end
      end    

  SlamAndAwe.priorityTable.name["bsh_rage"] = "Battle Shout (if=rage<70)"
	SlamAndAwe.priorityTable.icon["bsh_rage"] = SlamAndAwe.constants["Battle Shout Icon"]
	SlamAndAwe.priorityTable.test["bsh_rage"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Battle Shout"]);
       if usable then
           local rage = UnitPower("player", "rage")
           if rage < 70 then
            return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Battle Shout"])
           end
       end
      end
      
  SlamAndAwe.priorityTable.name["ava"] = SlamAndAwe.constants["Avatar"]
	SlamAndAwe.priorityTable.icon["ava"] = SlamAndAwe.constants["Avatar Icon"]
	SlamAndAwe.priorityTable.test["ava"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Avatar"]);
       if usable and SlamAndAwe:IsOffGCD() then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Avatar"])
       end
      end
      
  SlamAndAwe.priorityTable.name["blb"] = SlamAndAwe.constants["Bloodbath"]
	SlamAndAwe.priorityTable.icon["blb"] = SlamAndAwe.constants["Bloodbath Icon"]
	SlamAndAwe.priorityTable.test["blb"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Bloodbath"]);
       if usable and SlamAndAwe:IsOffGCD() then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Bloodbath"])
       end
      end

  SlamAndAwe.priorityTable.name["hel"] = "Heroic Leap (if=debuff.colossus_smash.up&off.gcd)"
	SlamAndAwe.priorityTable.icon["hel"] = SlamAndAwe.constants["Heroic Leap Icon"]
	SlamAndAwe.priorityTable.test["hel"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Heroic Leap"]);
       local CS = SlamAndAwe:GetDebuffInfo(SlamAndAwe.constants["Colossus Smash"])
       if usable and CS and SlamAndAwe:IsOffGCD() then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Heroic Leap"])
       end
      end

  SlamAndAwe.priorityTable.name["stb"] = SlamAndAwe.constants["Storm Bolt"]
	SlamAndAwe.priorityTable.icon["stb"] = SlamAndAwe.constants["Storm Bolt Icon"]
	SlamAndAwe.priorityTable.test["stb"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Storm Bolt"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Storm Bolt"])
       end
      end     
      
   SlamAndAwe.priorityTable.name["drr"] = SlamAndAwe.constants["Dragon Roar"]
	SlamAndAwe.priorityTable.icon["drr"] = SlamAndAwe.constants["Dragon Roar Icon"]
	SlamAndAwe.priorityTable.test["drr"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Dragon Roar"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Dragon Roar"])
       end
      end               
      
  SlamAndAwe.priorityTable.name["bls"] = SlamAndAwe.constants["Bladestorm"]
	SlamAndAwe.priorityTable.icon["bls"] = SlamAndAwe.constants["Bladestorm Icon"]
	SlamAndAwe.priorityTable.test["bls"] =  
			function () 	
 --      local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Bladestorm"]);
 --      if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Bladestorm"])
 --      end
      end  
      
  SlamAndAwe.priorityTable.name["imv"] = "Impending Victory (if=health.pct>20)"
	SlamAndAwe.priorityTable.icon["imv"] = SlamAndAwe.constants["Impending Vicotry Icon"]
	SlamAndAwe.priorityTable.test["imv"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Impending Vicotry"]);
       if usable and not SlamAndAwe:SubTwenty() then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Impending Vicotry"])
       end
      end 
      
  SlamAndAwe.priorityTable.name["dec"] = "Deadly Calm (if=off.gcd&rage>40)"
	SlamAndAwe.priorityTable.icon["dec"] = SlamAndAwe.constants["Deadly Calm Icon"]
	SlamAndAwe.priorityTable.test["dec"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Deadly Calm"]);
       if usable and SlamAndAwe:IsOffGCD() then
             local rage = UnitPower("player", "rage")
             if rage > 40 then
              return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Deadly Calm"])
             end
       end
      end    
      
  SlamAndAwe.priorityTable.name["dec_boss"] = "Deadly Calm on Boss (if=off.gcd&rage>40)"
	SlamAndAwe.priorityTable.icon["dec_boss"] = SlamAndAwe.constants["Deadly Calm Icon"]
	SlamAndAwe.priorityTable.test["dec_boss"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Deadly Calm"]);
       if usable and SlamAndAwe:IsOffGCD() and SlamAndAwe:IsBoss() then
             local rage = UnitPower("player", "rage")
             if rage > 40 then
              return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Deadly Calm"]) and UnitClassification("target") == "worldboss"
              end
       end
      end          
      
  SlamAndAwe.priorityTable.name["shw"] = SlamAndAwe.constants["Shockwave"]
	SlamAndAwe.priorityTable.icon["shw"] = SlamAndAwe.constants["Shockwave Icon"]
	SlamAndAwe.priorityTable.test["shw"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Shockwave"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Shockwave"])
       end
      end       
      
  SlamAndAwe.priorityTable.name["ex"] = SlamAndAwe.constants["Execute"]
	SlamAndAwe.priorityTable.icon["ex"] = SlamAndAwe.constants["Execute Icon"]
	SlamAndAwe.priorityTable.test["ex"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Execute"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Execute"])
       end
      end       
      
  SlamAndAwe.priorityTable.name["het"] = SlamAndAwe.constants["Heroic Throw"]
	SlamAndAwe.priorityTable.icon["het"] = SlamAndAwe.constants["Heroic Throw Icon"]
	SlamAndAwe.priorityTable.test["het"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Heroic Throw"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Heroic Throw"])
       end
      end   
      
--Protection
    
  SlamAndAwe.priorityTable.name["shs"] = SlamAndAwe.constants["Shield Slam"]
	SlamAndAwe.priorityTable.icon["shs"] = SlamAndAwe.constants["Shield Slam Icon"]
	SlamAndAwe.priorityTable.test["shs"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Shield Slam"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Shield Slam"])
       end
      end      

  SlamAndAwe.priorityTable.name["shbl"] = SlamAndAwe.constants["Shield Block"]
	SlamAndAwe.priorityTable.icon["shbl"] = SlamAndAwe.constants["Shield Block Icon"]
	SlamAndAwe.priorityTable.test["shbl"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Shield Block"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Shield Block"])
       end
      end

  SlamAndAwe.priorityTable.name["shba"] = SlamAndAwe.constants["Shield Barrier"]
	SlamAndAwe.priorityTable.icon["shba"] = SlamAndAwe.constants["Shield Barrier Icon"]
	SlamAndAwe.priorityTable.test["shba"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Shield Barrier"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Shield Barrier"])
       end
      end      

  SlamAndAwe.priorityTable.name["deva"] = SlamAndAwe.constants["Devastate"]
	SlamAndAwe.priorityTable.icon["deva"] = SlamAndAwe.constants["Devastate Icon"]
	SlamAndAwe.priorityTable.test["deva"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Devastate"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Devastate"])
       end
      end 
     
  SlamAndAwe.priorityTable.name["reve"] = SlamAndAwe.constants["Revenge"]
	SlamAndAwe.priorityTable.icon["reve"] = SlamAndAwe.constants["Revenge Icon"]
	SlamAndAwe.priorityTable.test["reve"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Revenge"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Revenge"])
       end
      end        
      
  SlamAndAwe.priorityTable.name["thcl"] = SlamAndAwe.constants["Thunder Clap"]
	SlamAndAwe.priorityTable.icon["thcl"] = SlamAndAwe.constants["Thunder Clap Icon"]
	SlamAndAwe.priorityTable.test["thcl"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Thunder Clap"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Thunder Clap"])
       end
      end       
      

  SlamAndAwe.priorityTable.name["thcl_wb"] = "Thunder Clap (if=!debuff.weakened_blows or duration <= 2)"
	SlamAndAwe.priorityTable.icon["thcl_wb"] = SlamAndAwe.constants["Thunder Clap Icon"]
	SlamAndAwe.priorityTable.test["thcl_wb"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Thunder Clap"]);
       if usable then
           local wbPresent, wbDuration = SlamAndAwe:GetDebuffInfo(SlamAndAwe.constants["Weakened Blows"])
           return (not wbPresent or wbDuration <= 2) and SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Thunder Clap"])
       end
      end       
  
  SlamAndAwe.priorityTable.name["hams"] = "Hamstring (if=!debuff.hamstring or duration <= 2)"
	SlamAndAwe.priorityTable.icon["hams"] = SlamAndAwe.constants["Hamstring Icon"]
	SlamAndAwe.priorityTable.test["hams"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Hamstring"]);
       if usable then
           local hamsPresent, hamsDuration = SlamAndAwe:GetDebuffInfo(SlamAndAwe.constants["Hamstring"])
           return (not hamsPresent or hamsDuration <= 2) and SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Hamstring"])
       end
      end 
      
  SlamAndAwe.priorityTable.name["whwi"] = SlamAndAwe.constants["Whirlwind"]
	SlamAndAwe.priorityTable.icon["whwi"] = SlamAndAwe.constants["Whirlwind Icon"]
	SlamAndAwe.priorityTable.test["whwi"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Whirlwind"]);
       if (usable and not nomana) then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Whirlwind"])
       end
      end       
      

  SlamAndAwe.priorityTable.name["whwi_rw"] = "Whirlwind (if=buff.raging_wind)"
	SlamAndAwe.priorityTable.icon["whwi_rw"] = SlamAndAwe.constants["Whirlwind Icon"]
	SlamAndAwe.priorityTable.test["whwi_rw"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Whirlwind"]);
       if (usable and not nomana) then
           local rwPresent = SlamAndAwe:GetBuffInfo(SlamAndAwe.constants["Raging Wind"])
           return rwPresent and SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Whirlwind"])
       end
      end       
          
  SlamAndAwe.priorityTable.name["desh"] = SlamAndAwe.constants["Demoralizing Shout"]
	SlamAndAwe.priorityTable.icon["desh"] = SlamAndAwe.constants["Demoralizing Shout Icon"]
	SlamAndAwe.priorityTable.test["desh"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Demoralizing Shout"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Demoralizing Shout"])
       end
      end  
      
  SlamAndAwe.priorityTable.name["most"] = SlamAndAwe.constants["Mortal Strike"]
	SlamAndAwe.priorityTable.icon["most"] = SlamAndAwe.constants["Mortal Strike Icon"]
	SlamAndAwe.priorityTable.test["most"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Mortal Strike"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Mortal Strike"])
       end
      end    
      
  SlamAndAwe.priorityTable.name["ovpo"] = SlamAndAwe.constants["Overpower"]
	SlamAndAwe.priorityTable.icon["ovpo"] = SlamAndAwe.constants["Overpower Icon"]
	SlamAndAwe.priorityTable.test["ovpo"] =  
			function () 	
       local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Overpower"]);
       if usable then
           return SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Overpower"])
       end
      end    
                                         
-------------------------------
-- Priority Frame functions
-------------------------------

function SlamAndAwe:SetPriorityBackdrop(icon)

	if SlamAndAwe.db.char.enableDisableBorder then 
		
	self.PriorityFrame:SetBackdrop({ bgFile = icon
	})
	else
	--self.PriorityFrame.Icon:SetTexture(icon)
	self.PriorityFrame:SetBackdrop({ bgFile = icon,
		edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
		tile = false, tileSize = 0, edgeSize = 12,
		insets = { left = 2, right = 2, top = 2, bottom = 2 }
	})
	end
end

function SlamAndAwe:CreatePriorityFrame()
	self.updatePriority = false
	self.PriorityFrame:SetScale(SlamAndAwe.db.char.priority.scale)
	self.PriorityFrame:SetFrameStrata(SlamAndAwe.db.char.framestratalevel)
	self.PriorityFrame:SetWidth(SlamAndAwe.db.char.priority.fWidth)
	self.PriorityFrame:SetHeight(SlamAndAwe.db.char.priority.fHeight)
	self.PriorityFrame.Icon = _G["SAA_PriorityFrameIcon"]
	self:SetPriorityBackdrop("Interface/Tooltips/UI-Tooltip-Background")
	self.PriorityFrame:SetBackdropColor(0, 0, 0, SlamAndAwe.db.char.priority.alpha);
	self.PriorityFrame:SetMovable(true);
	self.PriorityFrame:RegisterForDrag("LeftButton");
	self.PriorityFrame:EnableMouse(false)
	self.PriorityFrame:SetPoint(SlamAndAwe.db.char.priority.point, SlamAndAwe.db.char.priority.relativeTo, SlamAndAwe.db.char.priority.relativePoint, SlamAndAwe.db.char.priority.xOffset, SlamAndAwe.db.char.priority.yOffset)
	self.PriorityFrame:SetScript("OnDragStart", 
		function()
			self.PriorityFrame:StartMoving();
		end );
	self.PriorityFrame:SetScript("OnDragStop",
		function()
			self.PriorityFrame:StopMovingOrSizing();
			self.PriorityFrame:SetScript("OnUpdate", nil);
			self:FinishedMoving(SlamAndAwe.db.char.priority, self.PriorityFrame);
		end );
	self:SetPriorityUpdateScript()
	if not self.PriorityFrame.topText then
		self.PriorityFrame.topText = self.PriorityFrame:CreateFontString(nil, "OVERLAY")
	end
	self.PriorityFrame.topText:SetTextColor(1,1,1,1)
	self.PriorityFrame.topText:SetFont(media:Fetch("font", SlamAndAwe.db.char.barfont), SlamAndAwe.db.char.barfontsize)
	self.PriorityFrame.topText:SetPoint("TOP", self.PriorityFrame, "TOP", 0, SlamAndAwe.db.char.barfontsize + 2)
	self.PriorityFrame.topText:SetText(string.format(L["Next Priority (Set %s)"], SlamAndAwe.db.char.priority.groupnumber))
	self.PriorityFrame.cooldown:SetAllPoints(self.PriorityFrame)
	self:CreateInterruptPurgeFrames()
	
	if SlamAndAwe.db.char.priority.show and InCombatLockdown() then
		self.PriorityFrame:Show()
	else
		self.PriorityFrame:Hide()
	end
	if SlamAndAwe.db.char.priority.titleshow then
		self.PriorityFrame.topText:Show()
	else
		self.PriorityFrame.topText:Hide()
	end
	if LBF and LBFgroup then
		LBFgroup:AddButton(self.PriorityFrame)
	end
end

function SlamAndAwe:ResetPriority()
	self.PriorityFrame:ClearAllPoints()
	SlamAndAwe.db.char.priority.point = self.defaults.char.priority.point
	SlamAndAwe.db.char.priority.relativeTo = self.defaults.char.priority.relativeTo 
	SlamAndAwe.db.char.priority.relativePoint = self.defaults.char.priority.relativePoint
	SlamAndAwe.db.char.priority.xOffset = self.defaults.char.priority.xOffset
	SlamAndAwe.db.char.priority.yOffset = self.defaults.char.priority.yOffset
	SlamAndAwe.db.char.priority.fWidth = self.defaults.char.priority.fWidth
	SlamAndAwe.db.char.priority.fHeight = self.defaults.char.priority.fHeight
	SlamAndAwe.db.char.priority.scale = self.defaults.char.priority.scale
	SlamAndAwe.db.char.priority.prOption = self.defaults.char.priority.prOption
	self.PriorityFrame:SetPoint(SlamAndAwe.db.char.priority.point, SlamAndAwe.db.char.priority.relativeTo, SlamAndAwe.db.char.priority.relativePoint, SlamAndAwe.db.char.priority.xOffset, SlamAndAwe.db.char.priority.yOffset)
	self:CreatePriorityFrame()
	self:Print(L["priority_reset"])
end

function SlamAndAwe:SetPriorityUpdateScript()
	self.PriorityFrame:SetScript("OnUpdate", 
		function()
			if self.updatePriority then
				SlamAndAwe.db.char.priority.previous = SlamAndAwe.db.char.priority.next
				SlamAndAwe:SetNextPriority()
--				if SlamAndAwe.db.char.priority.next ~= SlamAndAwe.db.char.priority.previous or SlamAndAwe:CheckShamanisticRage() then
				SlamAndAwe:SetPriorityIcon(SlamAndAwe.db.char.priority.next) -- always set icon to fix the times where it was getting stuck
--				end
				if SlamAndAwe.db.char.priority.showcooldown then
					local startTime, duration = GetSpellCooldown(SlamAndAwe.constants["Execute"])
					if startTime then
						SlamAndAwe.PriorityFrame.cooldown:SetCooldown(startTime, duration)
					end
				end
			end
		end );
end

function SlamAndAwe:SetPriorityIcon(priority)
	--self:DebugPrint("setting icon to "..priority)
	if InCombatLockdown() or priority == "none" then
		local icon = self.priorityTable.icon[priority]
		if self:CheckWindShear() then
          self:SetSubFrameBackdrop(self.PriorityFrame.purge.frame, SlamAndAwe.constants["Heroic Strike Icon"], 4)
          else
    		self:SetSubFrameBackdrop(self.PriorityFrame.purge.frame, "Interface/Tooltips/UI-Tooltip-Background", 4)
				self.PriorityFrame.purge.frame:SetBackdropColor(0, 0, 0, 0);
		end
		self:SetPriorityBackdrop(icon)
	end
end

function SlamAndAwe:CheckWindShear()
	if SlamAndAwe.db.char.hsshow then
	   local UL = SlamAndAwe:GetBuffInfo(SlamAndAwe.constants["Ultimatum"])   
	   if UL then
      return true
     else    
     local avail = SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Heroic Strike"])
     local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Heroic Strike"])
     if usable and avail then
        local SubTwenty = SlamAndAwe:SubTwenty()
        local CS, CSduration = SlamAndAwe:GetDebuffInfo(SlamAndAwe.constants["Colossus Smash"])
        local TFB, TFBduration, TFBcount = SlamAndAwe:GetBuffInfo(SlamAndAwe.constants["Taste for Blood"])
        local DC = SlamAndAwe:GetBuffInfo(SlamAndAwe.constants["Deadly Calm"])   		
        local rage = UnitPower("player", "rage")
                  
        if rage >= SlamAndAwe.db.char.rageThreshold then
            return true
        elseif SlamAndAwe.db.char.currentspec == "Fury" then     
          --Fury
          if not SubTwenty then
            -- Target below 20% health
            if CS then
              if rage >= 40 then
                return true
              end
            elseif (DC and CS) then
              if rage >= 30 then
                return true
              end
            end
          end
          --End Fury
        elseif SlamAndAwe.db.char.currentspec == "Arms" then
          --Arms
          if not SubTwenty then
            if ((TFB and TFBduration <=2) or (TFBcount == 5) or (TFB and CSduration <= 2) or DC) and CS then
              return true
            end
          end
        end     
      end
    end
  end
end

function SlamAndAwe:SetNextPriority()
	-- force update of stacks count to ensure priority shown correctly
--	SlamAndAwe.db.char.msstacks = SlamAndAwe:GetMaelstromInfo()
--	if SlamAndAwe.db.char.priority.combopoints then
--		self:ShowComboPoints()
--	end
	SlamAndAwe.db.char.priority.next = "none"
	for index = 1, 20 do
		if SlamAndAwe.db.char.priority.prOption[index] and self.priorityTable.test[SlamAndAwe.db.char.priority.prOption[index]] then  -- verify that the option actually exists
			if self.priorityTable.test[SlamAndAwe.db.char.priority.prOption[index]]() then
				SlamAndAwe.db.char.priority.next = SlamAndAwe.db.char.priority.prOption[index]
				return -- we need to break out of the routine as we have found the top priority
			end
		end
	end
end

function SlamAndAwe:SubTwenty()
	local currenthp = UnitHealth("target")
	local totalhp = UnitHealthMax("target")
  if currenthp == 0 then
    dechp = 0
    perchp = 0
  elseif currenthp == totalhp then 
    perchp = 100
  else
    local calchp = currenthp / totalhp
    local dechp = calchp * 100
    perchp = math.ceil(dechp)
  end  
 
  if perchp <= 20 then
    return true
  else
    return false
  end
end

function SlamAndAwe:CreateInterruptPurgeFrames()
--	if not self.PriorityFrame.interrupt then
--		self.PriorityFrame.interrupt = {}
--		self.PriorityFrame.interrupt.frame = CreateFrame("Frame", "SAA_PriorityInterruptFrame", self.PriorityFrame)
--	end
--	local interruptFrame = self.PriorityFrame.interrupt.frame
--	interruptFrame:SetScale(SlamAndAwe.db.char.priority.scale)
--	interruptFrame:SetFrameStrata("BACKGROUND")
--	interruptFrame:SetWidth(width)
--	interruptFrame:SetHeight(height)
--	self:SetSubFrameBackdrop(interruptFrame, "Interface/Tooltips/UI-Tooltip-Background", 4)	
--	interruptFrame:SetBackdropColor(0, 0, 0, 0);
--	interruptFrame:SetPoint("BOTTOMLEFT",  self.PriorityFrame, "BOTTOMRIGHT", 0 , 0)
--	if SlamAndAwe.db.char.priority.showinterrupt then
--		interruptFrame:Show()
--	else
--		interruptFrame:Hide()
--	end
	local width = SlamAndAwe.db.char.priority.fWidth / 1.6
	local height = SlamAndAwe.db.char.priority.fHeight / 1.6
	
	if not self.PriorityFrame.purge then
		self.PriorityFrame.purge = {}
		self.PriorityFrame.purge.frame = CreateFrame("Frame", "SAA_PrioritypurgeFrame", self.PriorityFrame)
	end

	local purgeFrame = self.PriorityFrame.purge.frame
	purgeFrame:SetScale(SlamAndAwe.db.char.priority.scale)
	purgeFrame:SetFrameStrata("BACKGROUND")
	purgeFrame:SetWidth(width)
	purgeFrame:SetHeight(height)
	self:SetSubFrameBackdrop(purgeFrame, "Interface/Tooltips/UI-Tooltip-Background", 4)	
	purgeFrame:SetBackdropColor(0, 0, 0, 0);
	purgeFrame:SetPoint("BOTTOMLEFT",  self.PriorityFrame, "BOTTOMRIGHT", 0 , 0)	
	if SlamAndAwe.db.char.priority.showpurge then
		purgeFrame:Show()
	else
		purgeFrame:Hide()
	end
end

function SlamAndAwe:SetSubFrameBackdrop(subFrame, icon, edgeSize)
	subFrame:SetBackdrop({ bgFile = icon
	})	
end