if (not ItemDataCache) then ItemDataCache = {} end
local ItemDataCache = ItemDataCache
if (not ItemDataCacheLocal) then
	ItemDataCacheLocal = {}
end

local settings

function ItemDataCache:OnLoad()
	this:RegisterEvent("VARIABLES_LOADED")
	this:RegisterEvent("ADDON_LOADED")
--	this:RegisterEvent("PLAYER_ENTERING_WORLD")
	this:RegisterEvent("BAG_UPDATE")
	-- this:RegisterEvent("UNIT_INVENTORY_CHANGED")
	this:RegisterEvent("MERCHANT_SHOW")
	-- this:RegisterEvent("MERCHANT_UPDATE");
	-- this:RegisterEvent("PLAYER_LEAVING_WORLD")
end

function ItemDataCache.OnEvent(event, arg1)
	if (event == "VARIABLES_LOADED") then
		if(ItemDataCache.Init) then ItemDataCache.Init() end
		ItemDataCache.isLoaded = true
		return
	end
	if (event == "ADDON_LOADED") then
		--ItemDataCache.Chatback(arg1)
		if (arg1 == "Informant" and ItemDataCache.OverrideInformant) then ItemDataCache.OverrideInformant() end
		if (arg1 == "BtmScan" and ItemDataCache.OverrideInformant) then ItemDataCache.OverrideBtmScan() end
	end
	if (event == "MERCHANT_SHOW") then
		ItemDataCache.ScanBagsAtMerchant()
		return
	end
	if (event == "BAG_UPDATE") then
		-- For cases when you trade or equip/deequip with merchant window open
		if(arg1 >= 0 and arg1 <= NUM_BAG_FRAMES and MerchantFrame:IsVisible() and (not InRepairMode())) then
			ItemDataCache.ScanBagsAtMerchant()
		end
		return
	end
	if (event == "PLAYER_ENTERING_WORLD") then
--		ItemDataCacheTooltip:SetOwner(UIParent, "ANCHOR_NONE")
		return
	end
	if (event == "UNIT_INVENTORY_CHANGED") then
		return
	end
	if (event == "PLAYER_LEAVING_WORLD") then
		-- this:UnregisterEvent("UNIT_INVENTORY_CHANGED");
		return
	end
end

function ItemDataCache.Init()
--	ItemDataCacheTooltip:SetScript("OnTooltipAddMoney", ItemDataCache.OnTooltipAddMoney)

	if (not ItemDataCacheLocal.ClassSubclassRelations) then ItemDataCacheLocal.ClassSubclassRelations={} end
	ItemDataCache.InitLocalClassNameAll()

	if (not ItemDataCacheLocal.ByID_selltovendor) then ItemDataCacheLocal.ByID_selltovendor={} end
	ItemDataCache.OnInit.ByID_selltovendor()
	ItemDataCache.PurgeLocalData("ByID_selltovendor")

	if(not ItemDataCacheLocal.ByID_buyfromvendor) then ItemDataCacheLocal.ByID_buyfromvendor={} end
	ItemDataCache.PurgeLocalData("ByID_buyfromvendor")

	if(not ItemDataCacheLocal.ByID_maxcharges) then ItemDataCacheLocal.ByID_maxcharges={} end
	-- defined in ItemDataCache_Scan_Tooltip.lua
	-- Reviews local data for ByID_maxcharges and purges all recipes there when their class IDs become available
	ItemDataCache.PurgeLocalDataByID_maxcharges()

	if (not ItemDataCacheLocal.Settings) then ItemDataCacheLocal.Settings={} end
	settings = ItemDataCacheLocal.Settings

	-- hook what we can
	if ( ItemDataCache.OverrideBtmScan ) then ItemDataCache.OverrideBtmScan() end
	if ( ItemDataCache.OverrideInformant ) then ItemDataCache.OverrideInformant() end
	-- self-destruct
	ItemDataCache.Init = nil
end

-- Removes data from local dynamic cache that is already present in static cache
-- /script ItemDataCache.PurgeLocalData("ByID_selltovendor")
function ItemDataCache.PurgeLocalData(localTable)
	local purged, updated = 0, 0
	local getStaticDataFunction = ItemDataCache.Get[localTable]
	local staticData
	for index, value in pairs(ItemDataCacheLocal[localTable]) do
		staticData=getStaticDataFunction(index, true)
		if (staticData) then
			if (value == staticData) then
				ItemDataCacheLocal[localTable][index]=nil
				purged = purged+1
			else
				updated = updated+1
			end
		end
	end
	ItemDataCache.Chatback("Finished local data purge for "..localTable..". "..purged.." entries matching static cache freed. "..updated.." entries with data more recent than static cache found.")
end

-- if(not ItemDataCache.Get) then ItemDataCache.Get={} end
-- if (not ItemDataCache.OnUpdate) then ItemDataCache.OnUpdate = {} end
function ItemDataCache.Get.ByID_maxcharges(itemID)
	return ItemDataCacheLocal and ItemDataCacheLocal.ByID_maxcharges and ItemDataCacheLocal.ByID_maxcharges[itemID]
end
function ItemDataCache.OnUpdate.ByID_maxcharges() end

function ItemDataCache.UpdateLocalDataByID(localTable, itemID, value)
	-- if(itemID==10446) then ItemDataCache.Chatback(debugstack()) end
	local _, itemLink = GetItemInfo(itemID)
	if (value == nil) then
		if (ItemDataCacheLocal[localTable][itemID]) then ItemDataCache.Chatback(format("Resetting local data for table %s item %s.", localTable, itemLink)) end
		ItemDataCacheLocal[localTable][itemID] = nil
		return
	end
	local knownData = ItemDataCache.Get[localTable](itemID)
	if(not knownData) then
		if(not settings.noNewDataMessages) then ItemDataCache.Chatback(format("Found new data for table %s item %s: %s.", localTable, itemLink, tostring(value))) end
		ItemDataCacheLocal[localTable][itemID]=value
		ItemDataCache.OnUpdate[localTable]()
	elseif (knownData ~= value) then
		if(not settings.noUpdatedDataMessages) then ItemDataCache.Chatback(format("UPDATED data for table %s item %s: %s. (was %s)", localTable, itemLink, tostring(value), tostring(knownData))) end
		-- ItemDataCache.Chatback("Static data: "..tostring(staticData)..", Local data: "..tostring(localCacheData)..".")
		ItemDataCacheLocal[localTable][itemID] = value
		ItemDataCache.OnUpdate[localTable]()
	end
end

function ItemDataCache.Chatback(value)
	DEFAULT_CHAT_FRAME:AddMessage("<ItemDataCache> "..tostring(value))
end

-- Some debugging trash:
-- /script local _, itemLink=GetItemInfo("item:20752:0:0:0:0:0:0:0") DEFAULT_CHAT_FRAME:AddMessage(itemLink)
-- /script ItemDataCacheTooltip:SetHyperlink("item:12054:0:0:0:0:0:0:0") ItemDataCache.DebugScanTooltip()
-- /script ItemDataCache.Chatback(ItemDataCacheTooltip:NumLines())
-- /script ItemDataCache.Chatback(ItemDataCacheTooltip:GetText())
-- /script ItemDataCacheTooltip:ClearLines() ItemDataCacheTooltip:SetHyperlink("item:27635:0:0:0:0:0:0:0") ItemDataCache.Chatback(getglobal("ItemDataCacheTooltipTextLeft1"):GetText())
-- ItemDataCache.Chatback(patternItemSpellChargesP1)
-- ItemDataCache.Chatback(patternItemSpellCharges)
-- ItemDataCache.Chatback(patternDurability)

-- TODO?: ignore openable containers
