--[[------------------------------------------------------------------
--SousChef.lua
--Author: Wobin
--v0.0.1

inspired by ingeniousclown's Research Assistant

------------------------------------------------------------------]]--
local LAM = LibStub:GetLibrary("LibAddonMenu-1.0")
local BACKPACK = ZO_PlayerInventoryBackpack
local BANK = ZO_PlayerBankBackpack
local GUILD_BANK = ZO_GuildBankBackpack

local COOKING_RANK_1 = [[SousChef\media\One.dds]]
local COOKING_RANK_2 = [[SousChef\media\Two.dds]]
local COOKING_RANK_3 = [[SousChef\media\Three.dds]]
local COOKING_RANK_4 = [[SousChef\media\Four.dds]]
local COOKING_RANK_5 = [[SousChef\media\Five.dds]]
local COOKING_RANK_6 = [[SousChef\media\Six.dds]]
local COOKING = { COOKING_RANK_1, COOKING_RANK_2, COOKING_RANK_3, COOKING_RANK_4, COOKING_RANK_5, COOKING_RANK_6 }
local CANLEARN = [[/esoui/art/loot/loot_finesseitem.dds]]
local containerHooks = { INVENTORY_BACKPACK, INVENTORY_BANK, INVENTORY_GUILD_BANK }
local itemQuality = { ITEM_QUALITY_MAGIC = { 0, 0, 1 }, ITEM_QUALITY_NORMAL = {1,1,1}, ITEM_QUALITY_ARCANE = {1, 0, 1}}
local Pantry = {}
local Cookbook = {}
local ReverseCookbook = {}
local settings = nil
local slotLines = {}
local hookedFunctions = {}

local function GetItemID(link)
	return tonumber(string.match(string.match(link, "%d+:"), "%d+"))
end

local function MatchInCookbook(bag, slot)
	return Cookbook[GetItemName(bag, slot):lower():gsub(" ","")]
end

local function MatchInGlobalCookbook(bag, slot)
	return settings.Cookbook[GetItemName(bag,slot):lower():gsub(" ", "")]
end

local function AddDetails(row)
	if not row.dataEntry or not row.dataEntry.data or row.AddedRecipes then return false end
	local bagId = row.dataEntry.data.bagId
	local slotIndex = row.dataEntry.data.slotIndex
	if ((GetItemCraftingInfo(bagId, slotIndex)) ~= CRAFTING_TYPE_PROVISIONING) then	return false end

	local usableIngredient = ReverseCookbook[GetItemID(GetItemLink(bagId, slotIndex))]
	if usableIngredient then
		ItemTooltip:AddLine("Used in:")
		for i,v in ipairs(usableIngredient) do
			ItemTooltip:AddLine(v)
		end
		row.AddedRecipes = true
	end
	return false
end



rowHandler = {}

local function AddRankToSlot(row)
	local bagId = row.dataEntry.data.bagId
	local slotIndex = row.dataEntry.data.slotIndex

	local rankIcon = slotLines[row:GetName()]
	if(not rankIcon) then
		rankIcon =  WINDOW_MANAGER:CreateControl(row:GetName() .. "SousChef", row, CT_TEXTURE)
		slotLines[row:GetName()] = rankIcon
		ZO_PreHookHandler(row, "OnMouseDown", AddDetails)
		ZO_PreHookHandler(row, "OnMouseUp", function(self) self.AddedRecipes = nil end )
	end

	-- Allow for ingeniousclown's Inventory Grid View
	if row:GetWidth() - row:GetHeight() < 5 then	-- if we're mostly square
		rankIcon:SetDimensions(20,20)
		rankIcon:SetAnchor(TOPLEFT, row, TOPLEFT, 2)
	else
		rankIcon:SetDimensions(30, 30)
		rankIcon:SetAnchor(CENTER, row, CENTER, 200)
	end

	rankIcon:SetHidden(true)

	if ((GetItemCraftingInfo(bagId, slotIndex)) == CRAFTING_TYPE_PROVISIONING) then
		local texture = Pantry[GetItemID(GetItemLink(bagId, slotIndex))]
		if texture then
			rankIcon:SetColor(settings.colour[1], settings.colour[2], settings.colour[3])
			rankIcon:SetHidden(false)
			rankIcon:SetTexture(COOKING[texture])


		end
	else
		if GetItemType(bagId, slotIndex) == ITEMTYPE_RECIPE then
			local match = MatchInCookbook(bagId, slotIndex)
			local gmatch = MatchInGlobalCookbook(bagId, slotIndex)
			if (match and settings.checkKnown == "known") or
			   (not match and settings.checkKnown == "unknown")then
				rankIcon:SetTexture(CANLEARN)
				rankIcon:SetHidden(false)
				if not match and gmatch and settings.checkKnown == "unknown" and settings.markAlt then
					rankIcon:SetColor(1,1,1,0.2)
				else
					rankIcon:SetColor(1,1,1,1)
				end
			end
		end

	end
end

local function ParseRecipes()
	local lists = GetNumRecipeLists()
	for listIndex = 1, lists do
		local name, count = GetRecipeListInfo(listIndex)
		for recipeIndex = 1, count do
			if GetRecipeInfo(listIndex, recipeIndex) then
				-- Store the recipes known
				Cookbook[(GetRecipeResultItemInfo(listIndex, recipeIndex)):gsub(" ",""):lower() .. "recipe"] = true
				settings.Cookbook[(GetRecipeResultItemInfo(listIndex, recipeIndex)):gsub(" ",""):lower() .. "recipe"] = true
				local _, _, ingredientCount, level = GetRecipeInfo(listIndex, recipeIndex)
				for ingredientIndex = 1, ingredientCount do
					local link = GetItemID(GetRecipeIngredientItemLink(listIndex, recipeIndex, ingredientIndex, LINK_STYLE_NORMAL))
					-- Store the fact that the ingredient is used
					Pantry[link] = level
					-- Store the recipe it's used in
					if not ReverseCookbook[link] then ReverseCookbook[link] = {} end
					table.insert(ReverseCookbook[link], GetRecipeResultItemLink(listIndex, recipeIndex, LINK_STYLE_BRACKETS))
				end
			end

		end
	end
end

local function SousChefCreateSettings()
	local panel = LAM:CreateControlPanel("SousChef", "Sous Chef")

	LAM:AddHeader(panel, "SousChef_General", "Settings")

  	LAM:AddDropdown(panel, "markLearnt", "Mark if recipes are ",
						"How do you want Sous Chef to indicate your knowledge of a recipe?",
						{"known", "unknown"}, function() return settings.checkKnown end,
						function(valueString) settings.checkKnown = valueString end)
	LAM:AddCheckbox(panel, "markAltKnows", "Alternate Character Check", "Indicate if an alt knows the recipe on unknown recipes. Will only work if the above setting is set to 'unknown'",
						function() return settings.markAlt end,
						function(value) settings.markAlt = not settings.markAlt end)
	LAM:AddColorPicker(panel, "setColour", "Indicator colour",
						"Allows you to set the colour of the indicator",
						function() return settings.colour[1], settings.colour[2], settings.colour[3] end,
						function(r,g,b) settings.colour[1] = r; settings.colour[2] = g; settings.colour[3] = b end)

end

local function SousChef_Loaded(eventCode, addOnName)

	if(addOnName ~= "SousChef") then
        return
    end

	local defaults = {
		watching = true,
		checkKnown = "unknown",
		markAlt = false,
		colour = {1, 1, 1},
		Cookbook = {}
	}

	settings = ZO_SavedVars:NewAccountWide("SousChef_Settings", 3, nil, defaults)

    SLASH_COMMANDS["/SousChef"] = function()
    	settings.watching = not settings.watching
    	if settings.watching then
    		d("Sous Chef is now ON")
    		CheckNow(BACKPACK)
    		CheckNow(BANK)
    		CheckNow(GUILD_BANK)
    	else
    		d("Sous Chef is now OFF")
    		for _,v in pairs(slotLines) do
    			v:SetHidden(true)
    		end
    	end
	end
	SLASH_COMMANDS["/SCDebug"] = function()
		d("Debug mode on")
		SCCookbook = Cookbook
		SCRCookbook = ReverseCookbook
		SCPantry = Pantry
		SCslotList = slotLines
		SCsettings = settings
	end

	SousChefCreateSettings()

	ParseRecipes()

	SLASH_COMMANDS["/sc"] = SLASH_COMMANDS["/SousChef"]

	-- Now we want to hook into the function that sets the details on the inventory slot
	for _,v in pairs(PLAYER_INVENTORY.inventories) do
		local listView = v.listView
		if listView and listView.dataTypes and listView.dataTypes[1] then
			hookedFunctions = listView.dataTypes[1].setupCallback

			listView.dataTypes[1].setupCallback =
				function(rowControl, slot)
					hookedFunctions(rowControl, slot)
					AddRankToSlot(rowControl)
				end
		end
	end
	ZO_ScrollList_RefreshVisible(BACKPACK)
	ZO_ScrollList_RefreshVisible(BANK)
	ZO_ScrollList_RefreshVisible(GUILD_BANK)



	--[[ Hook into the tooltip
	-- This causes security errors, will have to reconsider
	SousChefTooltip = ZO_InventorySlot_OnMouseEnter
	function ZO_InventorySlot_OnMouseEnter(...)
		local control = ...
		CallSecureProtected("SousChefTooltip", control, ...)
		AddDetails(control)
	end--]]
end

local function SousChef_Initialized()
	EVENT_MANAGER:RegisterForEvent("SousChefLoaded", EVENT_ADD_ON_LOADED, SousChef_Loaded)
end



SousChef_Initialized()