--[[
	item.lua
		Functions used by the item slots in Bagnon
		
	TODO:
		Code review
		Ability to disable item borders 
--]]

BAGNON_HEX = {
	["a"] = 10,
	["b"] = 11,
	["c"] = 12,
	["d"] = 13,
	["e"] = 14,
	["f"] = 15,
	["0"] = 0,
	["1"] = 1,
	["2"] = 2,
	["3"] = 3,
	["4"] = 4,
	["5"] = 5,
	["6"] = 6,
	["7"] = 7,
	["8"] = 8,
	["9"] = 9,
};

--[[ 
	Item Button Constructor
		The dummyBag is purely for compatibility with mods that need the same structure as a blizzard bag
		Blizzard bag functions use item:GetID() to reference the item slot, and item:GetParent():GetID() to reference their bag
		
		I'm fairly certain that the memory impact is still quite minimal.
--]]

function BagnonItem_Create(name, parent)
	local dummyBag = CreateFrame("Frame", nil, parent);
	
	--create the button
	local button = CreateFrame("Button", name, dummyBag);
	button:SetAlpha(parent:GetAlpha());
	button:SetHeight(37);
	button:SetWidth(37);
	
	--border texture
	local border = button:CreateTexture(name .. "Border", "OVERLAY");
	border:SetTexture("Interface\\Buttons\\UI-ActionButton-Border");
	border:SetBlendMode("ADD");
	border:SetHeight(68);
	border:SetWidth(68);
	border:SetPoint("CENTER", button, "CENTER", 0, 0.6);
	
	--icon texture
	local iconTexture = button:CreateTexture(name .. "IconTexture", "BORDER");
	iconTexture:SetAllPoints(button);
	
	--normal, pushed, highlight
	local normalTexture = button:CreateTexture(name .. "NormalTexture");
	normalTexture:SetTexture("Interface\\Buttons\\UI-Quickslot2");
	normalTexture:SetHeight(64);
	normalTexture:SetWidth(64);
	normalTexture:SetPoint("CENTER", button, "CENTER", 0, -1);
	button:SetNormalTexture(normalTexture);
	button:SetPushedTexture("Interface\\Buttons\\UI-Quickslot-Depress");
	button:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square");
	
	--font strings
	local count = button:CreateFontString(name .. "Count", "BORDER");
	count:SetFontObject(NumberFontNormal);
	count:SetPoint("BOTTOMRIGHT", button, "BOTTOMRIGHT", -2, 2);
	count:SetJustifyH("RIGHT");
	count:Hide();
	
	local stock = button:CreateFontString(name .. "Stock", "BORDER");
	stock:SetFontObject(NumberFontNormalYellow);
	stock:SetPoint("TOPLEFT", button, "TOPLEFT", 0, -2);
	stock:SetJustifyH("LEFT");
	stock:Hide();
	
	--cooldown model
	local cooldown = CreateFrame("Model", name .. "Cooldown", button, "CooldownFrameTemplate");
	cooldown:SetAllPoints(button);

	button:Hide();
	
	BagnonItem_SetScripts(button);
	
	return button;
end

function BagnonItem_SetScripts(button)
	--[[
	button:SetScript("OnUpdate", function()
		BagnonItem_OnUpdate()
	end);
	--]]
	
	button:SetScript("OnClick", function()
		BagnonItem_OnClick(arg1);
	end);
	
	button:SetScript("OnHide", function() 
		if ( this.hasStackSplit and (this.hasStackSplit == 1) ) then
			StackSplitFrame:Hide();
		end
	end);
	
	button:SetScript("OnEnter", function() 
		BagnonItem_OnEnter(this);
	end);
	
	button:SetScript("OnLeave", function()
		this.updateTooltip = nil;
		GameTooltip:Hide();
		ResetCursor();
	end);
	
	button:SetScript("OnDragStart", function() 
		BagnonItem_OnClick("LeftButton", 1);
	end);
	
	button:SetScript("OnReceiveDrag", function() 
		BagnonItem_OnClick("LeftButton", 1);
	end);
	
	button:RegisterForClicks("LeftButtonUp", "RightButtonUp");
	button:RegisterForDrag("LeftButton");
	
	--Fix for AxuItemMenus
	if(AxuItemMenus_DropDown) then
		button.SplitStack = function(itemButton, split) SplitContainerItem( itemButton:GetParent():GetID() , itemButton:GetID(), split); end;
	end
end

function BagnonItem_OnClick(mouseButton, ignoreModifiers)
	if ( this.isLink ) then
		if(this.hasItem) then
			if ( mouseButton == "LeftButton" ) then
				if ( IsControlKeyDown() ) then
					local itemSlot = this:GetID(); 
					local bagID = this:GetParent():GetID();
					local player = this:GetParent():GetParent().player;
					
					DressUpItemLink( (BagnonDB.GetItemData(player, bagID, itemSlot)) );
				elseif( IsShiftKeyDown() ) then
					local itemSlot = this:GetID(); 
					local bagID = this:GetParent():GetID();
					local player = this:GetParent():GetParent().player;
					
					ChatFrameEditBox:Insert( BagnonDB.GetItemHyperlink(player, bagID, itemSlot) );
				end
			end
		end
	else
		ContainerFrameItemButton_OnClick(mouseButton, ignoreModifiers);
	end
end

--[[
	Show tooltip on hover
--]]

function BagnonItem_OnEnter(item)
	--link case
	if(item.isLink) then
		if(item.hasItem)then
			GameTooltip:SetOwner(item);
			
			local itemSlot = item:GetID(); 
			local bagID = item:GetParent():GetID();
			local player = item:GetParent():GetParent().player;
			
			local link, count = BagnonDB.GetItemData(player, bagID, itemSlot);
			GameTooltip:SetHyperlink( link, count );
			
			Bagnon_AnchorTooltip(item);
		end
	--normal bag case
	else	
		--blizzard totally needs to make the bank item not a special case
		if( item:GetParent():GetID() == -1) then
			GameTooltip:SetOwner(item);
			GameTooltip:SetInventoryItem("player", BankButtonIDToInvSlotID( item:GetID() ) );
		--normal item case
		else
			ContainerFrameItemButton_OnEnter(item);
		end
		
		--Don't reposition tooltips for things using EnhTooltip
		if(not EnhTooltip) then
			Bagnon_AnchorTooltip(item);
		end
	end
end

function BagnonItem_OnUpdate()
	if ( GameTooltip:IsOwned(this) ) then
		BagnonItem_OnEnter(this);
	end
end

--[[
	Update Functions
--]]

-- Update the texture, lock status, and other information about an item
function BagnonItem_Update(item)
	local texture, itemCount, readable, locked;
	
	if( Bagnon_IsCachedItem(item) ) then
		item.isLink = 1;
		
		local itemSlot = item:GetID(); 
		local bagID = item:GetParent():GetID();
		local player = item:GetParent():GetParent().player;
		
		_, itemCount, texture = BagnonDB.GetItemData(player, bagID, itemSlot);
		BagnonItem_UpdateLinkBorder(item);
		
		if ( texture ) then
			item.hasItem = 1;
		else
			item.hasItem = nil;
		end
		
		--hide cooldown since there isn't one for linked items
		BagnonItem_UpdateCooldown(bagID, item);
	else
		item.isLink = nil;
		
		texture, itemCount, locked, _, readable = GetContainerItemInfo(item:GetParent():GetID(), item:GetID());
		BagnonItem_UpdateBorder(item);

		if ( texture ) then
			BagnonItem_UpdateCooldown(item:GetParent():GetID() , item);
			item.hasItem = 1;
		else
			getglobal(item:GetName() .. "Cooldown"):Hide();
			item.hasItem = nil;
		end
		
		SetItemButtonDesaturated(item, locked, 0.5, 0.5, 0.5);
		item.readable = readable;
	end
	
	--update texture and count
	SetItemButtonTexture( item, texture );
	SetItemButtonCount( item, itemCount );
end

function BagnonItem_UpdateBorder(button)
	local bagID = button:GetParent():GetID();
	
	if( BagnonSets.qualityBorders ) then
		--Adapted from OneBag.  The author had a clever idea of using the link to generate the color instead of getting the quality, then the color
		local link = ( GetContainerItemLink(bagID , button:GetID()) );
		if(link) then
			local _, _, hexString = strfind( link ,"|cff(%w+)|H");
			local red = ( 16 * BAGNON_HEX[string.sub(hexString, 1, 1)] + BAGNON_HEX[string.sub(hexString, 2, 2)] ) / 256;
			local green = ( 16 * BAGNON_HEX[string.sub(hexString, 3, 3)] + BAGNON_HEX[string.sub(hexString, 4, 4)] ) / 256;
			local blue = ( 16 * BAGNON_HEX[string.sub(hexString, 5, 5)] + BAGNON_HEX[string.sub(hexString, 6, 6)] ) / 256;
			if( red ~= green and red ~= blue ) then
				getglobal(button:GetName() .. "Border"):SetVertexColor(red, green, blue, 0.4);
				getglobal(button:GetName() .. "Border"):Show();
			else
				getglobal(button:GetName() .. "Border"):Hide();
			end
		else
			getglobal(button:GetName() .. "Border"):Hide();
		end		
	else
		getglobal(button:GetName() .. "Border"):Hide();
	end
	
	--ammo slot coloring
	if( bagID == KEYRING_CONTAINER ) then
		getglobal(button:GetName() .. "NormalTexture"):SetVertexColor(1, 0.7, 0);
	elseif( Bagnon_IsAmmoBag( bagID ) ) then
		getglobal(button:GetName() .. "NormalTexture"):SetVertexColor(1, 1, 0);
	elseif( Bagnon_IsProfessionBag( bagID ) ) then
		getglobal(button:GetName() .. "NormalTexture"):SetVertexColor(0, 1, 0);
	else
		getglobal(button:GetName() .. "NormalTexture"):SetVertexColor(1, 1, 1);
	end
end

function BagnonItem_UpdateLinkBorder(item)
	local itemSlot = item:GetID(); 
	local bagID = item:GetParent():GetID();
	local player = item:GetParent():GetParent().player;
		
	if( BagnonSets.qualityBorders ) then	
		local itemLink = ( BagnonDB.GetItemData(player, bagID, itemSlot) );
		if( itemLink ) then
			local _, _, quality = GetItemInfo( itemLink );
			if(quality and quality > 1) then
				local red, green, blue = GetItemQualityColor(quality);		
				getglobal(item:GetName() .. "Border"):SetVertexColor(red, green, blue, 0.4);
				getglobal(item:GetName() .. "Border"):Show();
			else
				getglobal(item:GetName() .. "Border"):Hide();
			end
		else
			getglobal(item:GetName() .. "Border"):Hide();
		end
	else
		getglobal(item:GetName() .. "Border"):Hide();
	end
	
	if( bagID == KEYRING_CONTAINER ) then
		getglobal(item:GetName() .. "NormalTexture"):SetVertexColor(1, 0.7, 0);
	elseif( Bagnon_IsAmmoBag(bagID, player) ) then
		getglobal(item:GetName() .. "NormalTexture"):SetVertexColor(1, 1, 0);
	elseif( Bagnon_IsProfessionBag(bagID , player) ) then
		getglobal(item:GetName() .. "NormalTexture"):SetVertexColor(0, 1, 0);
	else
		getglobal(item:GetName() .. "NormalTexture"):SetVertexColor(1, 1, 1);
	end
end

--Update cooldown
function BagnonItem_UpdateCooldown(container, button)
	if(button.isLink) then
		CooldownFrame_SetTimer(getglobal(button:GetName().."Cooldown"), 0, 0, 0);
	else
		local cooldown = getglobal(button:GetName().."Cooldown");
		local start, duration, enable = GetContainerItemCooldown( container, button:GetID() );

		CooldownFrame_SetTimer(cooldown, start, duration, enable);

		if ( duration > 0 and enable == 0 ) then
			SetItemButtonTextureVertexColor(button, 0.4, 0.4, 0.4);
		end
	end
end