--
-- AutoBarProfile
-- Copyright 2007+ Toadkiller of Proudmoore.
--
-- Buttons for AutoBar
-- http://www.wowace.com/wiki/AutoBar
-- http://toadkiller.wowinterface.com
-- http://www.curse-gaming.com/en/wow/addons-4430-1-autobar-toadkiller.html
--

AutoBarButton = {};

--local L = AceLibrary("AceLocale-2.2"):new("AutoBar");
local BS = AceLibrary:GetInstance("Babble-Spell-2.2");


function AutoBarButton:GetHotKeyDisplayText(keyText)
	if (keyText) then
		local displayText = string.gsub(keyText, "-CTRL", "C");
		displayText = string.gsub(displayText, "CTRL", "C");
		displayText = string.gsub(displayText, "-ALT", "A");
		displayText = string.gsub(displayText, "-SHIFT", "S");
		displayText = string.gsub(displayText, "-NUMPAD", "N");
		displayText = string.gsub(displayText, "-BUTTON", "B");
		displayText = string.gsub(displayText, "ALT", "A");
		displayText = string.gsub(displayText, "SHIFT", "S");
		displayText = string.gsub(displayText, "NUMPAD", "N");
		displayText = string.gsub(displayText, "BUTTON", "B");
		displayText = string.gsub(displayText, "MULTIPLY", "*");
		displayText = string.gsub(displayText, "DECIMAL", ".");
		displayText = string.gsub(displayText, "DIVIDE", "/");
		displayText = string.gsub(displayText, "MINUS", "-");
		displayText = string.gsub(displayText, "PLUS", "-");
		return displayText;
	else
		return "";
	end
end


local SPELL_FEED_PET = BS["Feed Pet"];
-- Set the state attributes of the button
function AutoBarButton:SetAttributes(button, baseName, bag, slot, count, itemId, category, itemName, action)
	local enabled = true;

	-- Handle targeted items
	local castSpell;
	local buttonsIndex = button:GetAttribute("buttonsIndex");
	local buttonInfo = AutoBar.buttons[buttonsIndex];
	button:SetAttribute("target-slot1", nil);
	button:SetAttribute("target-slot2", nil);
	button:SetAttribute("target-bag", nil);
	button:SetAttribute("target-slot", nil);
	button:SetAttribute("*unit2", nil);
	button:SetAttribute("*type1", nil);
	button:SetAttribute("*type2", nil);

	if (AutoBar_Category_Info[category]) then
		local targeted = AutoBar_Category_Info[category].targetted;
		if (targeted == "CHEST") then
			button:SetAttribute("target-slot1", 5);
			button:SetAttribute("target-slot2", 5);
		elseif (targeted == "SHIELD") then
			button:SetAttribute("target-slot1", 17);
			button:SetAttribute("target-slot2", 17);
		elseif (targeted == "WEAPON") then
			button:SetAttribute("target-slot1", 16);
			button:SetAttribute("target-slot2", 17);
		elseif (AutoBarProfile.CLASS == "HUNTER" and targeted == "PET") then
			-- Right Click targets pet
			button:SetAttribute("*type2", "spell");
			button:SetAttribute("spell2", SPELL_FEED_PET);
			button:SetAttribute("target-bag", bag);
			button:SetAttribute("target-slot", slot);
		elseif (targeted) then
			-- Support selfcast-RightMouse
			if (AutoBar.display.disableRightClickSelfCast) then
				button:SetAttribute("*unit2", nil);
			else
				button:SetAttribute("*unit2", "player");
			end
		end

		-- Disable battleground only items outside BG
		if (AutoBar_Category_Info[category].battleground and not AutoBar.inBG) then
			enabled = false;
		end

		castSpell = AutoBar_Category_Info[category].castSpell;
	end

	if (enabled) then
		if (buttonInfo) then
			-- Handle right click pet targeting for a slot
			if (buttonInfo.rightClickTargetsPet) then
				-- Right Click targets pet
				button:SetAttribute("*type2", "spell");
				button:SetAttribute("spell2", SPELL_FEED_PET);
				button:SetAttribute("target-bag", bag);
				button:SetAttribute("target-slot", slot);
			end

			if (not castSpell) then
				castSpell = buttonInfo.castSpell;
			end
		end

		button:SetAttribute("*spell1", nil);
		if (castSpell) then
			button:SetAttribute("*type2", "spell");
			button:SetAttribute("*spell2", castSpell);
		else
			button:SetAttribute("*spell2", nil);
		end

		button:SetScript("OnAttributeChanged", nil);
		if (bag or slot) then
			button:SetAttribute("type", "item");
			button:SetAttribute("bag", bag);
			button:SetAttribute("slot", slot);
		elseif (itemName) then
			button:SetAttribute("type", "item");
			button:SetAttribute("item", itemName);
			button:SetAttribute("bag", nil);
			button:SetAttribute("slot", nil);
		elseif (action) then
			button:SetAttribute("type", "action");
			button:SetAttribute("action", action);
			button:SetScript("OnAttributeChanged", ActionButton_Update);
		elseif (castSpell) then
			-- Also castSpell on left click
			button:SetAttribute("*type1", "spell");
			button:SetAttribute("*spell1", castSpell);
		end
	end
	button:SetAttribute("itemId", itemId);
	button:SetAttribute("category", category);

	AutoBarButton:UpdateTexture(button);
	AutoBarButton:UpdateCooldown(button);
	AutoBarButton:UpdateCount(button);
	AutoBarButton:UpdateUsable(button);

-- /dump UnitCanAttack("player", "target")
-- /dump UnitCanAssist("player", "target")
--	if (baseName == "AutoBarSAB1" or baseName == "AutoBarSAB1P1") then
----		button:SetAttribute("*helpbutton1", "hug1");
----		button:SetAttribute("*type-hug1", "item");
----		button:SetAttribute("unit-hug1", "target");
----		button:SetAttribute("bag-hug1", button:GetAttribute("bag"));
----		button:SetAttribute("slot-hug1", button:GetAttribute("slot"));
--
---- self:SetAttribute("*helpbutton1", "heal");
---- self:SetAttribute("*type-heal", "spell");
---- self:SetAttribute("spell-heal", "Flash Heal");
---- self:SetAttribute("ctrl-spell-heal", "Renew");
--
----		button:SetAttribute("type", nil);
----		button:SetAttribute("type*", "item");
----		button:SetAttribute("bag", bag);
----		button:SetAttribute("slot", slot);
--		button:SetAttribute("bag", nil);
--		button:SetAttribute("slot", nil);
--
----	button:SetAttribute("target-slot1", nil);
----	button:SetAttribute("target-slot2", nil);
----	button:SetAttribute("*unit2", nil);
--		button:SetAttribute("type", "spell");
--		button:SetAttribute("spell", "Thorns");
--
--		button:SetAttribute("*harmbutton1", "nuke1");
--		button:SetAttribute("*type-nuke1", "spell");
--		button:SetAttribute("spell-nuke1", "Barkskin");
--		button:SetAttribute("*unit-nuke1", "player");
--
--		button:SetAttribute("unit", "target");
--
----		button:SetAttribute("*harmbutton1", "nuke1");
----		button:SetAttribute("*type-nuke1", "spell");
----		button:SetAttribute("spell-nuke1", "Cannibalize");
----		button:SetAttribute("*unit-nuke1", "player");
--
----		button:SetAttribute("*harmbutton2", "nuke2");
----		button:SetAttribute("*type-nuke2", "spell");
----		button:SetAttribute("spell-nuke2", "Bloodrage");
----		button:SetAttribute("*unit-nuke2", "player");
--
----		button:SetAttribute("useparent-unit", true);
----		button:GetParent():SetAttribute("unit", "target");
--	end
--	if (baseName == "AutoBarSAB2" or baseName == "AutoBarSAB2P1") then
--		button:SetAttribute("type", "spell");
--		button:SetAttribute("spell", "Regrowth");
--	end
--	if (baseName == "AutoBarSAB3" or baseName == "AutoBarSAB3P1") then
--		button:SetAttribute("type", "spell");
--		button:SetAttribute("spell", "Rejuvenation");
--
--		button:SetAttribute("*helpbutton1", "heal");
--		button:SetAttribute("*type-heal", "spell");
--		button:SetAttribute("spell-heal", "Regrowth");
--		button:SetAttribute("ctrl-spell-heal", "Regrowth");
--
--		button:SetAttribute("*harmbutton1", "nuke1");
--		button:SetAttribute("*type-nuke1", "spell");
--		button:SetAttribute("spell-nuke1", "Moonfire");
--		button:SetAttribute("*unit-nuke1", "player");
----
----		button:SetAttribute("unit", "target");
--	end
--	if (baseName == "AutoBarSAB5" or baseName == "AutoBarSAB5P1") then
--		button:SetAttribute("type", "spell");
--		button:SetAttribute("spell", "Rejuvenation");
--	end
end


--
-- Button Update callback functions
--
function AutoBarButton:SetTooltip(button)
	if ( GetCVar("UberTooltips") == "1" ) then
		GameTooltip_SetDefaultAnchor(GameTooltip, this);
	else
		GameTooltip:SetOwner(this, "ANCHOR_RIGHT");
	end

	local type = button:GetAttribute("type"); -- Mmm is self a good substitute here for button?
	if (type == "item") then
		local bag = button:GetAttribute("bag");
		local slot = button:GetAttribute("slot");

		if (bag and slot) then
			GameTooltip:SetBagItem(bag, slot);
		elseif (slot) then
			GameTooltip:SetInventoryItem("player", slot);
		end
		this.updateTooltip = TOOLTIP_UPDATE_TIME;
	elseif (type == "spell") then
		local spellName = button:GetAttribute("*spell*");

		if (spellName) then
--TODO:			GameTooltip:SetSpell(spellId, spellbookTabNum);
		end
		this.updateTooltip = TOOLTIP_UPDATE_TIME;
	else
		this.updateTooltip = nil;
	end
end


function AutoBarButton:UpdateUsable(button)
	local itemId = button:GetAttribute("itemId");
	local category = button:GetAttribute("category");

	local isUsable = nil;
	local notEnoughMana = nil;
	if (itemId) then
		isUsable, notEnoughMana = IsUsableItem(itemId);
	elseif (button:GetAttribute("*type1") == "spell") then
		isUsable = true;
	end
	if (isUsable and category and AutoBar_Category_Info[category] and AutoBar_Category_Info[category].battleground and not AutoBar.inBG) then
		isUsable = false;
		notEnoughMana = false;
	end
	if (isUsable) then
		button.icon:SetVertexColor(1.0, 1.0, 1.0);
		button.normalTexture:SetVertexColor(1.0, 1.0, 1.0);
	elseif (notEnoughMana) then
		button.icon:SetVertexColor(0.5, 0.5, 1.0);
		button.normalTexture:SetVertexColor(0.5, 0.5, 1.0);
	else
		button.icon:SetVertexColor(0.2, 0.2, 0.2);
		button.normalTexture:SetVertexColor(1.0, 1.0, 1.0);
	end
end


function AutoBarButton:UpdateCount(button)
	local countText = getglobal(button:GetName().."Count");
	local itemId = button:GetAttribute("itemId");
	local count = 0;
	if (itemId) then
		count = GetItemCount(tonumber(itemId));
	end

	if (count > 1) then
		countText:SetText(count);
	else
		countText:SetText("");
	end
end


function AutoBarButton:UpdateCooldown(button)
	local cooldown = getglobal(button:GetName().."Cooldown");
	local bag = button:GetAttribute("bag");
	local slot = button:GetAttribute("slot");
	local start, duration, enable;

	cooldown:Show();
	if (bag and slot) then
		start, duration, enable = GetContainerItemCooldown(bag, slot);
	elseif (slot) then
		start, duration, enable = GetInventoryItemCooldown("player", slot);
	end
	if (start and duration and enable and start > 0 and duration > 0) then
		CooldownFrame_SetTimer(cooldown, start, duration, enable);
	else
		CooldownFrame_SetTimer(cooldown, 0, 0, 0);
	end
end


function AutoBarButton:UpdateTexture(button)
--DEFAULT_CHAT_FRAME:AddMessage("AutoBar_Button_Update " .. button:GetName());
	local bag = button:GetAttribute("bag");
	local slot = button:GetAttribute("slot");
	local itemId = button:GetAttribute("itemId");
	local texture;

	if (itemId) then
		itemName,_,_,_,_,_,_,_,_,texture = GetItemInfo(tonumber(itemId));
	end
	if (not texture) then
		local spellName = button:GetAttribute("*spell2");
		if (spellName) then
			texture = BS:GetSpellIcon(spellName);
		end
	end
	if (not texture) then
		local category = button:GetAttribute("category");
		texture = AutoBar_GetTexture(category);
	end
	if (texture) then
		button.icon:SetTexture(texture);
		button.icon:Show();
		this.rangeTimer = -1;
	else
		button.icon:Hide();
		this.rangeTimer = nil;
		button.hotKey:SetVertexColor(0.6, 0.6, 0.6);
	end

	-- Add a green border if button is an equipped item
	if ((not bag) and slot) then
		button.border:SetVertexColor(0, 1.0, 0, 0.75);
		button.border:Show();
	else
		button.border:Hide();
	end

	if (GameTooltip:IsOwned(this)) then
		AutoBarButton:SetTooltip(button);
	else
		this.updateTooltip = nil;
	end

	-- Update Macro Text
--	local macroText = button:GetAttribute("macroText");
--	local macroName = getglobal(button:GetName().."Name");
--	macroName:SetText(macroText);
end


-- Handle a click on a button
function AutoBarButton:PreClick(mousebutton, down)
--	local button = this;
--	if (IsMounted()) then
--		Dismount();
--	end
end


-- Handle a click on a button
function AutoBarButton:PostClick(mousebutton, down)
	local button = this;
	if (down) then
		button:SetChecked(1);
	else
		button:SetChecked(0);
		button:SetNormalTexture("");
		button:SetPushedTexture("");
	end
end


-- Handle a click on a popped up button
function AutoBarButton:PopupPostClick(mousebutton, down)
	local popupButton = this;
	popupButton:SetChecked(0);
	popupButton:SetNormalTexture("");
	popupButton:SetPushedTexture("");

	local buttonsIndex = popupButton:GetAttribute("buttonsIndex");
	local buttonInfo = AutoBar.buttons[buttonsIndex];

--DEFAULT_CHAT_FRAME:AddMessage("AutoBarButton:PopupPostClick buttonsIndex " .. buttonsIndex);
	if (buttonInfo.arrangeOnUse and not InCombatLockdown()) then
		local popupButtonIndex = popupButton:GetAttribute("popupButtonIndex");
		if (popupButtonIndex == 0) then
			return
		end
		local currentItems = AutoBar_Buttons_CurrentItems[buttonsIndex][popupButtonIndex];
		local index;
		local itemId = popupButton:GetAttribute("itemId");
		local category = popupButton:GetAttribute("category");
		local update = false;
		for index = AUTOBAR_MAXSLOTCATEGORIES, 1, -1 do
			if (buttonInfo[index] == category) then
				-- First arrange the slot categories
				local targetIndex = table.maxn(buttonInfo);
				local temp = buttonInfo[index];
				if (index ~= targetIndex) then
					buttonInfo[index] = buttonInfo[targetIndex];
					buttonInfo[targetIndex] = temp;
					update = true;
				end
--DEFAULT_CHAT_FRAME:AddMessage("arrangeOnUse start " .. category .. " / " .. itemId);
				-- Arrange the category if allowed
				if (AutoBar_Category_Info[category] and AutoBar_Category_Info[category].arrangeOnUse) then
					local categoryList = AutoBar_Category_Info[category].items;
					for i, categoryItemId in ipairs(categoryList) do
--DEFAULT_CHAT_FRAME:AddMessage("arrangeOnUse ".. i .. " / " .. categoryItemId);
						if (categoryItemId == itemId and i ~= table.maxn(categoryList)) then
							temp = categoryList[i];
--DEFAULT_CHAT_FRAME:AddMessage("arrangeOnUse ".. temp);
							table.remove(categoryList, i);
							table.insert(categoryList, temp);
							update = true;
							break;
						end
					end
				end
				if (update) then
					AutoBar.ConfigChanged();
				end
				break;
			end
		end
	end
end


-- Set the visual look and feel for the button
function AutoBarButton:InitializeVisual(button)
	button:RegisterForClicks("LeftButtonDown", "RightButtonDown", "LeftButtonUp", "RightButtonUp");

	button:SetPushedTexture("");

	local buttonName = button:GetName();
	local oldNT = _G[buttonName.."NormalTexture"];
	oldNT:Hide();

	button.normalTexture = button:CreateTexture(buttonName .. "BTNT");
	button.normalTexture:SetAllPoints(oldNT);

	button.border = _G[buttonName.."Border"];
--	button.border:SetAllPoints(button);

	button.hotKey = _G[buttonName.."HotKey"];
	button.icon = _G[buttonName.."Icon"];
end


-- Set the visual look and feel for the button
function AutoBarButton:SetVisual(baseName)
	local button = _G[baseName];
	local buttonWidth, buttonHeight = AutoBar:GetButtonSize();
	local scale = buttonWidth / 36;
	local alpha = AutoBar.display.alpha / 10;

	local countText = _G[baseName.."Count"];
	local cooldown = _G[baseName.."Cooldown"];

	button:SetAlpha(alpha);
	button.normalTexture:SetAlpha(alpha);
	button:SetWidth(buttonWidth);
	button:SetHeight(buttonHeight);
	button:SetScale(scale);
--	button.border:SetWidth(2*buttonWidth*62/36);
--	button.border:SetHeight(2*buttonHeight*62/36);
--	button.border:SetTexCoord(0, 1, 0, 1);
-- /script AutoBarSAB1.border:SetHeight(72)
	AutoBar:RefreshStyle(button);

	local fonttext, fontsize, fontoptions;
	if (AutoBar.display.hideKeyText) then
		button.hotKey:Hide();
	else
		fonttext, fontsize, fontoptions = button.hotKey:GetFont();
		button.hotKey:SetJustifyH("LEFT");
		button.hotKey:SetJustifyV("TOP");
		button.hotKey:SetPoint("TOPLEFT", baseName, "TOPLEFT", 2, -2);
		button.hotKey:Show();
	end
	if (AutoBar.display.hideCount) then
		countText:Hide();
	else
		countText:Show();
		fonttext, fontsize, fontoptions = countText:GetFont();
		countText:SetFont(fonttext, 14 * scale, fontoptions);
	end

	cooldown:SetScale(math.max(buttonWidth-1, buttonHeight-1) / 36);
end




-- /script DEFAULT_CHAT_FRAME:AddMessage(tostring(AutoBarProfile.basic[2].castSpell))
-- /script DEFAULT_CHAT_FRAME:AddMessage(tostring(AutoBar.buttons[2].castSpell))
