hooksecurefunc (_G, "BattlePetToolTip_Show",
  function(speciesID, ...)
    Auctionator.Tooltip.AddPetTip(speciesID)
  end
)

-- This is called when mousing over an item in your bags
hooksecurefunc (GameTooltip, "SetBagItem",
  function(tip, bag, slot)
    local itemLocation = ItemLocation:CreateFromBagAndSlot(bag, slot)

    if itemLocation:IsValid() then
      local itemLink = C_Item.GetItemLink(itemLocation);
      local itemCount = C_Item.GetStackCount(itemLocation)

      Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
    end
  end
);

-- This is called when mousing over an item in a merchant window (Buyback Pane)
hooksecurefunc (GameTooltip, "SetBuybackItem",
  function(tip, slotIndex)
    local itemLink = GetBuybackItemLink(slotIndex)
    local _, _, _, itemCount = GetBuybackItemInfo(slotIndex);

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
  end
);

-- This is called when mousing over an item in a merchant window (Merchant Pane)
hooksecurefunc (GameTooltip, "SetMerchantItem",
  function(tip, index)
    local itemLink = GetMerchantItemLink(index)
    local _, _, _, itemCount = GetMerchantItemInfo(index);

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
  end
);

-- This is called when mousing over an item in your bank, or a bag in your bag list
hooksecurefunc (GameTooltip, "SetInventoryItem",
  function(tip, unit, slot)
    local itemLink = GetInventoryItemLink(unit, slot)
    local itemCount = GetInventoryItemCount(unit, slot)

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount ~= 0 and itemCount or 1)
  end
);

-- This is called when mousing over an item in your guild bank
-- Guild banks don't keep track of pets inside them correctly, so showing the AH
-- price is difficult.
hooksecurefunc (GameTooltip, "SetGuildBankItem",
  function(tip, tab, slot)
    local itemLink = GetGuildBankItemLink(tab, slot)
    local _, itemCount = GetGuildBankItemInfo(tab, slot)

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
  end
);

-- This is called when mousing over the result item on a recipe page in the tradeskill window
hooksecurefunc( GameTooltip, 'SetRecipeResultItem',
  function(tip, recipeResultItemId)
    local itemLink = C_TradeSkillUI.GetRecipeItemLink(recipeResultItemId)

    local itemCount  = C_TradeSkillUI.GetRecipeNumItemsProduced(recipeResultItemId)

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
  end
);

-- This is called when mousing over a reagant item on a recipe page in the tradeskill window
hooksecurefunc( GameTooltip, 'SetRecipeReagentItem',
  function( tip, reagentId, index )
    local itemLink = C_TradeSkillUI.GetRecipeReagentItemLink(reagentId, index)

    local itemCount = select(3, C_TradeSkillUI.GetRecipeReagentInfo(reagentId, index))

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
  end
);

-- This is called when mousing over an item in the loot window
hooksecurefunc (GameTooltip, "SetLootItem",
  function (tip, slot)
    if LootSlotHasItem(slot) then
      local itemLink, _, itemCount = GetLootSlotLink(slot);

      Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
    end
  end
);

-- TODO Haven't tested this so making an educated guess:
-- This is called when mousing over an item in the loot roll window
hooksecurefunc (GameTooltip, "SetLootRollItem",
  function (tip, slot)
    local itemLink = GetLootRollItemLink(slot)

    local _, _, itemCount = GetLootRollItemInfo(slot)

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
  end
);

-- This is called when mousing over an item in a quest window
hooksecurefunc (GameTooltip, "SetQuestItem",
  function (tip, type, index)
    local itemLink = GetQuestItemLink(type, index)

    local _, _, itemCount = GetQuestItemInfo(type, index);

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
  end
);

-- This is called when mousing over an item in a quest description in your quest log
hooksecurefunc (GameTooltip, "SetQuestLogItem",
  function (tip, type, index)
    local itemLink = GetQuestLogItemLink(type, index)

    local itemCount;
    if type == "choice" then
      _, _, itemCount = GetQuestLogChoiceInfo(index);
    else
      _, _, itemCount = GetQuestLogRewardInfo(index)
    end

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
  end
);

-- This is called when mousing over an item in the send mail window
hooksecurefunc (GameTooltip, "SetSendMailItem",
  function (tip, id)
    local _, _, _, itemCount = GetSendMailItem(id)
    local itemLink = GetSendMailItemLink(id);

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
  end
);

-- This occurs when:
-- 1. mousing over an item in the Open Mail frame
-- 2. mousing over an item in the Inbox frame
hooksecurefunc (GameTooltip, "SetInboxItem",
  function(tip, index, attachIndex)
    if Auctionator.Config.Get(Auctionator.Config.Options.MAILBOX_TOOLTIPS) then
      local attachmentIndex = attachIndex or 1

      local itemLink = GetInboxItemLink(index, attachmentIndex)

      local _, _, _, itemCount = GetInboxItem(index, attachmentIndex);

      Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
    end
  end
);

-- This occurs when mousing over an item in the Inbox frame
hooksecurefunc("InboxFrameItem_OnEnter",
  function(self)
    local itemCount = select(8, GetInboxHeaderInfo(self.index))
    local tooltipEnabled =
      Auctionator.Config.Get(Auctionator.Config.Options.MAILBOX_TOOLTIPS) and  (
      Auctionator.Config.Get(Auctionator.Config.Options.VENDOR_TOOLTIPS) or
      Auctionator.Config.Get(Auctionator.Config.Options.AUCTION_TOOLTIPS) or
      Auctionator.Config.Get(Auctionator.Config.Options.ENCHANT_TOOLTIPS)
    )

    if tooltipEnabled and itemCount and itemCount > 1 then
      local itemEntries = {}
      local name, itemCount, itemLink

      for attachmentIndex = 1, ATTACHMENTS_MAX_RECEIVE do
        name, _, _, itemCount = GetInboxItem(self.index, attachmentIndex)

        if name then
          itemLink = GetInboxItemLink(self.index, attachmentIndex)

          table.insert(itemEntries, {
            link = itemLink,
            count = itemCount,
            name = name
          })
        end
      end

      Auctionator.Tooltip.ShowTipWithMultiplePricing(GameTooltip, itemEntries)
    end
  end
);

-- This occurs when clicking on an item link (i.e. in chat)
hooksecurefunc(ItemRefTooltip, "SetHyperlink",
  function(tip, itemstring)
    local _, itemLink = GetItemInfo(itemstring);

    Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, 1)
  end
);

-- Occurs when mousing over  items I'm trading
hooksecurefunc (GameTooltip, "SetTradePlayerItem",
  function (tip, id)
    local itemLink = GetTradePlayerItemLink(id)
    if itemLink ~= nil then
      local _, _, itemCount = GetTradePlayerItemInfo(id);

      Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
    end
  end
);

-- Occurs when mousing over items other player are trading
hooksecurefunc (GameTooltip, "SetTradeTargetItem",
  function (tip, id)
    local itemLink = GetTradeTargetItemLink(id)
    if itemLink ~= nil then
      local _, _, itemCount = GetTradeTargetItemInfo(id)

      Auctionator.Tooltip.ShowTipWithPricing(tip, itemLink, itemCount)
    end
  end
);

function Auctionator.Tooltip.LateHooks()
  -- As AuctionHouseUtil doesn't exist until the AH is opened this cannot be
  -- called before the AH opens.
  hooksecurefunc(AuctionHouseUtil, "SetAuctionHouseTooltip",
    function(owner, rowData)
      if rowData.itemLink then
        Auctionator.Tooltip.ShowTipWithPricing(GameTooltip, rowData.itemLink, rowData.count ~= nil and rowData.count or 1 )

      elseif rowData.itemKey then
        if rowData.itemKey.battlePetSpeciesID ~= 0 then
          return
        end

        local itemLink = select(2, GetItemInfo(rowData.itemKey.itemID))

        if itemLink ~= nil then
          Auctionator.Tooltip.ShowTipWithPricing(GameTooltip, itemLink, rowData.count ~= nil and rowData.count or 1)
        end
      end
    end
  )
end
