--[[
frame = [REQUIRED][FRAME] - The frame that is intended to open
showFunc = [OPTIONAL][FUNCTION] - This will happen when we recieve the event with this type.. If none is specified ShowUIPanel will be called by default.
hideFunc = [OPTIONAL][FUNCTION] - This happens on PLAYER_INTERACTION_FRAME_HIDE. If nothing is specified, HideUIPanel will be called.
loadFunc = [OPTIONAL][FUNCTION] - Only need to specify if the frame requires to be loaded before used.
]]
local InteractionManagerFrameInfo = {
	[Enum.PlayerInteractionType.Merchant] =
	{
		frame = "MerchantFrame",
		showFunc = "MerchantFrame_MerchantShow",
		hideFunc = "MerchantFrame_MerchantClosed"
	},
	[Enum.PlayerInteractionType.Banker] =
	{
		frame = "BankFrame",
		showFunc = "BankFrame_Open"
	},
	[Enum.PlayerInteractionType.CharacterBanker] =
	{
		frame = "BankFrame",
		showFunc = "BankFrame_Open"
	},
	[Enum.PlayerInteractionType.AccountBanker] =
	{
		frame = "BankFrame",
		showFunc = "BankFrame_Open"
	},
	[Enum.PlayerInteractionType.Trainer] =
	{
		frame = "ClassTrainerFrame",
		showFunc = "ClassTrainerFrame_Show",
		hideFunc = "ClassTrainerFrame_Hide",
		loadFunc = ClassTrainerFrame_LoadUI
	},
	[Enum.PlayerInteractionType.AlliedRaceDetailsGiver] =
	{
		frame = "AlliedRacesFrame",
		loadFunc = AlliedRaces_LoadUI,
		showFunc = nop;
	},
	[Enum.PlayerInteractionType.HousingBulletinBoard] =
	{
		frame = "HousingBulletinBoardFrame",
		loadFunc = function()
            if not HousingBulletinBoardFrame then
                C_AddOns.LoadAddOn("Blizzard_HousingBulletinBoard");
            end
        end,
	},
	[Enum.PlayerInteractionType.RenameNeighborhood] = 
	{
		frame = "NeighborhoodChangeNameDialog",
		loadFunc = function() 
			if not HousingBulletinBoardFrame then
				C_AddOns.LoadAddOn("Blizzard_HousingBulletinBoard");
			end
		end,
		showFunc = function()
			if not C_HousingNeighborhood.IsNeighborhoodManager() then
				UIErrorsFrame:AddExternalErrorMessage(ERR_HOUSING_RESULT_PERMISSION_DENIED);
				C_PlayerInteractionManager.ClearInteraction(Enum.PlayerInteractionType.RenameNeighborhood);
				return;
			end

			StaticPopupSpecial_Show(NeighborhoodChangeNameDialog);
			NeighborhoodChangeNameDialog.NameText:SetText(C_HousingNeighborhood.GetNeighborhoodName());
		end,
	},
	[Enum.PlayerInteractionType.OpenHouseFinder] =
	{
		frame = "HouseFinderFrame",
		loadFunc = function()
			if not HouseFinderFrame then
				C_AddOns.LoadAddOn("Blizzard_HousingHouseFinder");
			end
			ShowUIPanel(HouseFinderFrame);
		end,
	},
	[Enum.PlayerInteractionType.GuildBanker] =
	{
		frame = "GuildBankFrame",
		loadFunc = GuildBankFrame_LoadUI,
	},
	[Enum.PlayerInteractionType.Registrar] =
	{
		frame = "GuildRegistrarFrame"
	},
	[Enum.PlayerInteractionType.GuildTabardVendor] =
	{
		frame = "TabardFrame",
		showFunc = "TabardFrame_Open"
	},
	[Enum.PlayerInteractionType.PersonalTabardVendor] =
	{
		frame = "TabardFrame",
		showFunc = "TabardFrame_Open"
	},
	[Enum.PlayerInteractionType.MailInfo] =
	{
		frame = "MailFrame",
		showFunc = "MailFrame_Show",
		hideFunc = "MailFrame_Hide"
	},
	[Enum.PlayerInteractionType.Auctioneer] =
	{
		frame = "AuctionHouseFrame",
		showFunc = function()
			if ( GameLimitedMode_IsActive() ) then
				UIErrorsFrame:AddExternalErrorMessage(ERR_FEATURE_RESTRICTED_TRIAL);
				C_AuctionHouse.CloseAuctionHouse();
			else
				ShowUIPanel(AuctionHouseFrame);
			end
		end;
	},
	[Enum.PlayerInteractionType.Transmogrifier] =
	{
		frame = "TransmogFrame",
		loadFunc = Transmog_LoadUI,
	},
	[Enum.PlayerInteractionType.BlackMarketAuctioneer] = {
		frame = "BlackMarketFrame",
		showFunc = "BlackMarketFrame_Show",
		hideFunc = "BlackMarketFrame_Hide",
		loadFunc = BlackMarket_LoadUI,
	},
	[Enum.PlayerInteractionType.WorldMap] = {
		frame = "WorldMapFrame",
		showFunc = nop;
	},
	[Enum.PlayerInteractionType.GarrArchitect] = {
		frame = "GarrisonBuildingFrame",
		loadFunc = Garrison_LoadUI,
	},
	[Enum.PlayerInteractionType.Trophy] = {
		frame = "GarrisonMonumentFrame",
		showFunc = function() if C_Trophy and C_Trophy.MonumentLoadList then C_Trophy.MonumentLoadList() end end,
		loadFunc = Garrison_LoadUI
	},
	[Enum.PlayerInteractionType.ObliterumForge] = {
		frame = "ObliterumForgeFrame",
		loadFunc = ObliterumForgeFrame_LoadUI
	},
	[Enum.PlayerInteractionType.ScrappingMachine] = {
		frame = "ScrappingMachineFrame",
		loadFunc = ScrappingMachineFrame_LoadUI,
	},
	[Enum.PlayerInteractionType.ContributionCollector] = {
		frame = "ContributionCollectionFrame",
		loadFunc = function() UIParentLoadAddOn("Blizzard_Contribution") end;
	},
	[Enum.PlayerInteractionType.AzeriteRespec] = {
		frame = "AzeriteRespecFrame",
		loadFunc = AzeriteRespecFrame_LoadUI
	},
	[Enum.PlayerInteractionType.IslandQueue] = {
		frame = "IslandsQueueFrame",
		loadFunc = IslandsQueue_LoadUI
	},
	[Enum.PlayerInteractionType.ItemInteraction] = {
		frame = "ItemInteractionFrame",
		loadFunc = ItemInteraction_LoadUI
	},
	[Enum.PlayerInteractionType.ChromieTime] = {
		frame = "ChromieTimeFrame",
		loadFunc = ChromieTimeFrame_LoadUI
	},
	[Enum.PlayerInteractionType.WeeklyRewards] = {
		frame = "WeeklyRewardsFrame",
		loadFunc = WeeklyRewards_LoadUI,
		forceShow = true
	},
	[Enum.PlayerInteractionType.Soulbind] = {
		frame = "SoulbindViewer",
		loadFunc = function() C_AddOns.LoadAddOn("Blizzard_Soulbinds"); end;
		showFunc = function() SoulbindViewer:Open(); end;
	},
	[Enum.PlayerInteractionType.CovenantSanctum] = {
		frame = "CovenantSanctumFrame",
		loadFunc = CovenantSanctum_LoadUI,
		showFunc = function() CovenantSanctumFrame:InteractionStarted(); end;
	},
	[Enum.PlayerInteractionType.Renown] = {
		frame = "CovenantRenownFrame",
		loadFunc = CovenantRenown_LoadUI
	},
	[Enum.PlayerInteractionType.ItemUpgrade] = {
		frame = "ItemUpgradeFrame",
		loadFunc = ItemUpgrade_LoadUI,
		showFunc = "ItemUpgradeFrame_Show",
		hideFunc = "ItemUpgradeFrame_Hide"
	},
	[Enum.PlayerInteractionType.AzeriteForge] = {
		frame = "AzeriteEssenceUI",
		loadFunc = function() UIParentLoadAddOn("Blizzard_AzeriteEssenceUI"); end;
		showFunc = function() if AzeriteEssenceUI:TryShow() and AzeriteEssenceUI:ShouldOpenBagsOnShow() then OpenAllBags(AzeriteEssenceUI); end; end;
	},
	[Enum.PlayerInteractionType.AdventureJournal] = {
		frame = "EncounterJournal",
		loadFunc = EncounterJournal_LoadUI,
		showFunc = function () if (C_AdventureJournal.CanBeShown()) then ShowUIPanel(EncounterJournal); EJSuggestFrame_OpenFrame(); end; end;
	},
	[Enum.PlayerInteractionType.MajorFactionRenown] = {
		frame = "EncounterJournal",
		loadFunc = EncounterJournal_LoadUI,
		showFunc = function()
						local majorFactionID = C_MajorFactions.GetRenownNPCFactionID();
						HideUIPanel(EncounterJournal);
						if majorFactionID > 0 then
							ShowUIPanel(EncounterJournal);
							EJ_ContentTab_Select(EncounterJournal.JourneysTab:GetID());
							EncounterJournalJourneysFrame:ResetView(nil, majorFactionID);
						end
					end,
	},
	[Enum.PlayerInteractionType.GuildRename] = {
		frame = "GuildRenameFrame",
		loadFunc = function() UIParentLoadAddOn("Blizzard_GuildRename"); end,
		showFunc = function() GuildRenameFrame:BeginInteraction(); end,
	},
	[Enum.PlayerInteractionType.TieredEntrance] = {
		frame = "DelvesDifficultyPickerFrame",
		loadFunc = function() C_AddOns.LoadAddOn("Blizzard_DelvesDifficultyPicker"); end;
		showFunc = function() DelvesDifficultyPickerFrame:TryShow(textureKit); end;
	}
};

PlayerInteractionFrameManagerMixin = { };

function PlayerInteractionFrameManagerMixin:ShowFrame(interactionType)
	local frameInfo = InteractionManagerFrameInfo[interactionType];
	if not frameInfo then
		return;
	end

	if frameInfo.loadFunc and not _G[frameInfo.frame] then
		frameInfo.loadFunc();
	end

	if frameInfo.showFunc then
		if type(frameInfo.showFunc) == "string" then
			frameInfo.showFunc = _G[frameInfo.showFunc];
		end
		if frameInfo.showFunc then
			frameInfo.showFunc();
		end
	else
		ShowUIPanel(_G[frameInfo.frame], frameInfo.forceShow);
	end
end

function PlayerInteractionFrameManagerMixin:HideFrame(interactionType)
	local frameInfo = InteractionManagerFrameInfo[interactionType];
	if not frameInfo then
		return;
	end

	-- The frame isn't loaded, so nothing to hide.
	if not _G[frameInfo.frame] then
		return;
	end

	if frameInfo.hideFunc then
		if type(frameInfo.hideFunc) == "string" then
			frameInfo.hideFunc = _G[frameInfo.hideFunc];
		end
		if frameInfo.hideFunc then
			frameInfo.hideFunc();
		end
	else
		HideUIPanel(_G[frameInfo.frame]);
	end
end

function PlayerInteractionFrameManagerMixin:OnLoad()
	self:RegisterEvent("PLAYER_INTERACTION_MANAGER_FRAME_SHOW");
	self:RegisterEvent("PLAYER_INTERACTION_MANAGER_FRAME_HIDE");
end

function PlayerInteractionFrameManagerMixin:OnEvent(event, ...)
	if event == "PLAYER_INTERACTION_MANAGER_FRAME_SHOW" then
		local interactionType = ...;
		self:ShowFrame(interactionType);
	elseif event == "PLAYER_INTERACTION_MANAGER_FRAME_HIDE" then
		local interactionType = ...;
		self:HideFrame(interactionType);
	end
end
