local scaningID, scaningLink, scaningStack
local scaningMoneyFound, scanningChargesFound
local scaningDurabilty, scaningDurabilityMax
local scanningIsSoulboundFound
local scanningIsUnsellableFound
local scaningStatsModFound = {}
ItemDataCache.ScaningStatsModFound = scaningStatsModFound
local scanStatsMod

--[[
--  to replace xml created tooltip

CreateFrame("GameTooltip", "ItemDataCacheTooltip")
ItemDataCacheTooltip:SetOwner(WorldFrame, "ANCHOR_NONE")
-- Allow tooltip SetX() methods to dynamically add new lines based on these
ItemDataCacheTooltip:AddFontStrings(
   ItemDataCacheTooltip:CreateFontString("$parentTextLeft1", nil, "GameTooltipText" ),
   ItemDataCacheTooltip:CreateFontString("$parentTextRight1", nil, "GameTooltipText" ))
--]]


function ItemDataCache.OnTooltipAddMoney(self, money)
--   ItemDataCache.Chatback("Caught adding money. ID: "..scaningID.." StackSize: "..scaningStack.." Price: "..money.." PriceForOne: "..(money/scaningStack))
--		ItemDataCache.Chatback(debugstack())
   scaningMoneyFound = money / scaningStack
end

ItemDataCacheTooltip:SetScript("OnTooltipAddMoney", ItemDataCache.OnTooltipAddMoney)

--[[
ARMOR_TEMPLATE = "%d Armor"; -- Item's armor display template
DAMAGE_TEMPLATE = "%d - %d Damage"; -- Weapon damage template
DAMAGE_TEMPLATE_WITH_SCHOOL = "%d - %d %s Damage";
DPS_TEMPLATE = "(%.1f damage per second)";
HP_TEMPLATE = "%d Health";
MAX_HP_TEMPLATE = "%d Max health";
PLUS_AMMO_DAMAGE_TEMPLATE = "+ %g damage per second";
PLUS_AMMO_SCHOOL_DAMAGE_TEMPLATE = "+ %g %s damage per second";
PLUS_DAMAGE_TEMPLATE = "+ %d - %d Damage";
PLUS_DAMAGE_TEMPLATE_WITH_SCHOOL = "+%d - %d %s Damage";
PLUS_SINGLE_DAMAGE_TEMPLATE = "+ %d Damage";
PLUS_SINGLE_DAMAGE_TEMPLATE_WITH_SCHOOL = "+%d %s Damage";
RESISTANCE_TEMPLATE = "%d %s";
SHIELD_BLOCK_TEMPLATE = "%d Block";
SINGLE_DAMAGE_TEMPLATE = "%d Damage";
SINGLE_DAMAGE_TEMPLATE_WITH_SCHOOL = "%d %s Damage"; -- Weapon damage template, for weapons doing school damage
ITEM_MOD_HASTE_SPELL_RATING = "Improves spell haste rating by %d.";
ITEM_MOD_HEALTH = "%c%d Health"; -- Item adds %d to health, %c is +/-
ITEM_SOULBOUND
ITEM_READABLE
ITEM_UNIQUE
ITEM_UNIQUE_EQUIPPABLE
ITEM_UNIQUE_MULTIPLE
ITEM_OPENABLE
--]]
local patternStatsMod = {}
ItemDataCache.PatternStatsMod = patternStatsMod
local initPatternStatsModDone

function ItemDataCache.InitStatModPatterns()
	for varName, varValue in pairs(_G) do
		local at, _, stat = strfind(varName, "^ITEM_MOD_(.+)")
		if at then
			-- %%.-d should catch %c%d too
			patternStatsMod[string.lower(stat)] = gsub(varValue, "%%.-d", "([+-]?%%d+)")
			 ItemDataCache.Chatback(patternStatsMod[string.lower(stat)])
		end
	end
	patternStatsMod.armor = gsub(ARMOR_TEMPLATE, "%%.-d", "(%%d+)")
	patternStatsMod.block = gsub(SHIELD_BLOCK_TEMPLATE, "%%.-d", "(%%d+)")
	initPatternStatsModDone = true
end

--[[ ITEM_SPELL_CHARGES changed to plural form in 2.4.2, and 
ITEM_SPELL_CHARGES_P1 removed {brykrys}
ITEM_SPELL_CHARGES = "%d |4Charge:Charges;"; -- Spell charges on an item
ITEM_SPELL_CHARGES_NONE = "No charges"; -- Used in the tooltip when charges = 0 on items that are not consumed
--]]
local function SplitPluralPattern (pattern)
	local head, singular, plural, tail = strmatch (pattern, "^(.*)|4(.+):(.+);(.*)$")
	head = head or ""
	tail = tail or ""
	if singular then
		singular = head..singular..tail
	end
	if plural then
		plural = head..plural..tail
	end

	return singular, plural
end
local patternItemSpellCharges, patternItemSpellChargesP1 = SplitPluralPattern(gsub(ITEM_SPELL_CHARGES, "%%.-d", "(%%d+)"))
SplitPluralPattern = nil -- no longer needed

local patternDurability = gsub(DURABILITY_TEMPLATE, "%%.-d", "(%%d+)")
-- local patternDurability = gsub(DURABILITY_TEMPLATE, "%%d", "(%%d+)")

function ItemDataCache.ScanTooltip()
	scanningChargesFound = false
	scaningDurability = nil
	scaningDurabilityMax = nil
	scanningIsSoulboundFound = false
	scanningIsUnsellableFound = false

	if (scanStatsMod or ItemDataCache.ScanStatsMod) then
		for stat, pattern in pairs(patternStatsMod) do
			scaningStatsModFound[stat] = nil
		end
	end
	for i = 2, ItemDataCacheTooltip:NumLines(), 1 do
		local line = getglobal("ItemDataCacheTooltipTextLeft"..i):GetText()
		if (line) then
			-- Do something with one tooltip line
--			 ItemDataCache.Chatback(line)
			-- Check for "No sell price"
			if (line == ITEM_UNSELLABLE) then
				scanningIsUnsellableFound = true
			elseif (line == ITEM_SOULBOUND) then
				scanningIsSoulboundFound = true
			end

			if not scanningChargesFound then
				scanningChargesFound = strmatch(line, patternItemSpellChargesP1) or strmatch(line, patternItemSpellCharges)
				if scanningChargesFound then
					scanningChargesFound = tonumber (scanningChargesFound)
				elseif strfind(line, ITEM_SPELL_CHARGES_NONE) then
					scanningChargesFound = 0
				end
			end

			if scaningDurabilityMax == nil then
			   scaningDurability, scaningDurabilityMax = strmatch(line, patternDurability)
--                           ItemDataCache.Chatback(line ..' = ' .. patternDurability)
-- 			   ItemDataCache.Chatback(scaningLink..": "..tostring(scaningDurability).."/"..tostring(scaningDurabilityMax))
			   if (scaningDurability and scaningDurabilityMax) then
				scaningDurability = tonumber(scaningDurability)
				scaningDurabilityMax = tonumber(scaningDurabilityMax)
			   end
		        end


			if (scanStatsMod or ItemDataCache.ScanStatsMod) then
				if (not initPatternStatsModDone) then ItemDataCache.InitStatModPatterns() end
				for stat, pattern in pairs(patternStatsMod) do
					-- ItemDataCache.Chatback("CHK: "..stat.." "..pattern.." "..line)
					local result = strmatch(line, pattern)
					if (result) then
						scaningStatsModFound[stat]=(scaningStatsModFound[stat] or 0)+tonumber(result)
						-- ItemDataCache.Chatback("RES: "..stat.." "..scaningStatsModFound[stat])
						break
					end
				end
			end
		end
	end
	if (scanStatsMod or ItemDataCache.ScanStatsMod) then
            scanStatsMod=false
            ItemDataCache.ScanStatsMod=false
        end

end

-- simplified version to find only one attribute (pattern)
function ItemDataCache.ScanTooltipPattern(pattern)
	for i=2, ItemDataCacheTooltip:NumLines(), 1 do
		local line = getglobal("ItemDataCacheTooltipTextLeft"..i):GetText()
		if (line and line == pattern) then return true end
	end
	return false
end

function ItemDataCache.TooltipScanBagItem(bag, slot)
	scaningMoneyFound = false
	ItemDataCacheTooltip:ClearLines()
	-- ItemDataCache.Chatback("Trying to scan "..bag.." "..slot..".")
	ItemDataCacheTooltip:SetBagItem(bag, slot)
	return ItemDataCache.ScanTooltip()
end

function ItemDataCacheTooltip.ScanHyperlink(item)
	scaningMoneyFound = false
	ItemDataCacheTooltip:ClearLines()
	ItemDataCacheTooltip:SetHyperlink(item)
	return ItemDataCache.ScanTooltip()
end

function ItemDataCache.TooltipScanBagItemIsSoulbound(bag, slot)
	ItemDataCacheTooltip:ClearLines()
	ItemDataCacheTooltip:SetBagItem(bag, slot)
	return ItemDataCache.ScanTooltipPattern(ITEM_SOULBOUND)
end

function ItemDataCache.DebugScanTooltip()
	for i=2, ItemDataCacheTooltip:NumLines(), 1 do
		local line=getglobal("ItemDataCacheTooltipTextLeft"..i):GetText()
		if (line) then
			ItemDataCache.Chatback(line)
		end
	end
end

local function ItemDataCacheInternal_InitRecipeClasses()
	if (ItemDataCache.InitLocalClassName(9, 3) and ItemDataCache.InitLocalClassName(9, 6) and ItemDataCache.InitLocalClassName(9, 8)) then
		-- self-destruct
		ItemDataCacheInternal_InitRecipeClasses = nil
	end
end

function ItemDataCache.PurgeLocalDataByID_maxcharges()
	if (ItemDataCacheInternal_InitRecipeClasses) then ItemDataCacheInternal_InitRecipeClasses() end
	local removed=0
	for index, value in pairs(ItemDataCacheLocal.ByID_maxcharges) do
		local class, subClass = ItemDataCache.Get.ByID_class(index)
		if ((class and subClass) and ((class==9 and subClass==3) or (class == 9 and subClass==6) or (class==9 and subClass==8))) then
			ItemDataCacheLocal.ByID_maxcharges[index] = nil
			removed = removed + 1
		end
	end
	ItemDataCache.Chatback("Finished local data purge for ByID_maxcharges. "..removed.." incorrect entries removed.")
	-- self-destruct
	ItemDataCache.PurgeLocalDataByID_maxcharges=nil
end

-- /script ItemDataCache.ScanBagsAtMerchant()
function ItemDataCache.ScanBagsAtMerchant()
 -- ItemDataCache.Chatback("Scanning...")
	if ((not MerchantFrame:IsVisible()) or InRepairMode()) then return end
	for bag = 0,NUM_BAG_FRAMES do
		for slot=1,GetContainerNumSlots(bag) do
			scaningLink = GetContainerItemLink(bag, slot)
			if (scaningLink) then
				local _
				scaningID = tonumber(strmatch(scaningLink, ".*item:(%d+):.*"))
				_, scaningStack = GetContainerItemInfo(bag, slot)
--				  ItemDataCache.Chatback("Trying to scan "..scaningLink.." ("..scaningID..").")
				ItemDataCache.TooltipScanBagItem(bag, slot)
				-- UpdateLocalDataByID will call OnUpdate which can call IDC function again and mess up
				-- file-scoped variable values.
				-- Let's save all we need to write data to DB now.
				local thisLink = scaningLink
				local thisID = scaningID
				local thisChargesFound = scanningChargesFound
				local thisMoneyFound = scaningMoneyFound
				local thisDurability = scaningDurability
				local thisDurabilityMax = scaningDurabilityMax
				local thisIsUnsellableFound = scanningIsUnsellableFound
				-- if(thisMoneyFound) then ItemDataCache.Chatback(thisMoneyFound) end
				if (thisChargesFound) then
					--ItemDataCache.Chatback(format("Found %d charges on %s.", thisChargesFound, scaningLink)) -- debug
					if (ItemDataCacheInternal_InitRecipeClasses) then ItemDataCacheInternal_InitRecipeClasses() end
					local class, subClass=ItemDataCache.Get.ByID_class(thisID)
					if((class and subClass) and ((class==9 and subClass==3) or (class==9 and subClass==6) or (class==9 and subClass==8))) then
						ItemDataCache.UpdateLocalDataByID("ByID_maxcharges", thisID, nil)
					else
						ItemDataCache.UpdateLocalDataByID("ByID_maxcharges", thisID, true)
					end
				end
				-- if(thisChargesFound) then ItemDataCache.Chatback(thisLink.." charges: "..tostring(thisChargesFound)..".") end
				-- ignore item and reset local price if item have charges and price is different from 0
				if (thisIsUnsellableFound) then
					ItemDataCache.UpdateLocalDataByID("ByID_selltovendor", thisID, 0)
				elseif (ItemDataCache.Get.ByID_maxcharges(thisID)) then
		--			ItemDataCache.Chatback(thisLink.." first pass")
					if (ItemDataCacheLocal.ByID_selltovendor[itemID] and ItemDataCacheLocal.ByID_selltovendor[itemID] ~= 0) then
						ItemDataCache.UpdateLocalDataByID("ByID_selltovendor", thisID, nil)
					end
				-- Only save item if it is at full durability
				else
--   				   ItemDataCache.Chatback(format(thisLink .. "Dura is %s over %s.", tostring(thisDurability), tostring(thisDurabilityMax))) -- debug
				   if (thisMoneyFound and thisDurability == thisDurabilityMax) then
 --  				    ItemDataCache.Chatback(format(" = Dura is %s over %s.", tostring(thisDurability), tostring(thisDurabilityMax))) -- debug
--   				    ItemDataCache.Chatback(format(" Updating %s to %s", thisLink, tostring(thisMoneyFound))) -- debug
				    ItemDataCache.UpdateLocalDataByID("ByID_selltovendor", thisID, thisMoneyFound)
				   end
				end
			end
		end
	end
end
