-- @release $Id: SlamAndAwe.lua 245 2012-12-07 14:12:15Z reighnman $

if select(2, UnitClass('player')) ~= "WARRIOR" then
	DisableAddOn("SlamAndAwe")
	return
end

local L = LibStub("AceLocale-3.0"):GetLocale("SlamAndAwe")
local AceAddon = LibStub("AceAddon-3.0")
local media = LibStub:GetLibrary("LibSharedMedia-3.0")
SlamAndAwe = AceAddon:NewAddon("SlamAndAwe", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0")
local SCT = SCT
local REVISION = tonumber(("$Revision: 245 $"):match("%d+"))
local _, _, _, clientVersion = GetBuildInfo()
local queryDisable = false

SlamAndAwe.frames = {}

SlamAndAwe.BaseFrame = CreateFrame("Frame","SlamAndAweBase",UIParent)
SlamAndAwe.frames["TasteForBlood"] = CreateFrame("Frame","SAA_Bar1_Status", SlamAndAwe.BaseFrame) 
SlamAndAwe.frames["TasteForBlood"].icon = CreateFrame("Frame","SAA_Bar1_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["ShieldBarrier"] = CreateFrame("Frame","SAA_Bar2_Status",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["ShieldBarrier"].icon = CreateFrame("Frame","SAA_Bar2_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["ShieldBlock"] = CreateFrame("Frame","SAA_Bar3_Status",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["ShieldBlock"].icon = CreateFrame("Frame","SAA_Bar3_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["ShieldWall"] = CreateFrame("Frame","SAA_Bar4_Status",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["ShieldWall"].icon = CreateFrame("Frame","SAA_Bar4_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["ColossusSmash"] = CreateFrame("Frame","SAA_Bar5_Status",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["ColossusSmash"].icon = CreateFrame("Frame","SAA_Bar5_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["Recklessness"] = CreateFrame("Frame","SAA_Bar6_Status",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["Recklessness"].icon = CreateFrame("Frame","SAA_Bar6_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["DeadlyCalm"] = CreateFrame("Frame","SAA_Bar7_Status",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["DeadlyCalm"].icon = CreateFrame("Frame","SAA_Bar7_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["SweepingStrikes"] = CreateFrame("Frame","SAA_Bar8_Status",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["SweepingStrikes"].icon = CreateFrame("Frame","SAA_Bar8_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["Rage"] = CreateFrame("Frame","SAA_Bar9_Status",UIParent)
SlamAndAwe.frames["GCD"] = CreateFrame("Frame", "SAA_Bar10_Status", SlamAndAwe.BaseFrame)
SlamAndAwe.frames["DemoShout"] = CreateFrame("Frame","SAA_Bar11_Status",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["DemoShout"].icon = CreateFrame("Frame","SAA_Bar11_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["LastStand"] = CreateFrame("Frame","SAA_Bar12_Status",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["LastStand"].icon = CreateFrame("Frame","SAA_Bar12_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["RallyingCry"] = CreateFrame("Frame","SAA_Bar13_Status",SlamAndAwe.BaseFrame)
SlamAndAwe.frames["RallyingCry"].icon = CreateFrame("Frame","SAA_Bar13_StatusIcon",SlamAndAwe.BaseFrame)
SlamAndAwe.msgFrame = CreateFrame("MessageFrame","SlamAndAweMsg",UIParent)
SlamAndAwe.questionFrame = CreateFrame("Frame","SlamAndAweQuestion",UIParent)

SlamAndAwe.textures = {}
SlamAndAwe.borders = {}
SlamAndAwe.fonts = {}
SlamAndAwe.sounds = {}



SlamAndAwe.GCDMin = 0
SlamAndAwe.GCDMax = 0
SlamAndAwe.GCDWidth = 0
	
local shearMin, ShearMax, GCDPercent
local updateActiveRage = false
local updateActiveGCD = true
local GCDTime = 0

--SlamAndAwe
local CSMin, CSMax, DWMin, DWMax, REMin, REMax, RageMin, RageMax, SBMin, SBMax, SBlMin, SBlMax, SBlPos, SWMin, SWMax, DCMin, DCMax, tfbMin, tfbMax, SWSTMin, SWSTMax,
 DemoShoutMin, DemoShoutMax, LastStandMin, LastStandMax, RallyingCryMin, RallyingCryMax
local updateActiveColossusSmash = false
local CSTime = 0
local updateActiveShieldBarrier = false
local SBTime = 0
local SBLast = 0
local SBMin = 0
local SBMax = 10
local SBActive = false
local updateActiveRecklessness = false
local RETime = 0
local updateActiveDeadlyCalm = false
local DCTime = 0
local updateActiveShieldBlock = false
local SBlTime = 0
local SBlMax = 6
local updateActiveSweepingStrikes = false
local SWSTTime = 0
local updateActiveDemoShout = false
local DemoShoutTime = 0
local updateActiveLastStand = false
local LastStandTime = 0
local UpdateActiveRallyingCry = false
local RallyingCryTime = 0
local updateActiveShieldWall = false
local SWTime = 0
local updateActiveTasteForBlood = false
local lastSound = 0
local tfbTime = 0
local ffbflashing = false
local tfb4played = false
local updateActiveBanner = false
local last_banner_msg = nil
local last_banner_where = nil
local BannerTime = nil

-----------------------------------------
-- Initialisation & Startup Routines
-----------------------------------------

function SlamAndAwe:OnInitialize()
	local AceConfigReg = LibStub("AceConfigRegistry-3.0")
	local AceConfigDialog = LibStub("AceConfigDialog-3.0")
	local currentSpec = GetSpecialization()
	self:SetConstants()
	self:SetBindings()
	self:SetDefaultOptions()
	
	SlamAndAwe.db = LibStub("AceDB-3.0"):New("SlamAndAweDBPC", SlamAndAwe.defaults, "char")
	self:SetPriorityTable()
	self:GetMSBTAreaDefaults()
	LibStub("AceConfig-3.0"):RegisterOptionsTable("SlamAndAwe", self:GetOptions(), {"slamandawe", "saa"} )
	media.RegisterCallback(self, "LibSharedMedia_Registered")
	
	-- Add the options to blizzard frame (add them backwards so they show up in the proper order
	self.optionsFrame = AceConfigDialog:AddToBlizOptions("SlamAndAwe", "SlamAndAwe")
	SlamAndAwe.db:RegisterDefaults(SlamAndAwe.defaults)
	if not SlamAndAwe.db.char.immuneTargets then
		SlamAndAwe.db.char.immuneTargets = {}
	end
	self:InitialiseUptime()
	self:InitialiseBindings()
	self:CreateUptimeFrame()
	self:CreatePriorityFrame()
	self:CreateMsgFrame()
	self:News()
	self:VerifyOptions()
	
	if SlamAndAwe.db.char.enableDisableBorder then 
		SlamAndAwe.barBackdrop = {
				bgFile = "Interface/Tooltips/UI-Tooltip-Background",

			}
		SlamAndAwe.frameBackdrop ={
				bgFile = "Interface/Tooltips/UI-Tooltip-Background",
			}
	else 
	SlamAndAwe.barBackdrop = {
			bgFile = "Interface/Tooltips/UI-Tooltip-Background",
			edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
			tile = false, tileSize = 0, edgeSize = 12,
			insets = { left = 2, right = 2, top = 2, bottom = 2 }
		}
	SlamAndAwe.frameBackdrop ={
			bgFile = "Interface/Tooltips/UI-Tooltip-Background",
			--edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
			tile = false, tileSize = 0, edgeSize = 12,
			insets = { left = 0, right = 0, top = 0, bottom = 0 }
		}
		end


	if  not SlamAndAwe.db.char.enableProtSpec  and  not SlamAndAwe.db.char.disabled and currentSpec == 3 then
		SlamAndAwe:Disable()
	elseif not SlamAndAwe.db.char.enableFurySpec  and  not SlamAndAwe.db.char.disabled and currentSpec == 2 then
		SlamAndAwe:Disable()
	elseif not SlamAndAwe.db.char.enableArmsSpec  and  not SlamAndAwe.db.char.disabled and currentSpec == 1 then
		SlamAndAwe:Disable()
	end
		
	local version = GetAddOnMetadata("SlamAndAwe","Version")
	
	
	self.version = ("SlamAndAwe v%s (r%s)"):format(version, REVISION)
	self:Print(self.version.." Loaded.")
	
end

function SlamAndAwe:SetConstants()
	SlamAndAwe.constants = {}
	local C = SlamAndAwe.constants

	SlamAndAwe.constants["Pummel"], _, SlamAndAwe.constants["Pummel Icon"] = GetSpellInfo(6552)
	SlamAndAwe.constants["Shattering Throw"], _, SlamAndAwe.constants["Shattering Throw Icon"] = GetSpellInfo(64382)
	SlamAndAwe.constants["Berserker Rage"], _, SlamAndAwe.constants["Berserker Rage Icon"] = GetSpellInfo(18499)

	--Fury			
	SlamAndAwe.constants["Bloodthirst"], _, SlamAndAwe.constants["Bloodthirst Icon"] = GetSpellInfo(23881)
	SlamAndAwe.constants["Raging Blow"], _, SlamAndAwe.constants["Raging Blow Icon"] = GetSpellInfo(85288)
	SlamAndAwe.constants["Wild Strike"], _, SlamAndAwe.constants["Wild Strike Icon"] = GetSpellInfo(100130)

	--Arms
	SlamAndAwe.constants["Slam"], _, SlamAndAwe.constants["Slam Icon"] = GetSpellInfo(1464)
	SlamAndAwe.constants["Overpower"], _, SlamAndAwe.constants["Overpower Icon"] = GetSpellInfo(7384)
	SlamAndAwe.constants["Mortal Strike"], _, SlamAndAwe.constants["Mortal Strike Icon"] = GetSpellInfo(12294)
	SlamAndAwe.constants["Sweeping Strikes"], _, SlamAndAwe.constants["Sweeping Strikes Icon"] = GetSpellInfo(12328)

	--Both
	SlamAndAwe.constants["Hamstring"], _, SlamAndAwe.constants["Hamstring Icon"] = GetSpellInfo(1715)
	SlamAndAwe.constants["Execute"], _, SlamAndAwe.constants["Execute Icon"] = GetSpellInfo(5308)
	SlamAndAwe.constants["Battle Shout"], _, SlamAndAwe.constants["Battle Shout Icon"] = GetSpellInfo(6673)
	SlamAndAwe.constants["Recklessness"], _, SlamAndAwe.constants["Recklessness Icon"] = GetSpellInfo(1719)
	SlamAndAwe.constants["Bloodbath"], _, SlamAndAwe.constants["Bloodbath Icon"] = GetSpellInfo(12292)
	SlamAndAwe.constants["Avatar"], _, SlamAndAwe.constants["Avatar Icon"] = GetSpellInfo(107574)
	SlamAndAwe.constants["Storm Bolt"], _, SlamAndAwe.constants["Storm Bolt Icon"] = GetSpellInfo(107570)
	SlamAndAwe.constants["Shockwave"], _, SlamAndAwe.constants["Shockwave Icon"] = GetSpellInfo(46968)
	SlamAndAwe.constants["Bladestorm"], _, SlamAndAwe.constants["Bladestorm Icon"] = GetSpellInfo(46924)
	SlamAndAwe.constants["Impending Vicotry"], _, SlamAndAwe.constants["Impending Vicotry Icon"] = GetSpellInfo(103840)
	SlamAndAwe.constants["Colossus Smash"], _, SlamAndAwe.constants["Colossus Smash Icon"] = GetSpellInfo(86346)
	SlamAndAwe.constants["Dragon Roar"], _, SlamAndAwe.constants["Dragon Roar Icon"] = GetSpellInfo(118000)
	SlamAndAwe.constants["Heroic Throw"], _, SlamAndAwe.constants["Heroic Throw Icon"] = GetSpellInfo(57755)	
	SlamAndAwe.constants["Whirlwind"], _, SlamAndAwe.constants["Whirlwind Icon"] = GetSpellInfo(1680)
	SlamAndAwe.constants["Heroic Leap"], _, SlamAndAwe.constants["Heroic Leap Icon"] = GetSpellInfo(6544)
	SlamAndAwe.constants["Heroic Strike"], _, SlamAndAwe.constants["Heroic Strike Icon"] = GetSpellInfo(78)
	SlamAndAwe.constants["Deadly Calm"], _, SlamAndAwe.constants["Deadly Calm Icon"] = GetSpellInfo(85730)

	--Protection
	SlamAndAwe.constants["Commanding Shout"], _, SlamAndAwe.constants["Commanding Shout Icon"] = GetSpellInfo(469)
	SlamAndAwe.constants["Shield Slam"], _, SlamAndAwe.constants["Shield Slam Icon"] = GetSpellInfo(23922)		
	SlamAndAwe.constants["Revenge"], _, SlamAndAwe.constants["Revenge Icon"] = GetSpellInfo(6572)		
	SlamAndAwe.constants["Thunder Clap"], _, SlamAndAwe.constants["Thunder Clap Icon"] = GetSpellInfo(6343)		
	SlamAndAwe.constants["Devastate"], _, SlamAndAwe.constants["Devastate Icon"] = GetSpellInfo(20243)	

	--Buffs and Debuffs	
	SlamAndAwe.constants["Skull Banner"], _, SlamAndAwe.constants["Skull Banner Icon"] = GetSpellInfo(114207)
	SlamAndAwe.constants["Demoralizing Banner"], _, SlamAndAwe.constants["Demoralizing Banner Icon"] = GetSpellInfo(114203)
	SlamAndAwe.constants["Mocking Banner"], _, SlamAndAwe.constants["Mocking Banner Icon"] = GetSpellInfo(114192)
	SlamAndAwe.constants["Bloodsurge"], _, SlamAndAwe.constants["Bloodsurge Icon"] = GetSpellInfo(46916)
	SlamAndAwe.constants["Shield Block"], _, SlamAndAwe.constants["Shield Block Icon"] = GetSpellInfo(2565)		
	SlamAndAwe.constants["Shield Barrier"], _, SlamAndAwe.constants["Shield Barrier Icon"] = GetSpellInfo(112048)	
	SlamAndAwe.constants["Demoralizing Shout"], _, SlamAndAwe.constants["Demoralizing Shout Icon"] = GetSpellInfo(1160) -- Prot only	
	SlamAndAwe.constants["Ultimatum"], _, SlamAndAwe.constants["Ultimatum Icon"] = GetSpellInfo(122509)
	SlamAndAwe.constants["Battle Trance"], _, SlamAndAwe.constants["Battle Trance Icon"] = GetSpellInfo(12964) -- Doesn't exist
	SlamAndAwe.constants["Incite"], _, SlamAndAwe.constants["Incite Icon"] = GetSpellInfo(50687) -- Dosen't exist (prot only)
	SlamAndAwe.constants["Flurry"], _, SlamAndAwe.constants["Flurry Icon"] = GetSpellInfo(12972) -- For uptime frame
	SlamAndAwe.constants["Enrage"], _, SlamAndAwe.constants["Enrage Icon"] = GetSpellInfo(13046) -- For uptime frame
	SlamAndAwe.constants["Weakened Blows"], _, SlamAndAwe.constants["Weakened Blows Icon"] = GetSpellInfo(115798)
	SlamAndAwe.constants["Raging Wind"], _, SlamAndAwe.constants["Raging Wind Icon"] = GetSpellInfo(115317)		
	SlamAndAwe.constants["Shield Wall"], _, SlamAndAwe.constants["Shield Wall Icon"] = GetSpellInfo(871)	 
	SlamAndAwe.constants["Taste for Blood"], _, SlamAndAwe.constants["Taste for Blood Icon"] = GetSpellInfo(56638)	 
	SlamAndAwe.constants["Purge"], _, SlamAndAwe.constants["Purge Icon"] = GetSpellInfo(370) -- Probably not needed	  
	SlamAndAwe.constants["Last Stand"], _, SlamAndAwe.constants["Last Stand Icon"] = GetSpellInfo(12975)	
	SlamAndAwe.constants["Rallying Cry"], _, SlamAndAwe.constants["Rallying Cry Icon"] = GetSpellInfo(97462)
end

function SlamAndAwe:OnDisable()
	-- Called when the addon is disabled
	self:UnregisterEvent("PLAYER_ENTERING_WORLD")
	self:UnregisterEvent("PLAYER_LOGIN")
	self:UnregisterEvent("PLAYER_ALIVE")
	self:UnregisterEvent("UNIT_POWER")
	self:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED")
	self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
	self:UnregisterEvent("CHARACTER_POINTS_CHANGED")
	self:UnregisterEvent("PLAYER_REGEN_DISABLED")
	self:UnregisterEvent("PLAYER_REGEN_ENABLED")
	self:UnregisterEvent("SPELL_UPDATE_COOLDOWN")
	self:UnregisterEvent("UPDATE_BINDINGS")
	self:UnregisterEvent("UI_ERROR_MESSAGE")
	self:UnregisterEvent("GLYPH_UPDATED")
	--	we must still look out for talent changes to fire change of spec to re-enable
	--	self:UnregisterEvent("PLAYER_TALENT_UPDATE")
	--	self:UnregisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
	self:UnregisterEvent("UNIT_EXITED_VEHICLE")
	self:UnregisterEvent("UNIT_ENTERED_VEHICLE")
end

function SlamAndAwe:OnEnable()
	self:LibSharedMedia_Registered()
	self:RegisterEvent("PLAYER_ENTERING_WORLD")
	self:RegisterEvent("PLAYER_LOGIN")
	self:RegisterEvent("PLAYER_ALIVE")
	self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED")
	self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
	self:RegisterEvent("CHARACTER_POINTS_CHANGED")
	self:RegisterEvent("PLAYER_REGEN_DISABLED")
	self:RegisterEvent("PLAYER_REGEN_ENABLED")
	self:RegisterEvent("SPELL_UPDATE_COOLDOWN")
	self:RegisterEvent("UPDATE_BINDINGS")
	self:RegisterEvent("UI_ERROR_MESSAGE")
	self:RegisterEvent("UNIT_POWER")
	self:RegisterEvent("UNIT_AURA")	
	self:RegisterEvent("PLAYER_TALENT_UPDATE")
	self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
	self:RegisterEvent("UNIT_ENTERED_VEHICLE")
	self:RegisterEvent("UNIT_EXITED_VEHICLE")
	self:RegisterEvent("GLYPH_UPDATED")
end

function SlamAndAwe:LibSharedMedia_Registered()
	media:Register("sound", "SAA Maelstrom 1", "Sound\\Spells\\ShootWandLaunchLightning.wav")
	media:Register("sound", "SAA Maelstrom 2", "Sound\\Spells\\DynamiteExplode.wav")
	media:Register("sound", "SAA Maelstrom 3", "Sound\\Spells\\ArmorKitBuffSound.wav")
	media:Register("sound", "SAA Maelstrom 4", "Sound\\Spells\\Fizzle\\FizzleShadowA.wav")
	media:Register("sound", "SAA Maelstrom 5", "Sound\\Spells\\LevelUp.wav")
	media:Register("sound", "SAA Maelstrom 6", "Sound\\Spells\\Tradeskills\\FishBite.wav")
	media:Register("sound", "SAA Maelstrom 7", "Sound\\Spells\\Tradeskills\\MiningHitA.wav")
	media:Register("sound", "SAA Maelstrom 8", "Sound\\Spells\\AspectofTheSnake.wav")
	media:Register("sound", "SAA Maelstrom 9", "Sound\\Spells\\bind2_Impact_Base.wav")
	media:Register("sound", "SAA Shield 1", "Sound\\Doodad\\BellowIn.wav")
	media:Register("sound", "SAA Shield 2", "Sound\\Doodad\\BellowOut.wav")
	media:Register("sound", "SAA Shield 3", "Sound\\Doodad\\PVP_Lordaeron_Door_Open.wav")
	media:Register("sound", "SAA Shield 4", "Sound\\Spells\\ShaysBell.wav")

	for k, v in pairs(media:List("statusbar")) do
		self.textures[v] = v
	end
	for k, v in pairs(media:List("border")) do
		self.borders[v] = v
	end
	for k, v in pairs(media:List("font")) do
		self.fonts[v] = v
	end
	for k, v in pairs(media:List("sound")) do
		self.sounds[v] = v
	end
end

----------------------
-- Event Routines
----------------------

	
function SlamAndAwe:UNIT_ENTERED_VEHICLE()
	if UnitInVehicle("player") then
		self:TidyUpAfterCombat() -- on entering vehicle treat as if out of combat ie: disable incombat displays
	end
end

function SlamAndAwe:UNIT_EXITED_VEHICLE()
	if not UnitInVehicle("player") and InCombatLockdown() then
		self:EnteredCombat()  -- if in combat when exit vehichle enable SlamAndAwe combat effects
	end
end

function SlamAndAwe:PLAYER_ENTERING_WORLD()

    self:SetSpecialization()

	self:SetBorderTexture(nil, SlamAndAwe.db.char.border)
	self:SetBarBorderTexture(nil, SlamAndAwe.db.char.barborder)
	self:SetTalentEffects()
	if not SlamAndAwe.db.char.disabled then
		  self:RedrawFrames()
		  self:UpdateBindings()
		  SlamAndAwe.db.char.priority.prOption = SlamAndAwe.db.char.priority.prOptions[SlamAndAwe.db.char.priority.groupnumber]
   end
  	self:RageBar()
     if SlamAndAwe.db.char.debug then
        self:Print("PLAYER_ENTERING_WORLD Fired")
    end   
end

function SlamAndAwe:PLAYER_LOGIN()
	self:SetBorderTexture(nil, SlamAndAwe.db.char.border)
	self:SetBarBorderTexture(nil, SlamAndAwe.db.char.barborder)
	queryDisable = false -- when player first logs in set test for talents in Enh Spec to false
	  if SlamAndAwe.db.char.debug then
        self:Print("PLAYER_LOGIN Fired")
    end   
end

function SlamAndAwe:PLAYER_ALIVE()
  self:SetTalentEffects()
	if not SlamAndAwe.db.char.disabled then
     self:RageBar()
     self:RedrawFrames()
     self:UpdateBindings()
    if not queryDisable then -- only ask if not in Enh and addon active if this is fired immediately after first login
  --     self:QueryDisableAddon()
      self:QuerySpecChanged()
      queryDisable = true
     end
  end
  	  if SlamAndAwe.db.char.debug then
        self:Print("PLAYER_ALIVE Fired")
    end    
end

function SlamAndAwe:UI_ERROR_MESSAGE(_, ...)
	if SlamAndAwe.db.char.warning.range then
		local arg1 = select(1,...) or ""
		if strfind(arg1, L["Out of range"]) or strfind(arg1, L["too far away"]) then
			self:PrintMsg(arg1, SlamAndAwe.db.char.warning.colour, 0.5)
		end
	end
end

function SlamAndAwe:UNIT_POWER()
    if not SlamAndAwe.db.char.disabled then
        self:RageBar()
      if SlamAndAwe.db.char.sbshow then
        if SlamAndAwe.db.char.currentspec == "Protection" then
          if SlamAndAwe.db.char.debug then
       --   self:Print("Estimated ShieldBarrier: "..SlamAndAwe:EstimateShieldBarrier())
          end     
        SlamAndAwe:UpdateEstimatedShieldBarrierText(SlamAndAwe:EstimateShieldBarrier())
      end
    end
   end
end

function SlamAndAwe:UNIT_AURA(_, ...)
  if not SlamAndAwe.db.char.disabled then
    local arg1 = select(1,...) or ""
    if (arg1 == "player") then  
      if SlamAndAwe.db.char.currentspec == "Arms" then
        updateActiveTasteForBlood = true
        SlamAndAwe.db.char.tfbstacks = self:GetTasteForBloodInfo()
        if SlamAndAwe.db.char.barstext and SlamAndAwe.db.char.tfbshow then
          self.frames["TasteForBlood"].text:SetText(SlamAndAwe.db.char.tfbstacks.." stacks")
        else 
          self.frames["TasteForBlood"].text:SetText("")
        end
        self:TasteForBloodBar()
      end
      if SlamAndAwe.db.char.sbshow then   
           	_, _, _, _, _, _, _, _, _, _, _, _, _, _, SB_Current = UnitBuff("Player","Shield Barrier")
        if SB_Current then
            if SBActive then
              if SBLast < SB_Current then -- If Shield Barrier is already up and you were able to recast it (only with a larger barrier)           
                    self:ShieldBarrierBar()                             
                 else --Barrier is already up, just need to update text so the timer isnt refreshed
                    self:UpdateShieldBarrierText(true)
                end
            else
            if SlamAndAwe.db.char.debug then
             -- self:Print("Actual ShieldBarrier Was: "..SB_Current)
            end
              self:ShieldBarrierBar()                          	
            end
        else
          self:UpdateShieldBarrierText(false)
        end
      end
    end
   end 
end

function SlamAndAwe:COMBAT_LOG_EVENT_UNFILTERED(_, timestamp, event, hideCaster, sourceGUID, sourceName, sourceFlags, sourceFlags2, destGUID, destName, destFlags, _, _, _, _, interruptedSpellID, ...)
	if not SlamAndAwe.db.char.disabled then
		if sourceGUID == UnitGUID("player") then
			local spellID = select(1,...) or 0
			if event == "SPELL_INTERRUPT" then
				local spellName = select(1,...) -- was 5, then 7, now 1
				SlamAndAwe:Print(spellName)
				if spellName then
					if SlamAndAwe.db.char.warning.interrupt then
						self:PrintMsg(L["Interrupted: "] .. spellName, SlamAndAwe.db.char.warning.colour, SlamAndAwe.db.char.warning.duration)
					end
					if SlamAndAwe.db.char.announce_interrupt then
						self:Announce( SlamAndAwe.db.char.announce_interrupt_where , L["Interrupted: "] ..destName.. "'s " ..GetSpellLink(interruptedSpellID)..".")
					end
				end
			end
		end
	end
end

function SlamAndAwe:SPELL_UPDATE_COOLDOWN()
  if not SlamAndAwe.db.char.disabled then
    if SlamAndAwe.db.char.gcdshow then
      self:GCDBar()
    end
  end
end

function SlamAndAwe:UNIT_SPELLCAST_SUCCEEDED(_, ...)
  if not SlamAndAwe.db.char.disabled then
    local arg1 = select(1,...) or ""
    local arg2 = select(2,...) or ""
    if arg1 == "player" then -- skip if someone else casting
      if SlamAndAwe.db.char.announce_skull_banner then
        if arg2 == SlamAndAwe.constants["Skull Banner"] then
          self:Announce( SlamAndAwe.db.char.announce_skull_banner_where , L["skull_banner_msg"])
          self:TrackBanner( L["skull_banner_msg_end"] , SlamAndAwe.db.char.announce_skull_banner_where , SlamAndAwe.db.char.sBannerLen )       
        end
      end
      if SlamAndAwe.db.char.announce_demoralizing_banner then
        if arg2 == SlamAndAwe.constants["Demoralizing Banner"] then
          self:Announce( SlamAndAwe.db.char.announce_demoralizing_banner_where , L["demoralizing_banner_msg"])
          self:TrackBanner( L["demoralizing_banner_msg_end"] , SlamAndAwe.db.char.announce_demoralizing_banner_where , SlamAndAwe.db.char.dBannerLen )
        end
      end
      if SlamAndAwe.db.char.announce_mocking_banner then
        if arg2 == SlamAndAwe.constants["Mocking Banner"] then
          self:Announce( SlamAndAwe.db.char.announce_mocking_banner_where , L["mocking_banner_msg"]) 
          updateActiveBanner = false -- we don't announce when it ends but it overwrites other banners       
        end
      end
      if SlamAndAwe.db.char.csshow then
        if arg2 == SlamAndAwe.constants["Colossus Smash"] then
          self:ColossusSmashBar()
        end
      end
      if SlamAndAwe.db.char.reshow then
        if arg2 == SlamAndAwe.constants["Recklessness"] then
          self:RecklessnessBar()
        end
      end
      if SlamAndAwe.db.char.dcshow then
        if arg2 == SlamAndAwe.constants["Deadly Calm"] then
          self:DeadlyCalmBar()
        end
      end
      if SlamAndAwe.db.char.swstshow then
        if arg2 == SlamAndAwe.constants["Sweeping Strikes"] then
          self:SweepingStrikesBar()
        end
      end
      if SlamAndAwe.db.char.sblshow then
        if arg2 == SlamAndAwe.constants["Shield Block"] then
          self:ShieldBlockBar()
        end
      end
      if SlamAndAwe.db.char.swshow then
        if arg2 == SlamAndAwe.constants["Shield Wall"] then
          self:ShieldWallBar()
        end
      end
	  if SlamAndAwe.db.char.demoshoutshow then
        if arg2 == SlamAndAwe.constants["Demoralizing Shout"] then
          self:DemoShoutBar()
        end
      end
	  if SlamAndAwe.db.char.laststandshow then
        if arg2 == SlamAndAwe.constants["Last Stand"] then
          self:LastStandBar()
        end
      end
	  if SlamAndAwe.db.char.rallyingcryshow then
        if arg2 == SlamAndAwe.constants["Rallying Cry"] then
          self:RallyingCryBar()
        end
      end
    end
  end
end

function SlamAndAwe:CHARACTER_POINTS_CHANGED()
	self:SetTalentEffects()
	self:CreateBaseFrame()
	  if SlamAndAwe.db.char.debug then
      self:Print("CHARACTER_POINTS_CHANGED Fired")
    end     
end

function SlamAndAwe:PLAYER_REGEN_DISABLED() -- Entering Combat
	self:EnteredCombat()
end

function SlamAndAwe:PLAYER_REGEN_ENABLED() -- Leaving Combat
	self:TidyUpAfterCombat()
end

function SlamAndAwe:UPDATE_BINDINGS()
	if not InCombatLockdown() then
		self:UpdateBindings()
	end
end

function SlamAndAwe:PLAYER_TALENT_UPDATE()
	self:SetTalentEffects()
			if not SlamAndAwe.db.char.disabled then
        self:RedrawFrames()
        self:RageBar()
      end
    if SlamAndAwe.db.char.debug then
      self:Print("PLAYER_TALENT_UPDATE Fired")
      SlamAndAwe:GetGlyphInfo()
    end
end

function SlamAndAwe:GLYPH_UPDATED()
	self:SetTalentEffects()
			if not SlamAndAwe.db.char.disabled then
        self:RedrawFrames()
         self:RageBar()
      end
    if SlamAndAwe.db.char.debug then
      self:Print("GLYPH_UPDATED Fired")
    end      
end

function SlamAndAwe:ACTIVE_TALENT_GROUP_CHANGED()
  self:SetTalentEffects()
			if not SlamAndAwe.db.char.disabled then
        self:RedrawFrames()
        self:RageBar()
      end
    if SlamAndAwe.db.char.debug then
      self:Print("ACTIVE_TALENT_GROUP_CHANGED Fired")
    end  
end

----------------------------
-- Combat start and stop
----------------------------

function SlamAndAwe:EnteredCombat()
	if UnitInVehicle("player") then -- don't enable priorities & bars if we enter combat in a vehicle
		return
	end
	if SlamAndAwe.db.char.disablebars then
		self.BaseFrame:Show()
	end
  if SlamAndAwe.db.char.tfbshow and not SlamAndAwe.db.char.disabled then
		if SlamAndAwe.db.char.currentspec == "Arms" then
			self:SetTasteForBloodAlpha(SlamAndAwe.db.char.colours.tfbalpha) -- set maelstrom frame to in combat alpha
		end
	end
	if SlamAndAwe.db.char.uptime.show and not SlamAndAwe.db.char.disabled then
		if not self.uptime.incombat then
			self.uptime.incombat = true
			-- reset last fight data on entering combat
			self:InitialiseUptimeBuffs(self.uptime.lastfight)
			self.uptime.currentTime = GetTime()
			self:UpdateUptime()
			self:UpdateUptimeFrames(true)
			self.uptime.TimerEvent = self:ScheduleRepeatingTimer("UpdateUptime", 0.1, nil);
		end
	end
	if SlamAndAwe.db.char.priority.show and not SlamAndAwe.db.char.disabled then
		SlamAndAwe.db.char.priority.next = "none"
		self:SetPriorityIcon(SlamAndAwe.db.char.priority.next)
		self.updatePriority = true
		self.PriorityFrame:Show()
	end
	if SlamAndAwe.db.char.sbshow and not SlamAndAwe.db.char.disabled then
    if SlamAndAwe.db.char.currentspec == "Protection" then
	    SlamAndAwe:ShieldBarrierBar()
    end
	end
end

function SlamAndAwe:TidyUpAfterCombat()
	self.frames["TasteForBlood"]:Hide()
	self.frames["TasteForBlood"].icon:Hide()
	self.frames["SweepingStrikes"]:Hide()
	self.frames["SweepingStrikes"].icon:Hide()
	self.frames["DemoShout"]:Hide()
	self.frames["DemoShout"].icon:Hide()
	self.frames["ColossusSmash"].icon:Hide()
	self.frames["ColossusSmash"]:Hide()
	self.frames["Recklessness"].icon:Hide()
	self.frames["Recklessness"]:Hide()
	self.frames["DeadlyCalm"].icon:Hide()
	self.frames["DeadlyCalm"]:Hide()
	self.frames["LastStand"]:Hide()
	self.frames["LastStand"].icon:Hide()
	self.frames["ShieldBlock"].icon:Hide()
	self.frames["ShieldBlock"]:Hide()
	self.frames["ShieldBarrier"].icon:Hide()
	self.frames["ShieldBarrier"]:Hide()
	self.frames["ShieldWall"].icon:Hide()
	self.frames["ShieldWall"]:Hide()
	self.frames["RallyingCry"].icon:Hide()
	self.frames["RallyingCry"]:Hide()
	if SlamAndAwe.db.char.hideRageBarOOC then
			self.frames["Rage"]:Hide()
	end
		
	self:SetPriorityIcon("none")
	self.updatePriority = false
	self.PriorityFrame:Hide()
	if SlamAndAwe.db.char.uptime.show and not SlamAndAwe.db.char.disabled then
		if self.uptime.incombat then
			self:UpdateUptime()
			self.uptime.incombat = false
			self:UpdateUptimeFrames(true)
			self:CancelTimer(self.uptime.TimerEvent , false)
		end
	end
	if SlamAndAwe.db.char.disablebars then
		self.BaseFrame:Hide()
	end
	if not SlamAndAwe.db.char.binding.macroset then
		-- call update Bindings to set macro keys if we were in combat when addon initialised
		self:UpdateBindings()
	end
end

----------------------------
-- Question box handler
----------------------------



function SlamAndAwe:QueryDisableAddon()
--	if SlamAndAwe.db.char.maelstromTalents == 0 then -- check MW talents again to counter Player_Entering_World bug
--		self:SetTalentEffects()
--	end
--	if UnitLevel("player") >= 60 then -- don't bother asking to disable addon if player under level 60.
--		if SlamAndAwe.db.char.maelstromTalents == 0 and not SlamAndAwe.db.char.disabled then
--			-- addon is enabled but we have changed to a non Enhance Spec ask if we should disable addon
--			self:DisplayQuestionFrame(false, false)
--		elseif SlamAndAwe.db.char.maelstromTalents > 0 and SlamAndAwe.db.char.disabled then
--			-- addon is disabled and we have changed to an Enhance Spec ask if we should enable addon
--			self:DisplayQuestionFrame(true, false)
--		end
--	end
end

StaticPopupDialogs["SAA_QUESTION_FRAME"] = {
	text = L["You have changed to a new talent spec do you want to enable SlamAndAwe?"],
	button1 = "Yes",
	button2 = "No",
	OnAccept = function()
	SlamAndAwe:EnableDisable()
	end,
	timeout = 0,
	hideOnEscape = 1,
}

function SlamAndAwe:DisplayQuestionFrame(enable, spec)
	if spec then
		if enable then 
			StaticPopupDialogs["SAA_QUESTION_FRAME"].text = L["You have changed to a supported spec, do you want to enable SlamAndAwe?"]
		else
			StaticPopupDialogs["SAA_QUESTION_FRAME"].text = L["You have changed to a non supported spec, do you want to disable SlamAndAwe?"]
		end
	else
		if enable then 
			StaticPopupDialogs["SAA_QUESTION_FRAME"].text = L["You are in a supported spec, do you want to enable SlamAndAwe?"]
		else
			StaticPopupDialogs["SAA_QUESTION_FRAME"].text = L["You are NOT in a supported spec, do you want to disable SlamAndAwe?"]
		end
	end
	self:DebugPrint("entered DisplayQuestionFrame, text is :"..StaticPopupDialogs["SAA_QUESTION_FRAME"].text)
	StaticPopup_Show("SAA_QUESTION_FRAME")
end
	
---------------------------
-- Buff Info functions
---------------------------

 function SlamAndAwe:GetTasteForBloodInfo()
 	local index = 1
 	while UnitBuff("PLAYER", index) do
 		local name, _, _, count, _, _, tfbTime = UnitBuff("PLAYER", index)
 		if name == SlamAndAwe.constants["Taste for Blood"] then
 			return count, tfbTime
 		end
 		index = index + 1
 	end
 	return 0, 0 
 end

---------------------------
-- General Helper functions
---------------------------

 function SlamAndAwe:Announce(where,what)
  messagetype = SlamAndAwe:MessageType(where)
  if messagetype == "RAID" and not IsInRaid() then
	return
  elseif messagetype == "PARTY" and not IsInGroup() then
	return
  else
	SendChatMessage(what , messagetype , nil, nil)
  end
 end

 function SlamAndAwe:TrackBanner(msg,where,length)
	last_banner_msg = msg
	last_banner_where = where
	BannerTime = GetTime() + length
	updateActiveBanner = true
 end

---------------------------
-- functions
---------------------------

function SlamAndAwe:RedrawFrames()
	self:CreateBaseFrame()
	self:CreateUptimeFrame()
	self:CreatePriorityFrame()
end

function SlamAndAwe:SetSpecialization()
  local currentSpec = GetSpecialization()
  local currentSpecName = currentSpec and select(2, GetSpecializationInfo(currentSpec)) or "None"
  if currentSpec == 2 then
      SlamAndAwe.db.char.currentspec = "Fury"
  elseif currentSpec == 3 then
  	SlamAndAwe.db.char.currentspec = "Protection"
  elseif currentSpec == 1 then
  	SlamAndAwe.db.char.currentspec = "Arms" 
  else
  	SlamAndAwe.db.char.currentspec = "None"
  end
  SlamAndAwe:DebugPrint(currentSpec)
  SlamAndAwe:DebugPrint(GetSpecializationInfo(currentSpec))
  SlamAndAwe:DebugPrint(currentSpecName)
  SlamAndAwe:DebugPrint(SlamAndAwe.db.char.currentspec)
end

function SlamAndAwe:QuerySpecChanged()
	if SlamAndAwe.db.char.currentspec == "Fury" then 
		if SlamAndAwe.db.char.enableFurySpec then
			if SlamAndAwe.db.char.disabled then
				SlamAndAwe:Enable()
			end
			if SlamAndAwe.db.char.priority.groupnumber ~= 1 then
				if SlamAndAwe.db.char.priority.groupnumber < 4 then
					SlamAndAwe:SelectPrioritySet(1)
				end
			end		
		else
			if not SlamAndAwe.db.char.disabled then
				SlamAndAwe:Disable()
			end
		end
	elseif SlamAndAwe.db.char.currentspec == "Protection" then
		if SlamAndAwe.db.char.enableProtSpec then
			if SlamAndAwe.db.char.disabled then
				SlamAndAwe:Enable()
			end
			if SlamAndAwe.db.char.priority.groupnumber ~= 2 then
				if SlamAndAwe.db.char.priority.groupnumber < 4 then
					SlamAndAwe:SelectPrioritySet(2)
				end
			end
		else
			if not SlamAndAwe.db.char.disabled then
				SlamAndAwe:Disable()
			end
		end
	elseif SlamAndAwe.db.char.currentspec == "Arms" then
		if SlamAndAwe.db.char.enableProtSpec then
			if SlamAndAwe.db.char.disabled then
				SlamAndAwe:Enable()
			end
			if SlamAndAwe.db.char.priority.groupnumber ~= 3 then
				if SlamAndAwe.db.char.priority.groupnumber < 4 then
					SlamAndAwe:SelectPrioritySet(3)
				end
			end
		else
			if not SlamAndAwe.db.char.disabled then
				SlamAndAwe:Disable()
			end
		end
	end
end

function SlamAndAwe:SetTalentEffects()
  SlamAndAwe:SetSpecialization() -- Set spec first

  SlamAndAwe.db.char.SBLen = 6
  SlamAndAwe.db.char.SBPercent = 1
  SlamAndAwe.db.char.SBlLen = 6
  SlamAndAwe.db.char.SBlPercent = 1
  SlamAndAwe.db.char.CSLen = 6
  SlamAndAwe.db.char.CSPercent = 1
  SlamAndAwe.db.char.RELen = 12
  SlamAndAwe.db.char.REPercent = 1
  SlamAndAwe.db.char.DCLen = 9
  SlamAndAwe.db.char.DCPercent = 1
  SlamAndAwe.db.char.SWPercent = 1
  SlamAndAwe.db.char.ragecap = 100
  SlamAndAwe.db.char.SWSTLen = 10
  SlamAndAwe.db.char.SWSTPercent = 1
  SlamAndAwe.db.char.TFBLen = 15
  SlamAndAwe.db.char.TFBPercent = 1
  SlamAndAwe.db.char.DSPercent = 1
  SlamAndAwe.db.char.LSPercent = 1   
  SlamAndAwe.db.char.RCPercent = 1   
  
  local hasreckglyph
  hasreckglyph = SlamAndAwe:HasGlyph(94374)
  if hasreckglyph then  
    SlamAndAwe.db.char.RELen = SlamAndAwe.db.char.RELen * 1.5
  end
  
  local hasrageglyph
  hasrageglyph = SlamAndAwe:HasGlyph(58098)
  if hasrageglyph then  
    SlamAndAwe.db.char.ragecap = 120
  end

	if SlamAndAwe.db.char.gcdfullwidth then
		GCDPercent = 1
	else
		GCDPercent = 1.5 / 10
	end

  SlamAndAwe:QuerySpecChanged() -- Update priority group if needed
end

function SlamAndAwe:DisplayVersion()
	self:Print(self.version)
end

function SlamAndAwe:CreateBaseFrame()
	self:SetSpecialization()
	self:SetTalentEffects()
	self.BaseFrame:SetScale(SlamAndAwe.db.char.scale)

	self.BaseFrame:SetWidth(SlamAndAwe.db.char.fWidth + SlamAndAwe.db.char.fHeight / 7)
	self.BaseFrame:SetHeight(SlamAndAwe.db.char.fHeight)
	self.BaseFrame:SetBackdrop(self.frameBackdrop)
	self.BaseFrame:SetBackdropColor(1, 1, 1, 0)
	self.BaseFrame:SetMovable(true)
	self.BaseFrame:RegisterForDrag("LeftButton")
	self.BaseFrame:SetPoint(SlamAndAwe.db.char.point, SlamAndAwe.db.char.relativeTo, SlamAndAwe.db.char.relativePoint, SlamAndAwe.db.char.xOffset, SlamAndAwe.db.char.yOffset)
	self.BaseFrame:SetScript("OnDragStart", 
		function()
			self.BaseFrame:StartMoving();
		end );
	self.BaseFrame:SetScript("OnDragStop",
		function()
			self.BaseFrame:StopMovingOrSizing();
			self.BaseFrame:SetScript("OnUpdate", nil);
			self:FinishedMoving(SlamAndAwe.db.char, self.BaseFrame);
		end );
	self.BaseFrame:Show()
	
	SlamAndAwe.db.char.movingframes = false
	
	local barHeight = SlamAndAwe.db.char.fHeight / 7
	local baseOffset = (-1 * barHeight) + 3
	local barCount = 0

	SlamAndAwe:SetBarFrame(self.frames["GCD"], 
					SlamAndAwe.db.char.fWidth * GCDPercent, barHeight,
					barCount * baseOffset, 1,
					0, 1.5, 
					6, 1, 
					.6, .6, .6, .6,
					false)
	self.GCDWidth = self.frames["GCD"].statusbar:GetWidth() -- to account for spark width
	if SlamAndAwe.db.char.gcdshow then
		barCount = barCount + 1 -- we will use gcd frame 
	end
    
  colours = SlamAndAwe.db.char.colours.rage
	SlamAndAwe:SetBarFrame(self.frames["Rage"], 
					SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.REPercent, barHeight, 
					barCount * baseOffset, 1,
					0, SlamAndAwe.db.char.ragecap, 
					6, 1, 
          colours.r, colours.g, colours.b, colours.a,
					f)
	--if SlamAndAwe.db.char.rageshow then
		barCount = barCount + 1 -- we will use Rage frame 
	--end
	
--DPS Bars
  
  if ((SlamAndAwe.db.char.currentspec == "Fury") or (SlamAndAwe.db.char.currentspec == "Arms")) then
	
    colours = SlamAndAwe.db.char.colours.colossussmash
    SlamAndAwe:SetBarFrame(self.frames["ColossusSmash"], 
            SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.CSPercent, barHeight, 
            barCount * baseOffset, 1,
            0, SlamAndAwe.db.char.CSLen, 
            10, 1, 
            colours.r, colours.g, colours.b, colours.a,
            true)
    if SlamAndAwe.db.char.csshow then
      barCount = barCount + 1 -- we will use ColossusSmash frame 
    end
    self:SetBarIcon(self.frames["ColossusSmash"].icon, 86346)
    
    if SlamAndAwe.db.char.currentspec == "Arms" then
      colours = SlamAndAwe.db.char.colours.tfb
      SlamAndAwe:SetBarFrame(self.frames["TasteForBlood"], 
            SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.TFBPercent, barHeight,
            barCount * baseOffset, 1,
            0, SlamAndAwe.db.char.TFBLen, 
            10, 1, 
            colours.r, colours.g, colours.b, SlamAndAwe.db.char.colours.tfbalpha,
            true)
      if SlamAndAwe.db.char.tfbshow then
        barCount = barCount + 1 -- we will use tfb frame 
      end
      self:SetBarIcon(self.frames["TasteForBlood"].icon, 56638)
    end
    
    if SlamAndAwe.db.char.currentspec == "Arms" then
      colours = SlamAndAwe.db.char.colours.sweepingstrikes
      SlamAndAwe:SetBarFrame(self.frames["SweepingStrikes"], 
            SlamAndAwe.db.char.fWidth, barHeight,
            barCount * baseOffset, 1,
            0, SlamAndAwe.db.char.SWSTLen, 
            10, 1, 
            colours.r, colours.g, colours.b, colours.a,
            true)
      if SlamAndAwe.db.char.swstshow then
        barCount = barCount + 1 -- we will use swst frame 
      end
      self:SetBarIcon(self.frames["SweepingStrikes"].icon, 12328)
    end  

  --Protection Bars	----------------------------------------	
	elseif SlamAndAwe.db.char.currentspec == "Protection" then	
  ----------------------------------------------------------
   
   colours = SlamAndAwe.db.char.colours.shieldbarrier
    SlamAndAwe:SetBarFrame(self.frames["ShieldBarrier"], 
            SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.SBPercent, barHeight, 
            barCount * baseOffset, 1,
            0, SlamAndAwe.db.char.SBLen, 
            10, 1, 
            colours.r, colours.g, colours.b, colours.a,
            true)
    if SlamAndAwe.db.char.sbshow then
      barCount = barCount + 1 -- we will use ShieldBarrier frame
    end
    self:SetBarIcon(self.frames["ShieldBarrier"].icon, 112048)
    
    colours = SlamAndAwe.db.char.colours.shieldblock
    SlamAndAwe:SetBarFrame(self.frames["ShieldBlock"], 
            SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.SBlPercent, barHeight, 
            barCount * baseOffset, 1,
            0, SBlMax,
            10, 1, 
            colours.r, colours.g, colours.b, colours.a,
            true)
    if SlamAndAwe.db.char.sblshow then
      SBlPos = barCount
      barCount = barCount + 1 -- we will use ShieldBlock frame 
    end
    self:SetBarIcon(self.frames["ShieldBlock"].icon, 2565)
     
    colours = SlamAndAwe.db.char.colours.demoshout
    SlamAndAwe:SetBarFrame(self.frames["DemoShout"], 
		SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.DSPercent, barHeight,
		barCount * baseOffset, 1,
		0, SlamAndAwe.db.char.DSLen, 
		10, 1, 
		colours.r, colours.g, colours.b, colours.a,
		true)
    if SlamAndAwe.db.char.demoshoutshow then
      barCount = barCount + 1 -- we will use DemoShout frame 
    end
	    self:SetBarIcon(self.frames["DemoShout"].icon,1160) 

	colours = SlamAndAwe.db.char.colours.laststand
    SlamAndAwe:SetBarFrame(self.frames["LastStand"], 
		SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.LSPercent, barHeight,
		barCount * baseOffset, 1,
		0, SlamAndAwe.db.char.LSLen, 
		10, 1, 
		colours.r, colours.g, colours.b, colours.a,
		true)
    if SlamAndAwe.db.char.laststandshow then
      barCount = barCount + 1 -- we will use LastStand frame 
    end
	    self:SetBarIcon(self.frames["LastStand"].icon,12975) 


  else
  -- No Spec  
    self:Print("No specialization selected!")
  end

  -- All spec bars
    colours = SlamAndAwe.db.char.colours.deadlycalm
    SlamAndAwe:SetBarFrame(self.frames["DeadlyCalm"], 
            SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.DCPercent, barHeight, 
            barCount * baseOffset, 1,
            0, SlamAndAwe.db.char.DCLen, 
            10, 1, 
            colours.r, colours.g, colours.b, colours.a,
            true)
    if SlamAndAwe.db.char.dcshow then
      barCount = barCount + 1 -- we will use DeadlyCalm frame 
    end
    self:SetBarIcon(self.frames["DeadlyCalm"].icon, 85730)   
    
    colours = SlamAndAwe.db.char.colours.recklessness
    SlamAndAwe:SetBarFrame(self.frames["Recklessness"], 
            SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.REPercent, barHeight, 
            barCount * baseOffset, 1,
            0, SlamAndAwe.db.char.RELen, 
            10, 1, 
            colours.r, colours.g, colours.b, colours.a,
            true)
    if SlamAndAwe.db.char.reshow then
      barCount = barCount + 1 -- we will use Recklessness frame 
    end
    self:SetBarIcon(self.frames["Recklessness"].icon, 1719)
        
    colours = SlamAndAwe.db.char.colours.rallyingcry
    SlamAndAwe:SetBarFrame(self.frames["RallyingCry"], 
		SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.RCPercent, barHeight,
		barCount * baseOffset, 1,
		0, SlamAndAwe.db.char.RCLen, 
		10, 1, 
		colours.r, colours.g, colours.b, colours.a,
		true)
    if SlamAndAwe.db.char.rallyingcryshow then
      barCount = barCount + 1 -- we will use RAllyignCry frame 
    end
	self:SetBarIcon(self.frames["RallyingCry"].icon,97462) 	

    colours = SlamAndAwe.db.char.colours.shieldwall
    SlamAndAwe:SetBarFrame(self.frames["ShieldWall"], 
            SlamAndAwe.db.char.fWidth * SlamAndAwe.db.char.SBlPercent, barHeight, 
            barCount * baseOffset, 1,
            0, SlamAndAwe.db.char.SWLen, 
            10, 1, 
            colours.r, colours.g, colours.b, colours.a,
            true)
    if SlamAndAwe.db.char.swshow then
      barCount = barCount + 1 -- we will use ShieldWall frame 
    end
	self:SetBarIcon(self.frames["ShieldWall"].icon, 871)

end --End CreateBaseFrame()

function SlamAndAwe:SetBarFrame(frameName, barWidth, barHeight, frameOffset, frameLevel, minValue, maxValue, frameValue, frameSpark, frameR, frameG, frameB, frameAlpha, icon)
	frameName:SetFrameStrata(SlamAndAwe.db.char.framestratalevel)
	frameName:SetWidth(barWidth)
	frameName:SetHeight(barHeight)
	frameName:ClearAllPoints()
	frameName:SetPoint("TOPLEFT", self.BaseFrame, "TOPLEFT", barHeight, frameOffset)
	frameName:SetBackdrop(self.barBackdrop);
	frameName:SetBackdropColor(0, 0, 0, .2);
	frameName:SetBackdropBorderColor( 1, 1, 1, 1);
	frameName:EnableMouse(false)
	if not frameName.statusbar then
		frameName.statusbar = CreateFrame("StatusBar", nil, frameName)
	end
	frameName.statusbar:SetFrameLevel(frameLevel)
	frameName.statusbar:ClearAllPoints()
	frameName.statusbar:SetHeight(barHeight - 6)
	frameName.statusbar:SetWidth(barWidth - 6)
	frameName.statusbar:SetPoint("TOPLEFT", frameName, "TOPLEFT", 3, -3)
	frameName.statusbar:SetStatusBarTexture(media:Fetch("statusbar", SlamAndAwe.db.char.texture))
	frameName.statusbar:GetStatusBarTexture():SetHorizTile(false) -- fix for textures stretching rather than revealing (was originally set true but caused bar bgs to tile in 5.0)
	frameName.statusbar:SetStatusBarColor(frameR, frameG, frameB, frameAlpha)
	frameName.statusbar:SetMinMaxValues(minValue,maxValue)
	frameName.statusbar:SetValue(frameValue)
	
	if not frameName.spark then
		frameName.spark = frameName.statusbar:CreateTexture(nil, "OVERLAY")
	end
	frameName.spark:SetTexture("Interface\\CastingBar\\UI-CastingBar-Spark")
	frameName.spark:SetWidth(16)
	frameName.spark:SetHeight(barHeight + 16)
	frameName.spark:SetBlendMode("ADD")
	frameName.spark:SetPoint("CENTER",frameName.statusbar,"BOTTOMLEFT",(barWidth - 6)* frameSpark, -1)
	frameName.spark:Show()
	
	if not frameName.text then
		frameName.text = frameName:CreateFontString(nil,"OVERLAY")
	end
	local barfont = media:Fetch("font", SlamAndAwe.db.char.barfont)
	frameName.text:SetFont(barfont, SlamAndAwe.db.char.barfontsize, SlamAndAwe.db.char.barfonteffect)
	frameName.text:ClearAllPoints()
	frameName.text:SetTextColor(1, 1, 1, 1)
	frameName.text:SetPoint("CENTER", frameName, "LEFT");
	frameName.text:SetText("")
	
		if not frameName.text2 then
		frameName.text2 = frameName:CreateFontString(nil,"OVERLAY")
	end
	local barfont = media:Fetch("font", SlamAndAwe.db.char.barfont)
	frameName.text2:SetFont(barfont, SlamAndAwe.db.char.barfontsize, SlamAndAwe.db.char.barfonteffect)
	frameName.text2:ClearAllPoints()
	--frameName.text2:SetTextColor(1, 1, 1, 1)
	frameName.text2:SetPoint("CENTER", frameName, "RIGHT", 40, -1);
	frameName.text2:SetText("")


	frameName:SetScript("OnUpdate", 
		function()
			SlamAndAwe:OnBarUpdate();
		end );
	if icon then
		frameName.icon:SetWidth(barHeight - 3) -- same as height to get square box
		frameName.icon:SetHeight(barHeight - 3)
		frameName.icon:SetPoint("TOPRIGHT", frameName, "TOPLEFT", 0 , -2)
		frameName.icon:Hide()
	end	
	frameName:Hide()
end

function SlamAndAwe:SetBarIcon(iconFrame, spellID)
	local _, _, icon = GetSpellInfo(spellID)
	iconFrame:SetBackdrop({
		bgFile = icon,
		--edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
		tile = false, tileSize = 0, edgeSize = 12,
		insets = { left = 0, right = 0, top = 0, bottom = 0 } })
end

function SlamAndAwe:ResetBars()
	self.BaseFrame:ClearAllPoints()
	SlamAndAwe.db.char.point = self.defaults.char.point
	SlamAndAwe.db.char.relativeTo = self.defaults.char.relativeTo 
	SlamAndAwe.db.char.relativePoint = self.defaults.char.relativePoint
	SlamAndAwe.db.char.xOffset = self.defaults.char.xOffset
	SlamAndAwe.db.char.yOffset = self.defaults.char.yOffset
	SlamAndAwe.db.char.fWidth = self.defaults.char.fWidth
	SlamAndAwe.db.char.fHeight = self.defaults.char.fHeight
	SlamAndAwe.db.char.scale = self.defaults.char.scale
	SlamAndAwe.db.char.barfont = self.defaults.char.barfont
	SlamAndAwe.db.char.barfontsize = self.defaults.char.barfontsize
	SlamAndAwe.db.char.bartexture = self.defaults.char.bartexture
	SlamAndAwe.db.char.texture = self.defaults.char.texture
	self.BaseFrame:SetPoint(SlamAndAwe.db.char.point, SlamAndAwe.db.char.relativeTo, SlamAndAwe.db.char.relativePoint, SlamAndAwe.db.char.xOffset, SlamAndAwe.db.char.yOffset)
	SlamAndAwe:SetTalentEffects()
	self:RedrawFrames()
	SlamAndAwe.db.char.movingframes = true -- so that call to ShowHideBars resets to false
	self:ShowHideBars()
	self:Print(L["config_reset"])
end

function SlamAndAwe:DebugTalents()
local currentSpec = GetSpecialization()
local currentSpecName = currentSpec and select(2, GetSpecializationInfo(currentSpec)) or "None"
print("Your current spec:", currentSpecName)
--     name, texture, tier, column, selected, available = GetTalentInfo(currentSpec, nil, nil)
--     print(name, texture, tier, column, selected, available)
--     DEFAULT_CHAT_FRAME:AddMessage("- "..nameTalent..": "..currRank.."/"..maxRank);
end

function SlamAndAwe:DebugFrameValues()
	self:Print("CSLen : "..SlamAndAwe.db.char.CSLen)
	self:Print("CSPercent : "..SlamAndAwe.db.char.CSPercent)
	self:Print("DCLen : "..SlamAndAwe.db.char.DCLen)
	self:Print("DCPercent : "..SlamAndAwe.db.char.DCPercent)
end

function SlamAndAwe:GCDBar()
	local startTime, duration, enabled = GetSpellCooldown(SlamAndAwe.constants["Execute"]) -- Battle Shout because fury has it and demo is gone
	duration = duration or 0 -- force nil to 0 if for some bizzare reason no LS available.
	if duration > 0 then 
		self.frames["GCD"]:Show()
		updateActiveGCD = true
		GCDTime = startTime + duration
		self.GCDMax = duration
	end
end

function SlamAndAwe:RageBar()
  if not SlamAndAwe.db.char.disabled then
    if SlamAndAwe.db.char.rageshow then
          RageMin, RageMax = self.frames["Rage"].statusbar:GetMinMaxValues()
		  if SlamAndAwe.db.char.hideRageBarOOC then
			  if UnitAffectingCombat("player") then
				self.frames["Rage"]:Show()
				updateActiveRage = true
				else 
				self.frames["Rage"]:Hide()
			  end
			else
	--		  if UnitPower("player", "rage") > 0 then -- not sure why we were hiding rage bar with 0 rage, when you use shield barrier the bar would hide??
				self.frames["Rage"]:Show()
				updateActiveRage = true
	--			else 
	--			self.frames["Rage"]:Hide()
	--		  end
			end
      end
   end
end

function SlamAndAwe:TasteForBloodBar()
	if SlamAndAwe.db.char.tfbshow and not SlamAndAwe.db.char.disabled then
		local colours = SlamAndAwe.db.char.colours.tfb
		self.frames["TasteForBlood"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, SlamAndAwe.db.char.colours.tfbalpha)
	    self.frames["TasteForBlood"]:SetBackdropBorderColor( 1, 1, 1, SlamAndAwe.db.char.colours.tfbalpha); --was msalpha
		self.frames["TasteForBlood"].spark:Show()
		self.frames["TasteForBlood"]:Show()
		self.frames["TasteForBlood"].text:SetPoint("CENTER",self.frames["TasteForBlood"].statusbar,"LEFT",34,-1)
		if SlamAndAwe.db.char.showicons then
			self.frames["TasteForBlood"].icon:Show()
		else
			self.frames["TasteForBlood"].icon:Hide()
		end
	end
	updateActiveMaelstrom = true
    tfbMin, tfbMax = self.frames["TasteForBlood"].statusbar:GetMinMaxValues() -- MaelstromMin MaelstromMax	
end

function SlamAndAwe:ColossusSmashBar()
	local colours = SlamAndAwe.db.char.colours.colossussmash
	self.frames["ColossusSmash"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
	if SlamAndAwe.db.char.enableTimeRemaining then
		self.frames["ColossusSmash"].text2:SetTextColor(1, 1, 1, 1)
	end
	self.frames["ColossusSmash"]:Show()
	updateActiveColossusSmash = true
	CSTime = GetTime() + SlamAndAwe.db.char.CSLen
	CSMin, CSMax = self.frames["ColossusSmash"].statusbar:GetMinMaxValues()
	if SlamAndAwe.db.char.showicons then
		self.frames["ColossusSmash"].icon:Show()
	else
		self.frames["ColossusSmash"].icon:Hide()
	end
end

function SlamAndAwe:RecklessnessBar()
	local colours = SlamAndAwe.db.char.colours.recklessness
	self.frames["Recklessness"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
	if SlamAndAwe.db.char.enableTimeRemaining then
		self.frames["Recklessness"].text2:SetTextColor(1, 1, 1, 1)
	end
	self.frames["Recklessness"]:Show()
	updateActiveRecklessness = true
	RETime = GetTime() + SlamAndAwe.db.char.RELen
	REMin, REMax = self.frames["Recklessness"].statusbar:GetMinMaxValues()
	if SlamAndAwe.db.char.showicons then
		self.frames["Recklessness"].icon:Show()
	else
		self.frames["Recklessness"].icon:Hide()
	end
end

function SlamAndAwe:DeadlyCalmBar()
	local colours = SlamAndAwe.db.char.colours.deadlycalm
	self.frames["DeadlyCalm"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
	if SlamAndAwe.db.char.enableTimeRemaining then
		self.frames["DeadlyCalm"].text2:SetTextColor(1, 1, 1, 1)
	end
	self.frames["DeadlyCalm"]:Show()
	updateActiveDeadlyCalm = true
	DCTime = GetTime() + SlamAndAwe.db.char.DCLen
	DCMin, DCMax = self.frames["DeadlyCalm"].statusbar:GetMinMaxValues()
	if SlamAndAwe.db.char.showicons then
		self.frames["DeadlyCalm"].icon:Show()
	else
		self.frames["DeadlyCalm"].icon:Hide()
	end
end

function SlamAndAwe:SweepingStrikesBar()
	local colours = SlamAndAwe.db.char.colours.sweepingstrikes
	self.frames["SweepingStrikes"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
	if SlamAndAwe.db.char.enableTimeRemaining then
		self.frames["SweepingStrikes"].text2:SetTextColor(1, 1, 1, 1)
	end
	self.frames["SweepingStrikes"]:Show()
	updateActiveSweepingStrikes = true
	SWSTTime = GetTime() + SlamAndAwe.db.char.SWSTLen
	SWSTMin, SWSTMax = self.frames["SweepingStrikes"].statusbar:GetMinMaxValues()
	if SlamAndAwe.db.char.showicons then
		self.frames["SweepingStrikes"].icon:Show()
	else
		self.frames["SweepingStrikes"].icon:Hide()
	end
end
--------------------------------------------------------------------
--Protection Bars
--------------------------------------------------------------------

function SlamAndAwe:ShieldBarrierBar()
  local colours = SlamAndAwe.db.char.colours.shieldbarrier
	self.frames["ShieldBarrier"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
	self.frames["ShieldBarrier"].text2:SetTextColor(1, 1, 1, 1)
	self.frames["ShieldBarrier"]:Show()
	updateActiveShieldBarrier = true
	SBTime = GetTime() + SlamAndAwe.db.char.SBLen
	SBMin, SBMax = self.frames["ShieldBarrier"].statusbar:GetMinMaxValues()
	          	
	if SlamAndAwe.db.char.showicons then
		self.frames["ShieldBarrier"].icon:Show()
	else	
		self.frames["ShieldBarrier"].icon:Hide()
	end
end

function SlamAndAwe:UpdateShieldBarrierText(Active)
    if SlamAndAwe.db.char.currentspec == "Protection" then
      if Active then
        	self.frames["ShieldBarrier"].text:SetText(SB_Current)
          self.frames["ShieldBarrier"].text:SetPoint("LEFT",self.frames["ShieldBarrier"].statusbar,"LEFT",20,-1)
          SBLast = SB_Current
       else
          self.frames["ShieldBarrier"].text:SetText("0")
          self.frames["ShieldBarrier"].text:SetPoint("LEFT",self.frames["ShieldBarrier"].statusbar,"LEFT",20,-1)
          self.frames["ShieldBarrier"].statusbar:SetValue("0")
          self.frames["ShieldBarrier"].spark:SetPoint("CENTER",self.frames["ShieldBarrier"].statusbar,"LEFT", 0 ,-1)
       end
     end
end

function SlamAndAwe:UpdateEstimatedShieldBarrierText(Value)
              if not SB_Current or SB_Current <= Value then
                             self.frames["ShieldBarrier"].text2:SetTextColor(0, 1, 0, 1)        
              else
                        self.frames["ShieldBarrier"].text2:SetTextColor(1, 1, 1, 1)
              end              
        	self.frames["ShieldBarrier"].text2:SetText(Value)
            self.frames["ShieldBarrier"].text2:SetPoint("CENTER",self.frames["ShieldBarrier"].statusbar,"RIGHT",-40,-1)

end

function SlamAndAwe:ShieldBlockBar()
	local colours = SlamAndAwe.db.char.colours.shieldblock
	self.frames["ShieldBlock"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
	if SlamAndAwe.db.char.enableTimeRemaining then
		self.frames["ShieldBlock"].text2:SetTextColor(1, 1, 1, 1)
	end

	if SBlTime > GetTime() then -- sheild block is already up, need to append the current duration with new duration
		SBlTime = SBlTime + 6
		SBlMax = SBlTime - GetTime()
		SBlMin = 0
		self.frames["ShieldBlock"].statusbar:SetMinMaxValues(0,SBlMax)
	else
		self.frames["ShieldBlock"].statusbar:SetMinMaxValues(0,SlamAndAwe.db.char.SBlLen)
		SBlTime = GetTime() + SlamAndAwe.db.char.SBlLen
		SBlMin, SBlMax = self.frames["ShieldBlock"].statusbar:GetMinMaxValues()
	end	
	
	self.frames["ShieldBlock"]:Show()
	updateActiveShieldBlock = true	
	
	if SlamAndAwe.db.char.showicons then
		self.frames["ShieldBlock"].icon:Show()
	else
		self.frames["ShieldBlock"].icon:Hide()
	end
end


function SlamAndAwe:ShieldWallBar()
	local colours = SlamAndAwe.db.char.colours.shieldwall
	self.frames["ShieldWall"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
	if SlamAndAwe.db.char.enableTimeRemaining then
		self.frames["ShieldWall"].text2:SetTextColor(1, 1, 1, 1)
	end
	self.frames["ShieldWall"]:Show()
	updateActiveShieldWall = true
	SWTime = GetTime() + SlamAndAwe.db.char.SWLen
	SWMin, SWMax = self.frames["ShieldWall"].statusbar:GetMinMaxValues()
	if SlamAndAwe.db.char.showicons then
		self.frames["ShieldWall"].icon:Show()
	else
		self.frames["ShieldWall"].icon:Hide()
	end
end

function SlamAndAwe:DemoShoutBar()
	local colours = SlamAndAwe.db.char.colours.demoshout
	self.frames["DemoShout"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
	if SlamAndAwe.db.char.enableTimeRemaining then
		self.frames["DemoShout"].text2:SetTextColor(1, 1, 1, 1)
	end
	self.frames["DemoShout"]:Show()
	updateActiveDemoShout = true
	DemoShoutTime = GetTime() + SlamAndAwe.db.char.DSLen 
	DemoShoutMin, DemoShoutMax = self.frames["DemoShout"].statusbar:GetMinMaxValues()
	if SlamAndAwe.db.char.showicons then
		self.frames["DemoShout"].icon:Show()
	else
		self.frames["DemoShout"].icon:Hide()
	end
end

function SlamAndAwe:LastStandBar()
	local colours = SlamAndAwe.db.char.colours.laststand
	self.frames["LastStand"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
	if SlamAndAwe.db.char.enableTimeRemaining then
		self.frames["LastStand"].text2:SetTextColor(1, 1, 1, 1)
	end
	self.frames["LastStand"]:Show()
	updateActiveLastStand = true
	LastStandTime = GetTime() + SlamAndAwe.db.char.LSLen 
	LastStandMin, LastStandMax = self.frames["LastStand"].statusbar:GetMinMaxValues()
	if SlamAndAwe.db.char.showicons then
		self.frames["LastStand"].icon:Show()
	else
		self.frames["LastStand"].icon:Hide()
	end
end

function SlamAndAwe:RallyingCryBar()
	local colours = SlamAndAwe.db.char.colours.rallyingcry
	self.frames["RallyingCry"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
	if SlamAndAwe.db.char.enableTimeRemaining then
		self.frames["RallyingCry"].text2:SetTextColor(1, 1, 1, 1)
	end
	self.frames["RallyingCry"]:Show()
	updateActiveRallyingCry = true
	RallyingCryTime = GetTime() + SlamAndAwe.db.char.RCLen 
	RallyingCryMin, RallyingCryMax = self.frames["RallyingCry"].statusbar:GetMinMaxValues()
	if SlamAndAwe.db.char.showicons then
		self.frames["RallyingCry"].icon:Show()
	else
		self.frames["RallyingCry"].icon:Hide()
	end
end
--------------------------------------------------------------------
--------------------------------------------------------------------

function SlamAndAwe:DebugDebuffInfo()
	local index = 1
	while UnitDebuff("target", index) do
		local name, _, _, count, _, _, debuffExpires, unitCaster = UnitDebuff("target", index)
		local isMine = unitCaster == "player" 
		local expires = debuffExpires-GetTime()
		if isMine then
			self:DebugPrint("Debuff :"..name.." expires:"..expires)
		end
		index = index + 1
	end
end

function SlamAndAwe:DebugBuffInfo()
	local index = 1
	while UnitBuff("player", index) do
		local name, _, _, count, _, _, buffExpires = UnitBuff("player", index)
			local duration = buffExpires - GetTime()
		  self:DebugPrint("Buff :"..name.." expires:"..buffExpires.." duration:"..duration.." count:"..count)
		index = index + 1
	end
end


function SlamAndAwe:DurationString(duration)
    local string = (("%1.1f"):format(duration % 60)) .. "s";
    
    if (duration >= 60) then
        duration = floor(duration - (duration % 60)) / 60; -- minutes
        
        string = (duration % 60) .."m " .. string;
        
        if (duration >= 60) then
            duration = (duration - (duration % 60)) / 60; -- hours
            string = duration .. "h " .. string;
        end
    end
    return string
end

function SlamAndAwe:CheckPurgeableBuff()
	if SlamAndAwe.db.char.hsshow then
     local avail = SlamAndAwe:SpellAvailable(SlamAndAwe.constants["Heroic Strike"])
     local usable, nomana = IsUsableSpell(SlamAndAwe.constants["Heroic Strike"])
     local buff1 = SlamAndAwe:GetBuffInfo(SlamAndAwe.constants["Battle Trance"])
     local buff2 = SlamAndAwe:GetBuffInfo(SlamAndAwe.constants["Incite"])    		
     local rage = UnitPower("player", "rage")
		local hsrage = SlamAndAwe.db.char.rageThreshold
		
		if buff1 or buff2 then
      if usable and avail then
        return true
      end     
    elseif rage >= hsrage then
        if usable and avail then
						return true
        end
		end
	end
	return false
end

local OBU = {}

function SlamAndAwe:OnBarUpdate()
	if SlamAndAwe.db.char.disabled then
		return
	end
	
	OBU.width = SlamAndAwe.db.char.fWidth - 6
	OBU.timeLeft = 0
	
	if updateActiveRage then
	 local crage = UnitPower("player", "rage")
	 
	 if SlamAndAwe.db.char.currentspec == "Protection" then
      local colours = SlamAndAwe.db.char.colours.rage
      --(colours.r, colours.g, colours.b, colours.a)
      if crage >= 60 then
        self.frames["Rage"].statusbar:SetStatusBarColor(0, 1, 0, colours.a)
      else
        self.frames["Rage"].statusbar:SetStatusBarColor(colours.r, colours.g, colours.b, colours.a)
      end
    end
		self.frames["Rage"].statusbar:SetValue(crage)
		self.frames["Rage"].spark:SetPoint("CENTER",self.frames["Rage"].statusbar,"LEFT", crage / SlamAndAwe.db.char.ragecap * OBU.width * SlamAndAwe.db.char.REPercent ,-1)
		self.frames["Rage"].text:SetText(UnitPower('player'))
		self.frames["Rage"].text:SetPoint("LEFT",self.frames["Rage"].statusbar,"LEFT",20,-1)
	end	

	if updateActiveGCD then
		OBU.timeLeft = GCDTime - GetTime()
		self.frames["GCD"].statusbar:SetValue(OBU.timeLeft)
		OBU.sparkpoint = OBU.timeLeft / 1.5 * self.GCDWidth
		if OBU.sparkpoint > self.GCDWidth then
			OBU.sparkpoint = self.GCDWidth
		end
		self.frames["GCD"].spark:SetPoint("CENTER",self.frames["GCD"].statusbar,"LEFT", OBU.sparkpoint,-1)
		if GCDTime < GetTime() then
			self.frames["GCD"]:Hide()
			updateActiveGCD = false
		end
	end
	
	if updateActiveTasteForBlood then
		SlamAndAwe.db.char.tfbstacks, OBU.tfbTime = self:GetTasteForBloodInfo()
		OBU.timeLeft = OBU.tfbTime - GetTime()		
		
		if SlamAndAwe.db.char.tfbstacks ~= 4 then
			tfb4played = false
		end
		if SlamAndAwe.db.char.tfbstacks == 5 then
			if SlamAndAwe.db.char.tfb5soundplay and InCombatLockdown() then
				if SlamAndAwe.db.char.tfb5sound and lastSound < GetTime() - SlamAndAwe.db.char.tfb5repeat then
					PlaySoundFile(SlamAndAwe.db.char.tfb5sound)
					lastSound = GetTime()
				end
			end
		else
			if SlamAndAwe.db.char.tfbstacks == 4 and SlamAndAwe.db.char.tfb4soundplay and not tfb4played and InCombatLockdown() then
				PlaySoundFile(SlamAndAwe.db.char.tfb4sound)
				tfb4played = true
			end
		end		
		if SlamAndAwe.db.char.tfbshow then
			if SlamAndAwe.db.char.tfbstacks == 5 then
				self:SetTasteForBloodAlpha(SlamAndAwe.db.char.colours.tfbalphaFull)
				if SlamAndAwe.db.char.tfb5flash then
					UIFrameFlash(self.frames["TasteForBlood"], 0.25, 0.25, 30, true, 0.25, 0.25)
					if SlamAndAwe.db.char.showicons then
						UIFrameFlash(self.frames["TasteForBlood"].icon, 0.25, 0.25, 30, true, 0.25, 0.25)
					end
					tfbflashing = true
				end
			else
				if tfbflashing then
					tfbflashing = false
				end
				UIFrameFlashStop(self.frames["TasteForBlood"])
				self:SetTasteForBloodAlpha(SlamAndAwe.db.char.colours.tfbalpha)
				
				if SlamAndAwe.db.char.showicons then
					UIFrameFlashStop(self.frames["TasteForBlood"].icon)
				end
			end		
		
			self.frames["TasteForBlood"].statusbar:SetValue(OBU.timeLeft)
			self.frames["TasteForBlood"].spark:SetPoint("CENTER",self.frames["TasteForBlood"].statusbar,"LEFT", OBU.timeLeft/tfbMax * OBU.width * SlamAndAwe.db.char.TFBPercent,-1)		
			if OBU.tfbTime < GetTime() or SlamAndAwe.db.char.tfbstacks == 0 then
				self.frames["TasteForBlood"]:Hide()
				self.frames["TasteForBlood"].icon:Hide()
			else
				self.frames["TasteForBlood"]:Show()
				if SlamAndAwe.db.char.showicons then
					self.frames["TasteForBlood"].icon:Show()
				end
			end
		else
			self.frames["TasteForBlood"]:Hide()
			self.frames["TasteForBlood"].icon:Hide()
		end
		if OBU.tfbTime < GetTime() then
			self.frames["TasteForBlood"]:Hide()
			self.frames["TasteForBlood"].icon:Hide()
			if tfbflashing then
				UIFrameFlashStop(self.frames["TasteForBlood"])
				if SlamAndAwe.db.char.showicons then
					UIFrameFlashStop(self.frames["TasteForBlood"].icon)
				end
				self:SetTasteForBloodAlpha(SlamAndAwe.db.char.colours.tfbalpha)
				tfbflashing = false
			end
			updateActiveTasteForBlood = false
		end
	end
	
	
	if updateActiveColossusSmash then
		OBU.timeLeft = CSTime - GetTime()
		self.frames["ColossusSmash"].statusbar:SetValue(OBU.timeLeft)
		self.frames["ColossusSmash"].spark:SetPoint("CENTER",self.frames["ColossusSmash"].statusbar,"LEFT", OBU.timeLeft/CSMax * OBU.width * SlamAndAwe.db.char.CSPercent ,-1)
		if SlamAndAwe.db.char.enableTimeRemaining then
			self.frames["ColossusSmash"].text:SetText(round(CSTime - GetTime(),0))
			self.frames["ColossusSmash"].text:SetPoint("LEFT",self.frames["ColossusSmash"].statusbar,"LEFT",20,-1)
		end
		if CSTime < GetTime() then
			self.frames["ColossusSmash"]:Hide()
			self.frames["ColossusSmash"].icon:Hide()
			updateActiveColossusSmash = false
		end
	end
	
	if updateActiveRecklessness then
		OBU.timeLeft = RETime - GetTime()
		self.frames["Recklessness"].statusbar:SetValue(OBU.timeLeft)
		self.frames["Recklessness"].spark:SetPoint("CENTER",self.frames["Recklessness"].statusbar,"LEFT", OBU.timeLeft/REMax * OBU.width * SlamAndAwe.db.char.REPercent ,-1)
		if SlamAndAwe.db.char.enableTimeRemaining then	
			self.frames["Recklessness"].text:SetText(round(RETime - GetTime(),0))
			self.frames["Recklessness"].text:SetPoint("LEFT",self.frames["Recklessness"].statusbar,"LEFT",20,-1)
		end
		if RETime < GetTime() then
			self.frames["Recklessness"]:Hide()
			self.frames["Recklessness"].icon:Hide()
			updateActiveRecklessness = false
		end
	end
	
	if updateActiveDeadlyCalm then
		OBU.timeLeft = DCTime - GetTime()
		self.frames["DeadlyCalm"].statusbar:SetValue(OBU.timeLeft)
		self.frames["DeadlyCalm"].spark:SetPoint("CENTER",self.frames["DeadlyCalm"].statusbar,"LEFT", OBU.timeLeft/DCMax * OBU.width * SlamAndAwe.db.char.DCPercent ,-1)
		if SlamAndAwe.db.char.enableTimeRemaining then
			self.frames["DeadlyCalm"].text:SetText(round(DCTime - GetTime(),0))
			self.frames["DeadlyCalm"].text:SetPoint("LEFT",self.frames["DeadlyCalm"].statusbar,"LEFT",20,-1)
		end
		if DCTime < GetTime() then
			self.frames["DeadlyCalm"]:Hide()
			self.frames["DeadlyCalm"].icon:Hide()
			updateActiveDeadlyCalm = false
		end
	end
	
		if updateActiveSweepingStrikes then
		OBU.timeLeft = SWSTTime - GetTime()
		self.frames["SweepingStrikes"].statusbar:SetValue(OBU.timeLeft)
		self.frames["SweepingStrikes"].spark:SetPoint("CENTER",self.frames["SweepingStrikes"].statusbar,"LEFT", OBU.timeLeft/SWSTMax * OBU.width * SlamAndAwe.db.char.SWSTPercent ,-1)
		if SlamAndAwe.db.char.enableTimeRemaining then
			self.frames["SweepingStrikes"].text:SetText(round(SWSTTime - GetTime(),0))
			self.frames["SweepingStrikes"].text:SetPoint("LEFT",self.frames["SweepingStrikes"].statusbar,"LEFT",20,-1)
		end
		if SWSTTime < GetTime() then
			self.frames["SweepingStrikes"]:Hide()
			self.frames["SweepingStrikes"].icon:Hide()
			updateActiveSweepingStrikes = false
		end
	end
	
	-----------------------------------------------------------------------------
	--Protection
	-----------------------------------------------------------------------------
	


	if updateActiveShieldBarrier then
			if not SB_Current then
    --    self.frames["ShieldBarrier"]:Hide()
     --   self.frames["ShieldBarrier"].icon:Hide()
        updateActiveShieldBarrier = false
        SBActive = false
        SBLast = 0
        self:UpdateShieldBarrierText(false)
      else
          OBU.timeLeft = SBTime - GetTime()
          self.frames["ShieldBarrier"].statusbar:SetValue(OBU.timeLeft)
          self.frames["ShieldBarrier"].spark:SetPoint("CENTER",self.frames["ShieldBarrier"].statusbar,"LEFT", OBU.timeLeft/SBMax * OBU.width * SlamAndAwe.db.char.SBPercent ,-1)
        	self.frames["ShieldBarrier"].text:SetText(SB_Current)
          self.frames["ShieldBarrier"].text:SetPoint("LEFT",self.frames["ShieldBarrier"].statusbar,"LEFT",20,-1)

          SBActive = true
          SBLast = SB_Current
          if SBTime < GetTime() then
      --      self.frames["ShieldBarrier"]:Hide()
      --      self.frames["ShieldBarrier"].icon:Hide()
            updateActiveShieldBarrier = false --this was updateActiveShieldBlock.. typo maybe?
            SBActive = false
            SBLast = 0   
            self:UpdateShieldBarrierText(false)   
        end
      end  
   end
    
  if updateActiveShieldBlock then
		OBU.timeLeft = SBlTime - GetTime()
		self.frames["ShieldBlock"].statusbar:SetValue(OBU.timeLeft)
		self.frames["ShieldBlock"].spark:SetPoint("CENTER",self.frames["ShieldBlock"].statusbar,"LEFT", OBU.timeLeft/SBlMax * OBU.width * SlamAndAwe.db.char.SBlPercent ,-1)
		if SlamAndAwe.db.char.enableTimeRemaining then
		self.frames["ShieldBlock"].text:SetText(round(SBlTime - GetTime(),0))
		self.frames["ShieldBlock"].text:SetPoint("LEFT",self.frames["ShieldBlock"].statusbar,"LEFT",20,-1)
		end
		if SBlTime < GetTime() then 
			self.frames["ShieldBlock"]:Hide()
			self.frames["ShieldBlock"].icon:Hide()
			updateActiveShieldBlock = false
		end
	end 
	
	
	if updateActiveShieldWall then
		OBU.timeLeft = SWTime - GetTime()
		self.frames["ShieldWall"].statusbar:SetValue(OBU.timeLeft)
		self.frames["ShieldWall"].spark:SetPoint("CENTER",self.frames["ShieldWall"].statusbar,"LEFT", OBU.timeLeft/SWMax * OBU.width * SlamAndAwe.db.char.SWPercent ,-1)
		if SlamAndAwe.db.char.enableTimeRemaining then
			self.frames["ShieldWall"].text:SetText(round(SWTime - GetTime(),0))
			self.frames["ShieldWall"].text:SetPoint("LEFT",self.frames["ShieldWall"].statusbar,"LEFT",20,-1)
		end
		if SWTime < GetTime() then
			self.frames["ShieldWall"]:Hide()
			self.frames["ShieldWall"].icon:Hide()
			updateActiveShieldWall = false
		end
	end 
	
	if updateActiveDemoShout then
		OBU.timeLeft = DemoShoutTime - GetTime()
		self.frames["DemoShout"].statusbar:SetValue(OBU.timeLeft)
		self.frames["DemoShout"].spark:SetPoint("CENTER",self.frames["DemoShout"].statusbar,"LEFT", OBU.timeLeft/DemoShoutMax * OBU.width ,-1)
		if SlamAndAwe.db.char.enableTimeRemaining then		
			self.frames["DemoShout"].text:SetText(round(DemoShoutTime - GetTime(),0))
			self.frames["DemoShout"].text:SetPoint("LEFT",self.frames["DemoShout"].statusbar,"LEFT",20,-1)
		end
		if DemoShoutTime < GetTime() then
			self.frames["DemoShout"]:Hide()
			self.frames["DemoShout"].icon:Hide()
			updateActiveDemoShout = false
		end
	end 
	
	if updateActiveLastStand then
		OBU.timeLeft = LastStandTime - GetTime()
		self.frames["LastStand"].statusbar:SetValue(OBU.timeLeft)
		self.frames["LastStand"].spark:SetPoint("CENTER",self.frames["LastStand"].statusbar,"LEFT", OBU.timeLeft/LastStandMax * OBU.width ,-1)
		if SlamAndAwe.db.char.enableTimeRemaining then
			self.frames["LastStand"].text:SetText(round(LastStandTime - GetTime(),0))
			self.frames["LastStand"].text:SetPoint("LEFT",self.frames["LastStand"].statusbar,"LEFT",20,-1)
		end
		if LastStandTime < GetTime() then
			self.frames["LastStand"]:Hide()
			self.frames["LastStand"].icon:Hide()
			updateActiveLastStand = false
		end
	end 
	
	if updateActiveRallyingCry then
		OBU.timeLeft = RallyingCryTime - GetTime()
		self.frames["RallyingCry"].statusbar:SetValue(OBU.timeLeft)
		self.frames["RallyingCry"].spark:SetPoint("CENTER",self.frames["RallyingCry"].statusbar,"LEFT", OBU.timeLeft/RallyingCryMax * OBU.width ,-1)
		if SlamAndAwe.db.char.enableTimeRemaining then
			self.frames["RallyingCry"].text:SetText(round(RallyingCryTime - GetTime(),0))
			self.frames["RallyingCry"].text:SetPoint("LEFT",self.frames["RallyingCry"].statusbar,"LEFT",20,-1)
		end
		if RallyingCryTime < GetTime() then
			self.frames["RallyingCry"]:Hide()
			self.frames["RallyingCry"].icon:Hide()
			updateActiveRallyingCry = false
		end
	end 
	
	
	--Announcements
	
	if updateActiveBanner then
		if BannerTime < GetTime() then
			SlamAndAwe:Announce( last_banner_where , last_banner_msg)
			updateActiveBanner = false
		end
	end 
	
	
	-----------------------------------------------------------------------------
	--
	-----------------------------------------------------------------------------
	
	if SlamAndAwe.db.char.priority.show and not SlamAndAwe.db.char.disabled then
		if SlamAndAwe.db.char.priority.showinterrupt and self.PriorityFrame.interrupt then
			OBU.EnemySpell, _, _, OBU.EnemySpellIcon = UnitCastingInfo("target")
			if not OBU.EnemySpell then
				OBU.EnemySpellIcon = "Interface/Tooltips/UI-Tooltip-Background"
			end
			local nStance = GetShapeshiftForm();
			if self:SpellAvailable(SlamAndAwe.constants["Pummel"])  then
				self:SetSubFrameBackdrop(self.PriorityFrame.interrupt.frame, OBU.EnemySpellIcon, 4)
				self.PriorityFrame.purge.frame:SetBackdropBorderColor(1, 1, 1, 1);
			else
				self:SetSubFrameBackdrop(self.PriorityFrame.interrupt.frame, OBU.EnemySpellIcon, 20)
				self.PriorityFrame.purge.frame:SetBackdropBorderColor(1, 0, 0, 1); -- set border colour to Red if Purge not available
			end
			if not OBU.EnemySpell then
				self.PriorityFrame.purge.frame:SetBackdropColor(0, 0, 0, 0);
			end
		end
	end
end

function SlamAndAwe:CreateMsgFrame()
	self.msgFrame:ClearAllPoints()
	self.msgFrame:SetWidth(400)
	self.msgFrame:SetHeight(75)

	self.msgFrame:SetBackdrop({
		bgFile = "Interface/Tooltips/UI-Tooltip-Background",
		--edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
		tile = false, tileSize = 0, edgeSize = 12,
		insets = { left = 2, right = 2, top = 2, bottom = 2 }
	})
	self.msgFrame:SetBackdropColor(1, 1, 1, 0)
	self.msgFrame:SetMovable(true)
	self.msgFrame:RegisterForDrag("LeftButton")
	self.msgFrame:SetScript("OnDragStart", 
		function()
			self.msgFrame:StartMoving();
		end );
	self.msgFrame:SetScript("OnDragStop",
		function()
			self.msgFrame:StopMovingOrSizing();
			self.msgFrame:SetScript("OnUpdate", nil);
			self:FinishedMoving(SlamAndAwe.db.char.warning, self.msgFrame);
		end );
	self.msgFrame:SetPoint(SlamAndAwe.db.char.warning.point, SlamAndAwe.db.char.warning.relativeTo, SlamAndAwe.db.char.warning.relativePoint, SlamAndAwe.db.char.warning.xOffset, SlamAndAwe.db.char.warning.yOffset)
	self.msgFrame:SetInsertMode("TOP")
	self.msgFrame:SetFrameStrata(SlamAndAwe.db.char.framestratalevel)
	self.msgFrame:SetToplevel(true)
	local font = media:Fetch("font", SlamAndAwe.db.char.msgfont)
	self.msgFrame:SetFont(font, SlamAndAwe.db.char.msgfontsize, SlamAndAwe.db.char.msgfonteffect)
		
	self.msgFrame:Show()
end

function SlamAndAwe:PrintMsg(msg, col, time)
	if SlamAndAwe.db.char.warning.show and not SlamAndAwe.db.char.disabled then
		if col == nil then
			col = { r=1, b=1, g=1, a=1 }
		end
		if time == nil then 
			time = 3
		end
		if time ~= 5 then
			self.msgFrame:SetTimeVisible(time)
		end
		self.msgFrame:AddMessage(msg, col.r, col.g, col.b, 1, col.time)
	end
end

function SlamAndAwe:DebugPrint(msg)
	if SlamAndAwe.db.char.debug then
		self:Print(msg)
	end
end

function round(number, decimals)
    return (("%%.%df"):format(decimals)):format(number)
end
