Quantcast

Complete rewrite

Adrian L Lange [05-24-13 - 20:52]
Complete rewrite
- Added config
- Support for Loot Specialization
Filename
Config.lua
HabeebIt.lua
HabeebIt.toc
diff --git a/Config.lua b/Config.lua
new file mode 100644
index 0000000..b305da9
--- /dev/null
+++ b/Config.lua
@@ -0,0 +1,114 @@
+local addonName, ns = ...
+
+local buttons = {}
+local temporary = {}
+
+local defaults = {
+	position = 'TOP',
+}
+
+local Panel = CreateFrame('Frame', nil, InterfaceOptionsFramePanelContainer)
+Panel.name = addonName
+Panel:Hide()
+
+Panel:RegisterEvent('PLAYER_LOGIN')
+Panel:SetScript('OnEvent', function()
+	HabeebItDB = HabeebItDB or defaults
+
+	for key, value in pairs(defaults) do
+		if(HabeebItDB[key] == nil) then
+			HabeebItDB[key] = value
+		end
+	end
+
+	HabeebItContainer:PLAYER_LOGIN()
+end)
+
+function Panel:okay()
+	for key, value in pairs(temporary) do
+		HabeebItDB[key] = value
+	end
+
+	HabeebItContainer:HandleUpdate()
+end
+
+function Panel:default()
+	HabeebItDB = defaults
+	table.wipe(temporary)
+end
+
+function Panel:refresh()
+	for key, button in pairs(buttons) do
+		if(button:IsObjectType('Button')) then
+			UIDropDownMenu_SetSelectedValue(button, HabeebItDB[key])
+
+			-- This is for some reason needed, gotta take a look into it later
+			UIDropDownMenu_SetText(button, _G[HabeebItDB[key] .. '_KEY'])
+		end
+	end
+end
+
+local CreateDropdown
+do
+	local function OnClick(self)
+		UIDropDownMenu_SetSelectedValue(self:GetParent().dropdown, self.value)
+		temporary[self:GetParent().dropdown.key] = self.value
+	end
+
+	function CreateDropdown(parent, key, func)
+		local Dropdown = CreateFrame('Button', addonName .. 'DropDown_' .. GetTime(), parent, 'UIDropDownMenuTemplate')
+		Dropdown.OnClick = OnClick
+		Dropdown.key = key
+
+		UIDropDownMenu_SetWidth(Dropdown, 90)
+		UIDropDownMenu_SetSelectedValue(Dropdown, HabeebItDB[key])
+		UIDropDownMenu_Initialize(Dropdown, func)
+
+		local Text = Dropdown:CreateFontString(nil, nil, 'GameFontHighlight')
+		Text:SetPoint('LEFT', Dropdown, 'RIGHT', -1, 2)
+		Dropdown.Text = Text
+
+		buttons[key] = Dropdown
+
+		return Dropdown
+	end
+end
+
+Panel:SetScript('OnShow', function(self)
+	local Title = self:CreateFontString(nil, nil, 'GameFontNormalLarge')
+	Title:SetPoint('TOPLEFT', 16, -16)
+	Title:SetText(addonName)
+
+	local Description = self:CreateFontString(nil, nil, 'GameFontHighlightSmall')
+	Description:SetPoint('TOPLEFT', Title, 'BOTTOMLEFT', 0, -8)
+	Description:SetPoint('RIGHT', -32, 0)
+	Description:SetJustifyH('LEFT')
+	Description:SetText('Quick access to your upcoming loot!')
+	self.Description = Description
+
+	local Position = CreateDropdown(self, 'position', function(self)
+		local selected = UIDropDownMenu_GetSelectedValue(self)
+		local info = UIDropDownMenu_CreateInfo()
+		info.text = 'Bottom'
+		info.value = 'BOTTOM'
+		info.func = self.OnClick
+		info.checked = selected == info.value
+		UIDropDownMenu_AddButton(info)
+
+		info.text = 'Top'
+		info.value = 'TOP'
+		info.checked = selected == info.value
+		UIDropDownMenu_AddButton(info)
+	end)
+	Position:SetPoint('TOPLEFT', Description, 'BOTTOMLEFT', -13, -14)
+	Position.Text:SetText('Position of the list')
+
+	self:SetScript('OnShow', nil)
+end)
+
+InterfaceOptions_AddCategory(Panel)
+
+SLASH_HabeebIt1 = '/habeebit'
+SlashCmdList[addonName] = function()
+	InterfaceOptionsFrame_OpenToCategory(addonName)
+end
diff --git a/HabeebIt.lua b/HabeebIt.lua
index 3553734..2682635 100644
--- a/HabeebIt.lua
+++ b/HabeebIt.lua
@@ -1,20 +1,151 @@
 local _, ns = ...

-local items = {}
-local specializations = {}
-local collapsed = true
 local currentEncounterID
+local itemButtons = {}

-local Frame = CreateFrame('Frame', 'HabeebItFrame', BonusRollFrame)
-local Handle = CreateFrame('Button', 'HabeebItHandle', BonusRollFrame)
-
-local backdrop = {
-	bgFile = [[Interface\ChatFrame\ChatFrameBackground]], tile = true, tileSize = 16,
-	edgeFile = [[Interface\Tooltips\UI-Tooltip-Border]], edgeSize = 16,
+local BACKDROP = {
+	bgFile = [=[Interface\ChatFrame\ChatFrameBackground]=], tile = true, tileSize = 16,
+	edgeFile = [=[Interface\Tooltips\UI-Tooltip-Border]=], edgeSize = 16,
 	insets = {left = 4, right = 4, top = 4, bottom = 4}
 }

-local function OnUpdate(self, elapsed)
+local Container = CreateFrame('Frame', 'HabeebItContainer', BonusRollFrame)
+local Handle = CreateFrame('Button', 'HabeebItHandle', BonusRollFrame)
+
+local Hotspot = CreateFrame('Frame', nil, BonusRollFrame)
+local Buttons = CreateFrame('Frame', 'HabeebItSpecButtons', Hotspot)
+
+local function SpecButtonClick(self)
+	SetLootSpecialization(self.specID)
+	Buttons:Hide()
+	BonusRollFrame.SpecIcon:SetDesaturated(false)
+end
+
+local function SpecButtonEnter(self)
+	GameTooltip:SetOwner(self, 'ANCHOR_TOPRIGHT')
+	GameTooltip:AddLine(self.name, 1, 1, 1)
+	GameTooltip:Show()
+end
+
+local specButtons
+local function HotspotEnter()
+	if(not Buttons:IsShown()) then
+		if(not specButtons) then
+			local numSpecs = GetNumSpecializations()
+			for index = 1, numSpecs do
+				local specID, name, _, texture = GetSpecializationInfo(index)
+
+				local SpecButton = CreateFrame('Button', nil, Buttons)
+				SpecButton:SetPoint('LEFT', index * 28, 0)
+				SpecButton:SetSize(22, 22)
+				SpecButton:SetScript('OnClick', SpecButtonClick)
+				SpecButton:SetScript('OnEnter', SpecButtonEnter)
+				SpecButton:SetScript('OnLeave', GameTooltip_Hide)
+
+				SpecButton.specID = specID
+				SpecButton.name = name
+
+				local Icon = SpecButton:CreateTexture(nil, 'OVERLAY', nil, 1)
+				Icon:SetAllPoints()
+				Icon:SetTexture(texture)
+
+				local Ring = SpecButton:CreateTexture(nil, 'OVERLAY', nil, 2)
+				Ring:SetPoint('TOPLEFT', -6, 6)
+				Ring:SetSize(58, 58)
+				Ring:SetTexture([=[Interface\Minimap\Minimap-TrackingBorder]=])
+			end
+
+			Buttons:SetSize(numSpecs * 28 + 34, 38)
+
+			specButtons = true
+		end
+
+		BonusRollFrame.SpecIcon:SetDesaturated(true)
+		Buttons:Show()
+	end
+end
+
+local function HotspotLeave()
+	if(not Buttons:IsMouseOver()) then
+		BonusRollFrame.SpecIcon:SetDesaturated(false)
+		Buttons:Hide()
+	end
+end
+
+local function ButtonsLeave(self)
+	local parent = GetMouseFocus():GetParent()
+	if(not Hotspot:IsMouseOver() and not (parent and parent == self)) then
+		BonusRollFrame.SpecIcon:SetDesaturated(false)
+		self:Hide()
+	end
+end
+
+local collapsed = true
+local function HandleClick()
+	Handle:ClearAllPoints()
+
+	if(collapsed) then
+		if(HabeebItDB.position == 'BOTTOM') then
+			Handle.Arrow:SetTexCoord(1/2, 1, 1, 1, 1/2, 0, 1, 0)
+			Handle:SetPoint('BOTTOM', Container, 0, -14)
+		else
+			Handle.Arrow:SetTexCoord(1, 0, 1/2, 0, 1, 1, 1/2, 1)
+			Handle:SetPoint('TOP', Container, 0, 14)
+		end
+
+		Container:Show()
+	else
+		if(HabeebItDB.position == 'BOTTOM') then
+			Handle.Arrow:SetTexCoord(0, 0, 1/2, 0, 0, 1, 1/2, 1)
+			Handle:SetPoint('TOP', BonusRollFrame, 'BOTTOM', 0, 2)
+		else
+			Handle.Arrow:SetTexCoord(1/2, 1, 0, 1, 1/2, 0, 0, 0)
+			Handle:SetPoint('BOTTOM', BonusRollFrame, 'TOP', 0, -2)
+		end
+
+		Container:Hide()
+	end
+
+	collapsed = not collapsed
+end
+
+function Container:HandleUpdate()
+	self:ClearAllPoints()
+
+	if(HabeebItDB.position == 'BOTTOM') then
+		self:SetPoint('TOP', BonusRollFrame, 'BOTTOM')
+
+		Handle.Arrow:SetTexCoord(0, 0, 1/2, 0, 0, 1, 1/2, 1)
+		Handle.TopCenter:Hide()
+		Handle.TopRight:Hide()
+		Handle.TopLeft:Hide()
+		Handle.BottomCenter:Show()
+		Handle.BottomRight:Show()
+		Handle.BottomLeft:Show()
+	else
+		self:SetPoint('BOTTOM', BonusRollFrame, 'TOP')
+
+		Handle.Arrow:SetTexCoord(1/2, 1, 0, 1, 1/2, 0, 0, 0)
+		Handle.TopCenter:Show()
+		Handle.TopRight:Show()
+		Handle.TopLeft:Show()
+		Handle.BottomCenter:Hide()
+		Handle.BottomRight:Hide()
+		Handle.BottomLeft:Hide()
+	end
+
+	self:Hide()
+	collapsed = true
+end
+
+local function HookStartRoll()
+	local specID = GetLootSpecialization()
+	if(not specID or specID == 0) then
+		SetLootSpecialization(GetSpecializationInfo(GetSpecialization()))
+	end
+end
+
+local function ItemButtonUpdate(self, elapsed)
 	if(IsModifiedClick('COMPAREITEMS')) then
 		GameTooltip_ShowCompareItem()
 	else
@@ -30,119 +161,102 @@ local function OnUpdate(self, elapsed)
 	end
 end

-local function OnEnter(self)
+local function ItemButtonClick(self)
+	HandleModifiedItemClick(self.itemLink)
+end
+
+local function ItemButtonEnter(self)
 	GameTooltip:SetOwner(self, 'ANCHOR_TOPLEFT')
 	GameTooltip:SetItemByID(self.itemID)

-	self:SetScript('OnUpdate', OnUpdate)
+	self:SetScript('OnUpdate', ItemButtonUpdate)
 end

-local function OnLeave(self)
+local function ItemButtonLeave(self)
 	GameTooltip:Hide()

 	self:SetScript('OnUpdate', nil)
 end

-local function OnClick(self)
-	HandleModifiedItemClick(self.itemLink)
-end
-
 local function GetItemLine(index)
-	local Item = items[index]
-	if(not Item) then
-		Item = CreateFrame('Button', nil, Frame)
-		Item:SetSize(321, 45)
+	local ItemButton = itemButtons[index]
+	if(not ItemButton) then
+		ItemButton = CreateFrame('Button', nil, Container)
+		ItemButton:SetSize(276, 38)

-		local Icon = Item:CreateTexture(nil, 'BACKGROUND')
-		Icon:SetPoint('TOPLEFT', 2, -2)
-		Icon:SetSize(42, 42)
-		Item.Icon = Icon
+		local Icon = ItemButton:CreateTexture(nil, 'BACKGROUND')
+		Icon:SetPoint('TOPLEFT', 1, -1)
+		Icon:SetSize(36, 36)
+		ItemButton.Icon = Icon

-		local Background = Item:CreateTexture(nil, 'BORDER')
+		local Background = ItemButton:CreateTexture(nil, 'BORDER')
 		Background:SetAllPoints()
 		Background:SetTexture([[Interface\EncounterJournal\UI-EncounterJournalTextures]])
 		Background:SetTexCoord(0.00195313, 0.62890625, 0.61816406, 0.66210938)
 		Background:SetDesaturated(true)

-		local Name = Item:CreateFontString(nil, 'ARTWORK', 'GameFontNormalMed3')
-		Name:SetPoint('TOPLEFT', Icon, 'TOPRIGHT', 7, -7)
-		Name:SetSize(250, 12)
+		local Name = ItemButton:CreateFontString(nil, 'ARTWORK', 'GameFontNormalMed3')
+		Name:SetPoint('TOPLEFT', Icon, 'TOPRIGHT', 7, -4)
+		Name:SetPoint('TOPRIGHT', -6, -4)
+		Name:SetHeight(12)
 		Name:SetJustifyH('LEFT')
-		Item.Name = Name
+		ItemButton.Name = Name

-		local Class = Item:CreateFontString(nil, 'ARTWORK', 'GameFontHighlight')
-		Class:SetPoint('BOTTOMRIGHT', Name, 'TOPLEFT', 264, -30)
+		local Class = ItemButton:CreateFontString(nil, 'ARTWORK', 'GameFontHighlight')
+		Class:SetPoint('BOTTOMRIGHT', Name, 'TOPLEFT', 224, -28)
 		Class:SetSize(0, 12)
 		Class:SetJustifyH('RIGHT')
-		Item.Class = Class
+		ItemButton.Class = Class

-		local Slot = Item:CreateFontString(nil, 'ARTWORK', 'GameFontHighlight')
-		Slot:SetPoint('BOTTOMLEFT', Icon, 'BOTTOMRIGHT', 7, 5)
+		local Slot = ItemButton:CreateFontString(nil, 'ARTWORK', 'GameFontHighlight')
+		Slot:SetPoint('BOTTOMLEFT', Icon, 'BOTTOMRIGHT', 7, 4)
 		Slot:SetPoint('BOTTOMRIGHT', Class, 'BOTTOMLEFT', -15, 0)
 		Slot:SetSize(0, 12)
 		Slot:SetJustifyH('LEFT')
-		Item.Slot = Slot
-
-		Item:SetScript('OnClick', OnClick)
-		Item:SetScript('OnEnter', OnEnter)
-		Item:SetScript('OnLeave', OnLeave)
-
-		items[index] = Item
-	end
-
-	return Item
-end
+		ItemButton.Slot = Slot

-local function UpdatePosition()
-	local populateDown = Frame:GetBottom() > (UIParent:GetHeight() / 1.5)
+		ItemButton:SetScript('OnClick', ItemButtonClick)
+		ItemButton:SetScript('OnEnter', ItemButtonEnter)
+		ItemButton:SetScript('OnLeave', ItemButtonLeave)

-	Frame:ClearAllPoints()
-	if(populateDown) then
-		Frame:SetPoint('TOPLEFT', BonusRollFrame, 'TOPRIGHT')
-	else
-		Frame:SetPoint('BOTTOMLEFT', BonusRollFrame, 'BOTTOMRIGHT')
+		itemButtons[index] = ItemButton
 	end

-	for index, button in pairs(items) do
-		button:ClearAllPoints()
-		if(populateDown) then
-			button:SetPoint('TOP', 0, (6 + ((index - 1) * 48)) * -1)
-		else
-			button:SetPoint('BOTTOM', 0, 6 + ((index - 1) * 48))
-		end
-	end
+	return ItemButton
 end

-local function PopulateList()
+function Container:Populate()
 	local numItems = 0
 	for index = 1, EJ_GetNumLoot() do
 		local name, texture, slot, itemClass, itemID, itemLink, encounterID = EJ_GetLootInfoByIndex(index)
 		if(encounterID == currentEncounterID) then
 			numItems = numItems + 1

-			local Item = GetItemLine(numItems)
-			Item.Icon:SetTexture(texture)
-			Item.Name:SetText(name)
-			Item.Slot:SetText(slot)
-			Item.Class:SetText(itemClass)
+			local ItemButton = GetItemLine(numItems)
+			ItemButton.Icon:SetTexture(texture)
+			ItemButton.Name:SetText(name)
+			ItemButton.Slot:SetText(slot)
+			ItemButton.Class:SetText(itemClass)

-			Item.itemID = itemID
-			Item.itemLink = itemLink
+			ItemButton.itemID = itemID
+			ItemButton.itemLink = itemLink

-			Item:Show()
+			if(HabeebItDB.position == 'BOTTOM') then
+				ItemButton:SetPoint('TOP', 0, (6 + ((numItems - 1) * 40)) * -1)
+			else
+				ItemButton:SetPoint('BOTTOM', 0, 6 + ((numItems - 1) * 40))
+			end
+
+			ItemButton:Show()
 		end
 	end

-	Frame:SetHeight(math.max(76, 8 + (numItems * 48)))
+	self:SetHeight(math.max(50, 10 + (numItems * 40)))

 	if(numItems > 0) then
-		Frame.Empty:Hide()
+		self.Empty:Hide()
 	else
-		Frame.Empty:Show()
-	end
-
-	if(Frame:IsShown()) then
-		UpdatePosition()
+		self.Empty:Show()
 	end

 	if(EncounterJournal) then
@@ -151,33 +265,15 @@ local function PopulateList()
 	end
 end

-local function UpdateSpecializations(currentIndex)
-	for index, button in pairs(specializations) do
-		if(currentIndex == index) then
-			button.LeftBorder:SetVertexColor(1, 0, 0)
-			button.RightBorder:SetVertexColor(1, 0, 0)
-		else
-			button.LeftBorder:SetVertexColor(1, 1, 1)
-			button.RightBorder:SetVertexColor(1, 1, 1)
-		end
-	end
-end
-
-local function InitializeList(specialization, shown)
+function Container:Update()
 	if(EncounterJournal) then
 		EncounterJournal:UnregisterEvent('EJ_DIFFICULTY_UPDATE')
 	end

-	for index, button in pairs(items) do
+	for index, button in pairs(itemButtons) do
 		button:Hide()
 	end

-	if(not shown) then
-		collapsed = false
-		Handle:GetScript('OnClick')(Handle)
-		UpdateSpecializations(specialization)
-	end
-
 	local _, _, difficulty = GetInstanceInfo()
 	EJ_SetDifficulty(difficulty > 2 and (difficulty - 2) or 1)

@@ -186,163 +282,134 @@ local function InitializeList(specialization, shown)
 	EJ_SelectEncounter(currentEncounterID)

 	local _, _, classID = UnitClass('player')
-	EJ_SetLootFilter(classID, specialization and GetSpecializationInfo(specialization) or 0)
+	EJ_SetLootFilter(classID, GetLootSpecialization() or GetSpecializationInfo(GetSpecialization() or 0) or 0)

-	PopulateList()
+	self:Populate()
 end

-local function SpecializationClick(self)
-	UpdateSpecializations(self.index)
-	InitializeList(self.index, true)
-end
+function Container:Initialize()
+	collapsed = false
+	HandleClick()

-local function SpecializationEnter(self)
-	GameTooltip:SetOwner(self, 'ANCHOR_TOPRIGHT')
-	GameTooltip:AddLine(self.name, 1, 1, 1)
-	GameTooltip:Show()
+	Container:Update()
 end

-local function GetSpec()
-	local loot = GetLootSpecialization()
-	if(loot and loot > 0) then
-		for index = 1, GetNumSpecializations() do
-			if(GetSpecializationInfo(index) == loot) then
-				return index
-			end
-		end
-	else
-		return GetSpecialization()
+function Container:EJ_LOOT_DATA_RECIEVED(event)
+	if(EncounterJournal) then
+		EncounterJournal:UnregisterEvent(event)
 	end
-end

-local function CreateSpecializationTabs(self)
-	for index = 1, GetNumSpecializations() do
-		local SpecButton = CreateFrame('Button', nil, self)
-		SpecButton:SetSize(24, 16)
-		SpecButton:SetScript('OnClick', SpecializationClick)
-		SpecButton:SetScript('OnEnter', SpecializationEnter)
-		SpecButton:SetScript('OnLeave', GameTooltip_Hide)
-		SpecButton:SetFrameLevel(6)
-
-		local _, name, _, texture = GetSpecializationInfo(index)
-		SpecButton.index = index
-		SpecButton.name = name
-
-		local SpecBackground = SpecButton:CreateTexture(nil, 'BACKGROUND')
-		SpecBackground:SetAllPoints()
-		SpecBackground:SetTexture(texture)
-		SpecBackground:SetTexCoord(0, 1, 0.2, 0.8)
-
-		local SpecLeft = SpecButton:CreateTexture(nil, 'BORDER')
-		SpecLeft:SetPoint('BOTTOMLEFT', -6, -7)
-		SpecLeft:SetSize(18, 24)
-		SpecLeft:SetTexture([[Interface\RaidFrame\RaidPanel-BottomLeft]])
-		SpecLeft:SetTexCoord(0, 0.8, 0, 1)
-		SpecButton.LeftBorder = SpecLeft
-
-		local SpecRight = SpecButton:CreateTexture(nil, 'BORDER')
-		SpecRight:SetPoint('BOTTOMRIGHT', 6, -7)
-		SpecRight:SetSize(18, 24)
-		SpecRight:SetTexture([[Interface\RaidFrame\RaidPanel-BottomRight]])
-		SpecRight:SetTexCoord(0.2, 1, 0, 1)
-		SpecButton.RightBorder = SpecRight
-
-		if(index == 1) then
-			SpecButton:SetPoint('TOPLEFT', self, 'BOTTOMLEFT', 20, 2)
-		else
-			SpecButton:SetPoint('LEFT', specializations[index - 1], 'RIGHT', 15, 0)
-		end
-
-		specializations[index] = SpecButton
-	end
+	self:Populate()
+end

-	UpdateSpecializations(GetSpec())
+function Container:PLAYER_LOOT_SPEC_UPDATED(event)
+	self:Update()
 end

-Frame:RegisterEvent('PLAYER_LOGIN')
-Frame:SetScript('OnEvent', function(self, event, ...)
-	if(event == 'SPELL_CONFIRMATION_PROMPT') then
-		local spellID, confirmType = ...
-		if(confirmType == CONFIRMATION_PROMPT_BONUS_ROLL) then
-			currentEncounterID = ns.GetEncounterID(spellID)
-			if(currentEncounterID) then
-				if(#specializations == 0) then
-					CreateSpecializationTabs(self)
-				end
-
-				InitializeList(GetSpec())
-			else
-				print('|cffff8080HabeebIt:|r Found an unknown spell [' .. spellID .. ']. Please report this!')
-			end
-		end
-	elseif(event == 'SPELL_CONFIRMATION_TIMEOUT') then
-		currentEncounterID = nil
-	elseif(event == 'EJ_LOOT_DATA_RECIEVED' and currentEncounterID) then
-		PopulateList()
+function Container:SPELL_CONFIRMATION_PROMPT(event, spellID, confirmType)
+	if(confirmType == CONFIRMATION_PROMPT_BONUS_ROLL) then
+		currentEncounterID = ns.GetEncounterID(spellID)

-		if(EncounterJournal) then
-			EncounterJournal:UnregisterEvent(event)
-		end
-	elseif(event == 'PLAYER_LOGIN') then
-		self:RegisterEvent('SPELL_CONFIRMATION_PROMPT')
-		self:RegisterEvent('SPELL_CONFIRMATION_TIMEOUT')
-		self:RegisterEvent('EJ_LOOT_DATA_RECIEVED')
-
-		self:SetScript('OnShow', UpdatePosition)
-		self:SetPoint('BOTTOMLEFT', BonusRollFrame, 'BOTTOMRIGHT')
-		self:SetSize(338, 76)
-		self:SetFrameLevel(10)
-		self:Hide()
+		if(currentEncounterID) then
+			self:RegisterEvent('EJ_LOOT_DATA_RECIEVED')
+			self:RegisterEvent('PLAYER_LOOT_SPEC_UPDATED')

-		self:SetBackdrop(backdrop)
-		self:SetBackdropColor(0, 0, 0, 0.8)
-		self:SetBackdropBorderColor(0.6, 0.6, 0.6)
-
-		local Empty = self:CreateFontString(nil, 'ARTWORK', 'GameFontHighlight')
-		Empty:SetPoint('CENTER')
-		Empty:SetText('This encounter has no possible items for\nyour current class and/or specialization')
-		self.Empty = Empty
-
-		Handle:SetPoint('BOTTOMRIGHT', 16, 4)
-		Handle:SetSize(16, 64)
-		Handle:SetNormalTexture([[Interface\RaidFrame\RaidPanel-Toggle]])
-		Handle:GetNormalTexture():SetTexCoord(0, 1/2, 0, 1)
-		Handle:SetFrameLevel(6)
-
-		local HandleBackground = Handle:CreateTexture(nil, 'BACKGROUND')
-		HandleBackground:SetPoint('BOTTOMLEFT', -2, 0)
-		HandleBackground:SetPoint('TOPRIGHT')
-		HandleBackground:SetTexture(0, 0, 0, 0.8)
-
-		local BorderBottom = Handle:CreateTexture(nil, 'BORDER')
-		BorderBottom:SetPoint('BOTTOMRIGHT', 6, -3)
-		BorderBottom:SetSize(24, 24)
-		BorderBottom:SetTexture([[Interface\RaidFrame\RaidPanel-BottomRight]])
-
-		local BorderRight = Handle:CreateTexture(nil, 'BORDER')
-		BorderRight:SetPoint('RIGHT', 7.5, 0)
-		BorderRight:SetSize(12, 24)
-		BorderRight:SetTexture([[Interface\RaidFrame\RaidPanel-Right]])
-
-		local BorderTop = Handle:CreateTexture(nil, 'BORDER')
-		BorderTop:SetPoint('TOPRIGHT', 6, 3)
-		BorderTop:SetSize(24, 24)
-		BorderTop:SetTexture([[Interface\RaidFrame\RaidPanel-UpperRight]])
+			self:Initialize()
+		else
+			print('|cffff8080HabeebIt:|r Found an unknown spell [' .. spellID .. ']. Please report this!')
+		end
 	end
-end)
+end

-Handle:SetScript('OnClick', function(self)
-	self:ClearAllPoints()
+function Container:SPELL_CONFIRMATION_TIMEOUT()
+	currentEncounterID = nil

-	if(collapsed) then
-		self:SetPoint('BOTTOMRIGHT', Frame, 16, 4)
-		self:GetNormalTexture():SetTexCoord(1/2, 1, 0, 1)
-		Frame:Show()
+	self:UnregisterEvent('EJ_LOOT_DATA_RECIEVED')
+	self:UnregisterEvent('PLAYER_LOOT_SPEC_UPDATED')
+end
+
+function Container:PLAYER_LOGIN()
+	if(HabeebItDB.position == 'BOTTOM') then
+		self:SetPoint('TOP', BonusRollFrame, 'BOTTOM')
+		Handle:SetPoint('TOP', BonusRollFrame, 'BOTTOM', 0, 2)
 	else
-		self:SetPoint('BOTTOMRIGHT', BonusRollFrame, 16, 4)
-		self:GetNormalTexture():SetTexCoord(0, 1/2, 0, 1)
-		Frame:Hide()
+		self:SetPoint('BOTTOM', BonusRollFrame, 'TOP')
+		Handle:SetPoint('BOTTOM', BonusRollFrame, 'TOP', 0, -2)
 	end

-	collapsed = not collapsed
-end)
+	self:SetWidth(286)
+	self:SetFrameLevel(self:GetParent():GetFrameLevel() - 2)
+	self:SetBackdrop(BACKDROP)
+	self:SetBackdropColor(0, 0, 0, 0.8)
+	self:SetBackdropBorderColor(2/3, 2/3, 2/3)
+
+	self:RegisterEvent('SPELL_CONFIRMATION_PROMPT')
+	self:RegisterEvent('SPELL_CONFIRMATION_TIMEOUT')
+
+	local Empty = self:CreateFontString(nil, 'ARTWORK', 'GameFontHighlight')
+	Empty:SetPoint('CENTER')
+	Empty:SetText('This encounter has no possible items for\nyour current class and/or specialization.')
+	self.Empty = Empty
+
+	Handle:SetSize(64, 16)
+	Handle:SetNormalTexture([=[Interface\RaidFrame\RaidPanel-Toggle]=])
+	Handle:SetScript('OnClick', HandleClick)
+	Handle.Arrow = Handle:GetNormalTexture()
+
+	local HandleBackground = Handle:CreateTexture(nil, 'BACKGROUND')
+	HandleBackground:SetAllPoints()
+	HandleBackground:SetTexture(0, 0, 0, 0.8)
+
+	local TopCenter = Handle:CreateTexture(nil, 'BORDER')
+	TopCenter:SetPoint('TOP', 0, 4.5)
+	TopCenter:SetSize(24, 12)
+	TopCenter:SetTexture([=[Interface\RaidFrame\RaidPanel-UpperMiddle]=])
+	Handle.TopCenter = TopCenter
+
+	local TopRight = Handle:CreateTexture(nil, 'BORDER')
+	TopRight:SetPoint('TOPRIGHT', 4, 4)
+	TopRight:SetSize(24, 20)
+	TopRight:SetTexture([=[Interface\RaidFrame\RaidPanel-UpperRight]=])
+	TopRight:SetTexCoord(0, 1, 0, 0.8)
+	Handle.TopRight = TopRight
+
+	local TopLeft = Handle:CreateTexture(nil, 'BORDER')
+	TopLeft:SetPoint('TOPLEFT', -4, 4)
+	TopLeft:SetSize(24, 20)
+	TopLeft:SetTexture([=[Interface\RaidFrame\RaidPanel-UpperLeft]=])
+	TopLeft:SetTexCoord(0, 1, 0, 0.8)
+	Handle.TopLeft = TopLeft
+
+	local BottomCenter = Handle:CreateTexture(nil, 'BORDER')
+	BottomCenter:SetPoint('BOTTOM', 0, -9)
+	BottomCenter:SetSize(24, 12)
+	BottomCenter:SetTexture([=[Interface\RaidFrame\RaidPanel-BottomMiddle]=])
+	Handle.BottomCenter = BottomCenter
+
+	local BottomRight = Handle:CreateTexture(nil, 'BORDER')
+	BottomRight:SetPoint('BOTTOMRIGHT', 4, -6)
+	BottomRight:SetSize(24, 22)
+	BottomRight:SetTexture([=[Interface\RaidFrame\RaidPanel-BottomRight]=])
+	BottomRight:SetTexCoord(0, 1, 0.1, 1)
+	Handle.BottomRight = BottomRight
+
+	local BottomLeft = Handle:CreateTexture(nil, 'BORDER')
+	BottomLeft:SetPoint('BOTTOMLEFT', -4, -6)
+	BottomLeft:SetSize(24, 22)
+	BottomLeft:SetTexture([=[Interface\RaidFrame\RaidPanel-BottomLeft]=])
+	BottomLeft:SetTexCoord(0, 1, 0.1, 1)
+	Handle.BottomLeft = BottomLeft
+
+	self:HandleUpdate()
+
+	Hotspot:SetAllPoints(BonusRollFrame.SpecIcon)
+	Hotspot:SetScript('OnEnter', HotspotEnter)
+	Hotspot:SetScript('OnLeave', HotspotLeave)
+
+	Buttons:SetPoint('LEFT', 4, 4)
+	Buttons:SetScript('OnLeave', ButtonsLeave)
+
+	hooksecurefunc('BonusRollFrame_StartBonusRoll', HookStartRoll)
+end
+
+Container:SetScript('OnEvent', function(self, event, ...) self[event](self, event, ...) end)
diff --git a/HabeebIt.toc b/HabeebIt.toc
index 7ce3ee4..6b28eb6 100644
--- a/HabeebIt.toc
+++ b/HabeebIt.toc
@@ -1,8 +1,10 @@
-## Interface: 50200
+## Interface: 50300
 ## Author: p3lim
 ## Version: @project-version@
 ## Title: Habeeb It
 ## Notes: Easily see what the bonus loot roll can yield
+## SavedVariables: HabeebItDB

+Config.lua
 Encounters.lua
 HabeebIt.lua