changeset 2:f2456f1454af

rewrite
author tercio
date Sun, 01 Jun 2014 03:48:11 -0300
parents 726745261b87
children 1c0f88ab78b7
files PVPScan.lua PVPScan.xml libs.xml
diffstat 3 files changed, 356 insertions(+), 128 deletions(-) [+]
line wrap: on
line diff
--- a/PVPScan.lua	Mon May 19 05:50:51 2014 -0300
+++ b/PVPScan.lua	Sun Jun 01 03:48:11 2014 -0300
@@ -1,11 +1,12 @@
 
-PVPScan = LibStub ("AceAddon-3.0"):NewAddon ("PVPScan", "AceConsole-3.0", "AceEvent-3.0")
+PVPScan = LibStub ("AceAddon-3.0"):NewAddon ("PVPScan", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0")
 
 local LDB = LibStub ("LibDataBroker-1.1", true)
 local LDBIcon = LDB and LibStub ("LibDBIcon-1.0", true)
 local SharedMedia = LibStub:GetLibrary("LibSharedMedia-3.0")
 
 local _bit_band = bit.band
+local GetTime = GetTime
 
 local REACTION_HOSTILE = 0x00000040
 local REACTION_NEUTRAL = 0x00000020
@@ -23,6 +24,10 @@
 		SpotBarHeight = 20,
 		SpotBarAmount = 5,
 		SpotBarWidth = 150,
+		SpotBarTexture = "Blizzard Character Skills Bar",
+		SpotBarTimeOut = 10,
+		SpotBarCooldown = 5,
+		SpotBarPlayerCooldown = 10,
 		Locked = false,
 		SoundPlay = false,
 		SoundFile = "",
@@ -73,11 +78,37 @@
 			set = function (self, val) PVPScan.db.profile.SpotBarAmount = val; PVPScan:RefreshSpotBars() end,
 			order = 3,
 		},
+		SpotBarTexture = {
+			type = "select",
+			name = "Bar Texture",
+			desc = "Choose the texture used on target bars.",
+			values = function()
+					local TextureTable = {}
+					for name, _ in pairs (SharedMedia:HashTable ("statusbar")) do 
+						TextureTable [name] = name
+					end
+					return TextureTable
+				end,
+			get = function() return PVPScan.db.profile.SpotBarTexture end,
+			set = function (self, file) PVPScan.db.profile.SpotBarTexture = file; PVPScan:RefreshSpotBars() end,
+			order = 4,
+		},
+		SpotBarTimeOut = {
+			type = "range",
+			name = "Time Out", 
+			desc = "How many time wait until the bar auto hide.",
+			min = 5,
+			max = 120,
+			step = 5,
+			get = function() return PVPScan.db.profile.SpotBarTimeOut end,
+			set = function (self, val) PVPScan.db.profile.SpotBarTimeOut = val; end,
+			order = 9,
+		},
 		Locked = {
 			type = "toggle",
 			name = "Lock Scan Frame",
 			desc = "Lock or unlock the SpotBars Frame.",
-			order = 4,
+			order = 5,
 			get = function() return PVPScan.db.profile.Locked end,
 			set = function (self, val) PVPScan.db.profile.Locked = not PVPScan.db.profile.Locked; PVPScan:LockScanFrame (PVPScan.db.profile.Locked) end,
 		},
@@ -85,7 +116,7 @@
 			type = "toggle",
 			name = "Play Sound",
 			desc = "Play a sound when a enemy is found.",
-			order = 5,
+			order = 7,
 			get = function() return PVPScan.db.profile.SoundPlay end,
 			set = function (self, val) PVPScan.db.profile.SoundPlay = not PVPScan.db.profile.SoundPlay end,
 		},
@@ -102,13 +133,13 @@
 				end,
 			get = function() return PVPScan.db.profile.SoundFile end,
 			set = function (self, file) PVPScan.db.profile.SoundFile = file end,
-			order = 6,
+			order = 8,
 		},
 		Minimap = {
 			type = "toggle",
 			name = "Hide Minimap Icon",
 			desc = "Show or hide the minimap icon.",
-			order = 7,
+			order = 6,
 			get = function() return PVPScan.db.profile.Minimap.hide end,
 			set = function (self, val) 
 				PVPScan.db.profile.Minimap.hide = not PVPScan.db.profile.Minimap.hide
@@ -153,6 +184,8 @@
 	
 	PVPScan:RefreshSpotBars()
 	PVPScan:LockScanFrame (PVPScan.db.profile.Locked)
+	
+	PVPScan.EventFrame:SetScript ("OnEvent", PVPScan.OnParserEvent)
 end
 
 PVPScan:RegisterChatCommand ("pvpscan", function() 
@@ -207,11 +240,17 @@
 function PVPScan:EnableScan()
 	PVPScan.EventFrame:RegisterEvent ("COMBAT_LOG_EVENT_UNFILTERED")
 	PVPScan:RefreshSpotBars()
+	PVPScan.NextBarCheckForHide = GetTime() + PVPScan.db.profile.SpotBarTimeOut
+	PVPScan.BarChecker = PVPScan:ScheduleRepeatingTimer ("CheckBarTimeOut", 5)
 end
 
 function PVPScan:DisableScan()
 	PVPScan.EventFrame:UnregisterEvent ("COMBAT_LOG_EVENT_UNFILTERED")
 	PVPScan:RefreshSpotBars()
+	if (PVPScan.BarChecker) then
+		PVPScan:CancelTimer (PVPScan.BarChecker, true)
+		PVPScan.BarChecker = nil
+	end
 end
 
 function PVPScan:LockScanFrame (IsLocked)
@@ -231,17 +270,12 @@
 
 	--> parser
 
-	PVPScan.SpotBars = {}
-	PVPScan.NeedClass = {}
-	PVPScan.NextSpotBar = 1
+	PVPScan.SpotBars = {} -- container para os objetos das barras
+
+	PVPScan.NeedClass = {} -- container para os jogadores que precisam saber a classe
+	PVPScan.CurrentShownPlayers = {} -- nomes dos jogadores que estão sendo mostrados com o index da barra no valos
+	PVPScan.CooldownShownPlayers = {} -- nomes dos jogadores com o tempo de quando eles podem ser mostrados novamente nas barras
 	
-	local CurrentShownIndex = {}
-	local CurrentShownHash = {}
-	local CurrentShownTime = {}
-	local NeutralCandidate = {}
-	
-	local find_neutral_players = false
-
 	PVPScan.EventFrame = CreateFrame ("frame", "PVPScanCombatLobReader", UIParent)
 	PVPScan.EventFrame:RegisterEvent ("COMBAT_LOG_EVENT_UNFILTERED")
 
@@ -250,7 +284,7 @@
 		if (PVPScan.NeedClass [who_name]) then
 			local class = PVPScan:GuessClass (...)
 			if (class) then
-				PVPScan:UpdateBar (PVPScan.NeedClass [who_name], class, who_name)
+				PVPScan:UpdateBar (PVPScan.SpotBars [PVPScan.CurrentShownPlayers [who_name]], who_name, class, true)
 				PVPScan.NeedClass [who_name] = nil
 			end
 			return
@@ -259,112 +293,107 @@
 		if (PVPScan.NeedClass [target_name]) then
 			local class = PVPScan:GuessClass (...)
 			if (class) then
-				PVPScan:UpdateBar (PVPScan.NeedClass [target_name], class, target_name)
+				PVPScan:UpdateBar (PVPScan.SpotBars [PVPScan.CurrentShownPlayers [target_name]], target_name, class, true)
 				PVPScan.NeedClass [target_name] = nil
 			end
 			return
 		end
 		
-		if (not CurrentShownHash [target_name] and _bit_band (target_flags, OBJECT_TYPE_PLAYER) ~= 0) then --> is player
+		if (not PVPScan.CurrentShownPlayers [target_name] and _bit_band (target_flags, OBJECT_TYPE_PLAYER) ~= 0) then --> is player
 			if (_bit_band (target_flags, REACTION_HOSTILE) ~= 0) then --> is hostile
 				local class = PVPScan:GuessClass (...)
 				PVPScan:EnemySpoted (target_name, target_serial, target_flags, class)
-				
-			elseif (find_neutral_players and _bit_band (target_flags, REACTION_NEUTRAL) ~= 0) then
-				if (NeutralCandidate [target_name]) then
-					NeutralCandidate [target_name] = NeutralCandidate [target_name] + 1
-					if (NeutralCandidate [target_name] == 5) then
-						--print ("neutral", target_name)
-						local class = PVPScan:GuessClass (...)
-						PVPScan:EnemySpoted (target_name, target_serial, target_flags, class)
-					end
-				else
-					NeutralCandidate [target_name] = 1
-				end
-				
-			elseif (NeutralCandidate [target_name]) then
-				NeutralCandidate [target_name] = nil
 			end
 		end
 		
-		if (not CurrentShownHash [who_name] and _bit_band (who_flags, OBJECT_TYPE_PLAYER) ~= 0) then --> is player
+		if (not PVPScan.CurrentShownPlayers [who_name] and _bit_band (who_flags, OBJECT_TYPE_PLAYER) ~= 0) then --> is player
 			if (_bit_band (who_flags, REACTION_HOSTILE) ~= 0) then --> is hostile
 				local class = PVPScan:GuessClass (...)
 				PVPScan:EnemySpoted (who_name, who_serial, who_flags, class)
-			
-			elseif (find_neutral_players and _bit_band (who_flags, REACTION_NEUTRAL) ~= 0) then
-				if (NeutralCandidate [who_name]) then
-					NeutralCandidate [who_name] = NeutralCandidate [who_name] + 1
-					if (NeutralCandidate [who_name] == 5) then
-						--print ("neutral", who_name)
-						local class = PVPScan:GuessClass (...)
-						PVPScan:EnemySpoted (who_name, who_serial, who_flags, class)
-					end
-				else
-					NeutralCandidate [who_name] = 1
-				end
-				
-			elseif (NeutralCandidate [who_name]) then
-				NeutralCandidate [who_name] = nil
 			end
 		end
 	end
 
-	PVPScan.EventFrame:SetScript ("OnEvent", PVPScan.OnParserEvent)
-	
 	function PVPScan:LeftCombatLockdown()
 		if (PVPScan.schedule_frame_update) then
 			PVPScan.schedule_frame_update = false
 			PVPScan:RefreshSpotBars()
 		end
+		PVPScan:CheckNonCombatSpotBars()
 	end
 	function PVPScan:GotCombatLockdown()
 	end
 	
+	function PVPScan:GetNextSpotBar()
+		for i = 1, PVPScan.db.profile.SpotBarAmount do
+			local bar = PVPScan.SpotBars [i]
+			if (not bar) then
+				print (i, #PVPScan.SpotBars)
+			end
+			if (not bar.InUse and bar.Cooldown < GetTime()) then
+				return bar
+			end
+		end
+		return nil
+	end
+	
 	PVPScan:RegisterEvent ("PLAYER_REGEN_DISABLED", "GotCombatLockdown")
 	PVPScan:RegisterEvent ("PLAYER_REGEN_ENABLED", "LeftCombatLockdown")
 
 	-- found a enemy on the scan
+	function PVPScan:EnemySpoted (name, serial, flags, class)
 	
-	function PVPScan:EnemySpoted (name, serial, flags, class)
-
+		--se nao tiver nome, nao interessa
 		if (not name) then
 			return
 		end
+		
+		--se o player tiver no cooldown para mostrar, ignora-lo
+		if (PVPScan.CooldownShownPlayers [name] and PVPScan.CooldownShownPlayers [name] > GetTime()) then
+			return
+		end
 
-		--> check for overwrite
-		local current_player_shown = CurrentShownIndex [PVPScan.NextSpotBar]
-		if (current_player_shown) then
-			PVPScan.NeedClass [current_player_shown] = nil
+		local SpotBar = PVPScan:GetNextSpotBar()
+
+		if (not SpotBar) then
+			return
 		end
-	
-		local SpotBar = PVPScan.SpotBars [PVPScan.NextSpotBar]
 
-		if (class) then
-			PVPScan:UpdateBar (PVPScan.NextSpotBar, class, name)
-		else
-			PVPScan:UpdateBar (PVPScan.NextSpotBar, nil, name)
-			PVPScan.NeedClass [name] = PVPScan.NextSpotBar
+		--seta o cooldown deste jogador
+		PVPScan.CooldownShownPlayers [name] = GetTime() + PVPScan.db.profile.SpotBarPlayerCooldown
+		--seta em qual barra o jogador esta sendo mostrado
+		PVPScan.CurrentShownPlayers [name] = SpotBar.Index
+
+		--se nao tiver uma classe, agendar uma pesquisa
+		if (not class) then
+			PVPScan.NeedClass [name] = true
 		end
 		
-		CurrentShownIndex [PVPScan.NextSpotBar] = name
-		CurrentShownHash [name] = PVPScan.NextSpotBar
-		CurrentShownTime [name] = GetTime()
+		--atualiza a barra
+		PVPScan:UpdateBar (SpotBar, name, class)
 		
-		if (not UnitAffectingCombat ("player") and not InCombatLockdown()) then
-			SpotBar:SetAttribute ("macrotext", "/cleartarget\n/targetexact " .. name)
+		--toca o som se a configuracao permitir
+		if (PVPScan.db.profile.SoundPlay) then
+			local sound = PVPScan.db.profile.SoundFile
+			sound = SharedMedia:Fetch ("sound", sound)
+			if (sound) then
+				PlaySoundFile (sound, "Master")
+			end
 		end
-		
-		SpotBar:Show()
-		
-		PVPScan.NextSpotBar = PVPScan.NextSpotBar + 1
-		if (PVPScan.NextSpotBar > PVPScan.db.profile.SpotBarAmount) then
-			PVPScan.NextSpotBar = 1
-		end
-
 	end
 	
 	-- frames
+	
+	function PVPScanOnFrameEnter (self)
+		GameTooltip:SetOwner (self, "ANCHOR_TOPLEFT")
+		GameTooltip:ClearLines()
+		GameTooltip:AddLine ("Right Click To Open Options Panel")
+		GameTooltip:Show()
+	end
+	
+	function PVPScanOnFrameLeave (self)
+		GameTooltip:Hide()
+	end
 
 	function PVPScanOnFrameMouseDown (self, button)
 		if (button == "LeftButton") then
@@ -388,29 +417,146 @@
 		end
 	end
 
-	function PVPScan:UpdateBar (index, class, name)
+	function PVPScan:CheckNonCombatSpotBars()
+		for i = 1, PVPScan.db.profile.SpotBarAmount do
+			local SpotObject = PVPScan.SpotBars [i]
+			if (SpotObject.InUse and (SpotObject.NonTargetFrame:IsShown() or SpotObject.NeedUpdate)) then
+				PVPScan:UpdateBar (SpotObject, SpotObject.PlayerName, SpotObject.PlayerClass)
+			end
+		end
+	end
 	
+	function PVPScan:UpdateBar (SpotObject, Name, Class, ClassUpdate)
+	
+		SpotObject.IsShown = true
+		SpotObject.InUse = true
+		SpotObject.PlayerName = Name
+		SpotObject.PlayerClass = Class
+		SpotObject.Cooldown = GetTime() + PVPScan.db.profile.SpotBarCooldown
+		SpotObject.ExpireAt = GetTime() + PVPScan.db.profile.SpotBarTimeOut
+		SpotObject.NeedUpdate = false
+		
+		if (ClassUpdate) then
+			if (SpotObject.TargetFrame:IsShown()) then
+				if (not UnitAffectingCombat ("player") and not InCombatLockdown()) then
+					local color = RAID_CLASS_COLORS [Class]
+					local texcoord = CLASS_ICON_TCOORDS [Class]
+					SpotObject.TargetFrame.classtexture:SetVertexColor (color.r, color.g, color.b)
+					SpotObject.TargetFrame.classicon:SetTexture ([[Interface\Glues\CHARACTERCREATE\UI-CHARACTERCREATE-CLASSES]])
+					SpotObject.TargetFrame.classicon:SetTexCoord (unpack (texcoord))
+				else
+					SpotObject.NeedUpdate = true
+				end
+			else
+				local color = RAID_CLASS_COLORS [Class]
+				local texcoord = CLASS_ICON_TCOORDS [Class]
+				SpotObject.NonTargetFrame.classtexture:SetVertexColor (color.r, color.g, color.b)
+				SpotObject.NonTargetFrame.classicon:SetTexture ([[Interface\Glues\CHARACTERCREATE\UI-CHARACTERCREATE-CLASSES]])
+				SpotObject.NonTargetFrame.classicon:SetTexCoord (unpack (texcoord))
+			end
+		end
+
 		if (UnitAffectingCombat ("player") or InCombatLockdown()) then
-			--return
+			--> enable in combat bat
+			if (Class) then
+				local color = RAID_CLASS_COLORS [Class]
+				local texcoord = CLASS_ICON_TCOORDS [Class]
+				SpotObject.NonTargetFrame.classtexture:SetVertexColor (color.r, color.g, color.b)
+				SpotObject.NonTargetFrame.classicon:SetTexture ([[Interface\Glues\CHARACTERCREATE\UI-CHARACTERCREATE-CLASSES]])
+				SpotObject.NonTargetFrame.classicon:SetTexCoord (unpack (texcoord))
+			else
+				SpotObject.NonTargetFrame.classtexture:SetVertexColor (.7, .7, .7)
+				SpotObject.NonTargetFrame.classicon:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]])
+				SpotObject.NonTargetFrame.classicon:SetTexCoord (0, 1, 0, 1)
+			end
+			SpotObject.NonTargetFrame.name:SetText (Name)
+			SpotObject.NonTargetFrame:Show()
+			SpotObject.NeedUpdate = true
+		else
+			--> enable spot bar
+			if (Class) then
+				local color = RAID_CLASS_COLORS [Class]
+				local texcoord = CLASS_ICON_TCOORDS [Class]
+				SpotObject.TargetFrame.classtexture:SetVertexColor (color.r, color.g, color.b)
+				SpotObject.TargetFrame.classicon:SetTexture ([[Interface\Glues\CHARACTERCREATE\UI-CHARACTERCREATE-CLASSES]])
+				SpotObject.TargetFrame.classicon:SetTexCoord (unpack (texcoord))
+			else
+				SpotObject.TargetFrame.classtexture:SetVertexColor (.7, .7, .7)
+				SpotObject.TargetFrame.classicon:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]])
+				SpotObject.TargetFrame.classicon:SetTexCoord (0, 1, 0, 1)
+			end
+			SpotObject.TargetFrame:SetAttribute ("macrotext", "/cleartarget\n/targetexact " .. Name)
+			SpotObject.TargetFrame.name:SetText (Name)
+			SpotObject.TargetFrame.SpotObject = SpotObject
+			SpotObject.NonTargetFrame:Hide()
+			SpotObject.TargetFrame:Show()
 		end
+	end
 	
-		local SpotBar = PVPScan.SpotBars [index]
+	function PVPScan:CheckBarTimeOut()
+		if (not UnitAffectingCombat ("player") and not InCombatLockdown()) then
 		
-		if (class) then
-			local color = RAID_CLASS_COLORS [class]
-			SpotBar.classtexture:SetVertexColor (color.r, color.g, color.b)
-
-			local texcoord = CLASS_ICON_TCOORDS [class]
-			SpotBar.classicon:SetTexture ([[Interface\Glues\CHARACTERCREATE\UI-CHARACTERCREATE-CLASSES]])
-			SpotBar.classicon:SetTexCoord (unpack (texcoord))
-		else
-			SpotBar.classtexture:SetVertexColor (.7, .7, .7)
-			SpotBar.classicon:SetTexture ([[Interface\InventoryItems\WoWUnknownItem01]])
-			SpotBar.classicon:SetTexCoord (0, 1, 0, 1)
+			local time = GetTime()
+			
+			for repeat_twice = 1, 2 do
+				for i = 1, PVPScan.db.profile.SpotBarAmount do
+				
+					local SpotObject = PVPScan.SpotBars [i]
+					
+					if (SpotObject.InUse) then
+						--verifica se expirou
+						if (SpotObject.ExpireAt < time) then
+							PVPScan:DisableSpotBar (SpotObject)
+						end
+					else
+						for o = i+1, PVPScan.db.profile.SpotBarAmount do
+							local NextSpotObject = PVPScan.SpotBars [o]
+							if (NextSpotObject.InUse) then --> transferir pra cá
+								--seta a nova barra
+								local PlayerName = NextSpotObject.PlayerName
+								PVPScan:UpdateBar (SpotObject, PlayerName, NextSpotObject.PlayerClass)
+								--desliga a barra antiga
+								PVPScan:DisableSpotBar (NextSpotObject)
+								--seta em qual barra o jogador esta sendo mostrado
+								PVPScan.CurrentShownPlayers [PlayerName] = i
+								break
+							end
+						end
+					end
+				end
+			end
 		end
 		
-		SpotBar.name:SetText (name)
+	end
+	
+	function PVPScanSpotBarClick (self)
+		if (self.SpotObject) then
+			self.SpotObject.Cooldown = GetTime() + PVPScan.db.profile.SpotBarCooldown
+			self.SpotObject.ExpireAt = GetTime() + PVPScan.db.profile.SpotBarTimeOut
+		end
+	end
+	
+	function PVPScan:DisableSpotBar (SpotObject)
+		SpotObject.TargetFrame:Hide()
+		SpotObject.TargetFrame.SpotObject = nil
+		SpotObject.NonTargetFrame:Hide()
 		
+		SpotObject.IsShown = false
+		SpotObject.NeedUpdate = false
+		SpotObject.InUse = false
+		SpotObject.Cooldown = 0
+		SpotObject.ExpireAt = 0
+		
+		local name = SpotObject.PlayerName
+		
+		if (name) then
+			PVPScan.NeedClass [name] = nil
+			PVPScan.CurrentShownPlayers [name] = nil
+			PVPScan.CooldownShownPlayers [name] = nil
+		end
+		
+		SpotObject.PlayerName = nil
+		SpotObject.PlayerClass = nil
 	end
 	
 	function PVPScan:RefreshSpotBars()
@@ -434,37 +580,57 @@
 		if (amount_bars > #PVPScan.SpotBars) then
 			for i = #PVPScan.SpotBars+1, amount_bars do 
 			
-				local new_bar = CreateFrame ("Button", "PVPScanSpotBar" .. i, PVPScanFrame, "PVPScanSpotBarTemplate")
+				local NewBarObject = {
+					Index = i,
+					TargetFrame = CreateFrame ("Button", "PVPScanSpotBar" .. i, PVPScanFrame, "PVPScanSpotBarTemplate"),
+					NonTargetFrame = CreateFrame ("Button", "PVPScanSpotBarInCombat" .. i, PVPScanFrame, "PVPScanSpotBarInCombatTemplate"),
+					IsShown = false, -- se a barra esta sendo mostrada
+					PlayerName = nil, -- nome do jogador que esta sendo mostrado
+					PlayerClass = nil,
+					NeedUpdate = false, -- se a barra precisa de um update após o termino do combate
+					InUse = false, -- se a barra esta em uso
+					ExpireAt = 0, -- quando a barra ira sumir automaticamente
+					Cooldown = 0, -- tempo para poder por outro jogador nesta barra
+				}
+			
+				NewBarObject.NonTargetFrame:SetFrameLevel (NewBarObject.TargetFrame:GetFrameLevel()+1)
 				
 				local y = (i-1) * PVPScan.db.profile.SpotBarHeight * -1
 				
-				new_bar:SetPoint ("topleft", PVPScanFrame, "topleft", 0, y)
-				new_bar:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
+				NewBarObject.TargetFrame:SetPoint ("topleft", PVPScanFrame, "topleft", 0, y)
+				NewBarObject.NonTargetFrame:SetPoint ("topleft", PVPScanFrame, "topleft", 0, y)
 				
-				tinsert (PVPScan.SpotBars, new_bar)
+				NewBarObject.TargetFrame:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
+				NewBarObject.NonTargetFrame:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
+				
+				tinsert (PVPScan.SpotBars, NewBarObject)
 			end
 		end
 		
 		if (#PVPScan.SpotBars > amount_bars) then
 			for i = #PVPScan.SpotBars, amount_bars+1, -1 do
-				PVPScan.SpotBars [i]:Hide()
-				local name = CurrentShownIndex [i]
-				if (name) then
-					tremove (CurrentShownIndex, i)
-					CurrentShownHash [name] = nil
-					CurrentShownTime [name] = nil
-					PVPScan.NeedClass [name] = nil
-				end
+				PVPScan:DisableSpotBar (PVPScan.SpotBars [i])
 			end
 		end
 
 		--> refresh existing
-		for index, bar in ipairs (PVPScan.SpotBars) do
-			local y = (index-1) * PVPScan.db.profile.SpotBarHeight * -1
-			bar:SetPoint ("topleft", PVPScanFrame, "bottomleft", 0, y)
-			bar:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
-			bar.classtexture:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
-			bar.classicon:SetSize (PVPScan.db.profile.SpotBarHeight, PVPScan.db.profile.SpotBarHeight)
+		for Index, BarObject in ipairs (PVPScan.SpotBars) do
+			local y = (Index-1) * PVPScan.db.profile.SpotBarHeight * -1
+			--point
+			BarObject.TargetFrame:SetPoint ("topleft", PVPScanFrame, "bottomleft", 0, y)
+			BarObject.NonTargetFrame:SetPoint ("topleft", PVPScanFrame, "bottomleft", 0, y)
+			--size
+			BarObject.TargetFrame:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
+			BarObject.NonTargetFrame:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
+			--texture size
+			BarObject.TargetFrame.classtexture:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
+			BarObject.NonTargetFrame.classtexture:SetSize (PVPScan.db.profile.SpotBarWidth, PVPScan.db.profile.SpotBarHeight)
+			--bar texture
+			BarObject.TargetFrame.classtexture:SetTexture (SharedMedia:Fetch ("statusbar", PVPScan.db.profile.SpotBarTexture) or [[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]])
+			BarObject.NonTargetFrame.classtexture:SetTexture (SharedMedia:Fetch ("statusbar", PVPScan.db.profile.SpotBarTexture) or [[Interface\PaperDollInfoFrame\UI-Character-Skills-Bar]])
+			--icon size
+			BarObject.TargetFrame.classicon:SetSize (PVPScan.db.profile.SpotBarHeight, PVPScan.db.profile.SpotBarHeight)
+			BarObject.NonTargetFrame.classicon:SetSize (PVPScan.db.profile.SpotBarHeight, PVPScan.db.profile.SpotBarHeight)
 		end
 		
 	end
@@ -479,25 +645,7 @@
 				return PVPScan.ClassSpellList [arg1]
 			end
 		end
-		
-		if (type (arg3) == "number") then
-			if (PVPScan.ClassSpellList [arg3]) then
-				return PVPScan.ClassSpellList [arg3]
-			end
-		end
-		
-		if (type (arg2) == "number") then
-			if (PVPScan.ClassSpellList [arg3]) then
-				return PVPScan.ClassSpellList [arg3]
-			end
-		end
 
-		if (type (arg4) == "number") then
-			if (PVPScan.ClassSpellList [arg4]) then
-				return PVPScan.ClassSpellList [arg4]
-			end
-		end
-		
 		return nil
 	end
 
--- a/PVPScan.xml	Mon May 19 05:50:51 2014 -0300
+++ b/PVPScan.xml	Sun Jun 01 03:48:11 2014 -0300
@@ -17,6 +17,12 @@
 		</Backdrop>
 		
 		<Scripts>
+			<OnEnter>
+				PVPScanOnFrameEnter (self)
+			</OnEnter>
+			<OnLeave>
+				PVPScanOnFrameLeave (self)
+			</OnLeave>
 			<OnMouseDown>
 				PVPScanOnFrameMouseDown (self, button)
 			</OnMouseDown>
@@ -82,5 +88,78 @@
 				</FontString>
 			</Layer>
 		</Layers>
+		
+		<Scripts>
+			<OnMouseUp>
+				PVPScanSpotBarClick (self);
+			</OnMouseUp>
+		</Scripts>
+	</Button>
+	
+	<Button name="PVPScanSpotBarInCombatTemplate" frameStrata="HIGH" hidden="true" parent="PVPScanFrame" movable="false" virtual="true">
+		<Size>
+			<AbsDimension x="150" y="20"/>
+		</Size>
+	
+		<Layers>
+			<Layer level="BACKGROUND">
+				<Texture name="$parentClassTexture" parentKey="classtexture" file="Interface\PaperDollInfoFrame\UI-Character-Skills-Bar">
+					<Size>
+						<AbsDimension x="150" y="20"/>
+					</Size>
+					<Anchors>
+						<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT"/>
+					</Anchors>
+				</Texture>
+			</Layer>
+		
+			<Layer level="BORDER">
+				<Texture name="$parentClassIcon" parentKey="classicon" file="Interface\InventoryItems\WoWUnknownItem01">
+					<Size>
+						<AbsDimension x="20" y="20"/>
+					</Size>
+					<Anchors>
+						<Anchor point="LEFT" relativeTo="$parent" relativePoint="LEFT"/>
+					</Anchors>
+				</Texture>
+				
+				<FontString name="$parentName" text="Enemy Name" inherits="GameFontHighlightSmall" justifyH="LEFT" parentKey="name">
+					<FontHeight val="10"/>
+					<Anchors>
+						<Anchor point="LEFT" relativeTo="$parentClassIcon" relativePoint="RIGHT" x="2" y="0"/>
+					</Anchors>
+				</FontString>
+			</Layer>
+			
+			<Layer level="ARTWORK">
+				<Texture name="$parentInCombatShadow" parentKey="inCombatShadow" file="Interface\Tooltips\UI-Tooltip-Background">
+					<Size>
+						<AbsDimension x="150" y="20"/>
+					</Size>
+					<Anchors>
+						<Anchor point="TOPLEFT" relativeTo="$parentClassTexture" relativePoint="TOPLEFT"/>
+						<Anchor point="BOTTOMRIGHT" relativeTo="$parentClassTexture" relativePoint="BOTTOMRIGHT"/>
+					</Anchors>
+				</Texture>
+			</Layer>
+			<Layer level="OVERLAY">
+				<Texture name="$parentInCombatIcon" parentKey="inCombat" file="Interface\CHARACTERFRAME\Disconnect-Icon">
+					<Size>
+						<AbsDimension x="20" y="20"/>
+					</Size>
+					<TexCoords left="0.18" right="0.82" top="0.18" bottom="0.82"/>
+					<Anchors>
+						<Anchor point="RIGHT" relativeTo="$parent" relativePoint="RIGHT"/>
+					</Anchors>
+				</Texture>
+			</Layer>
+		</Layers>
+		
+		<Scripts>
+			<OnLoad>
+				self.inCombatShadow:SetVertexColor (0, 0, 0, .6);
+			</OnLoad>
+		</Scripts>
+		
 	</Button>
 </Ui>
\ No newline at end of file
--- a/libs.xml	Mon May 19 05:50:51 2014 -0300
+++ b/libs.xml	Sun Jun 01 03:48:11 2014 -0300
@@ -7,5 +7,6 @@
 	<Include file="Libs\AceConfig-3.0\AceConfig-3.0.xml"/>
 	<Include file="Libs\AceDBOptions-3.0\AceDBOptions-3.0.xml"/>
 	<Include file="Libs\AceEvent-3.0\AceEvent-3.0.xml" />
+	<Include file="Libs\AceTimer-3.0\AceTimer-3.0.xml" />
 	<Include file="Libs\LibSharedMedia-3.0\lib.xml" />
 </Ui>
\ No newline at end of file