local E = select(2, ...) -- Engine
local CO,L,UF,AB,LT,AUR,TT,B = E:LoadModules("Config", "Locale", "Unitframes", "Actionbars", "Layout", "Auras", "Tooltip", "Blizzard")

local _
local HiddenFrame = CreateFrame("Frame")
local AddonLoader = CreateFrame("Frame")

local AlertFrameHolder = CreateFrame("Frame", "AlertFrameHolder", E.Parent)
do
	AlertFrameHolder:SetSize(64,64)
	AlertFrameHolder:SetPoint("CENTER", E.Parent, "CENTER")
end

local SlashCmdList = SlashCmdList
local PlayerPowerBarAlt = PlayerPowerBarAlt
local UnitPowerBarAlt_TearDown = UnitPowerBarAlt_TearDown
local UnitPowerBarAlt_SetUp = UnitPowerBarAlt_SetUp
local SlashCmdList = SlashCmdList
local SLASH_TEST_ALERTS1 = SLASH_TEST_ALERTS1


B.BlizzardFrames = {
	PlayerFrame,
	TargetFrame,
	FocusFrame,
	PartyFrame,
	CompactPartyFrame,
	OrderHallCommandBar,
	CastingBarFrame,
	MainMenuBar,
	Actionbars,
	--Micromenu,
	BuffFrame,
	--MinimapCluster,
	--ObjectiveTrackerFrame,
	--CastingBarFrame,
	CompactRaidFrame,
	CompactRaidFrameManager,
}
B.MovableFrames = { "AddonList","AudioOptionsFrame","BankFrame","BonusRollFrame","BonusRollLootWonFrame","BonusRollMoneyWonFrame","CharacterFrame","ChatConfigFrame","DressUpFrame","FriendsFrame","FriendsFriendsFrame","GameMenuFrame",
	"GossipFrame","GuildInviteFrame","GuildRegistrarFrame","HelpFrame","InterfaceOptionsFrame","ItemTextFrame","LFDRoleCheckPopup","LFGDungeonReadyDialog","LFGDungeonReadyStatus","LootFrame","MailFrame","MerchantFrame",
	"OpenMailFrame","PVEFrame","PetStableFrame","PetitionFrame","PVPReadyDialog","QuestFrame","QuestLogPopupDetailFrame","RaidBrowserFrame","RaidInfoFrame","RaidParentFrame","ReadyCheckFrame",
	"ReportCheatingDialog","RolePollPopup","ScrollOfResurrectionSelectionFrame","SpellBookFrame","SplashFrame","StackSplitFrame","StaticPopup1","StaticPopup2","StaticPopup3","StaticPopup4","TabardFrame",
	"TaxiFrame","TimeManagerFrame","TradeFrame","TutorialFrame","VideoOptionsFrame","WorldMapFrame", "CollectionsJournal"
}

B.MovableAddonFrames = {
	["Blizzard_AchievementUI"] = { "AchievementFrame" },
	["Blizzard_ArchaeologyUI"] = { "ArchaeologyFrame" },
	["Blizzard_ArtifactUI"] = { "ArtifactRelicForgeFrame" },
	["Blizzard_AuctionUI"] = { "AuctionFrame" },
	["Blizzard_BarberShopUI"] = { "BarberShopFrame" },
	["Blizzard_BindingUI"] = { "KeyBindingFrame" },
	["Blizzard_BlackMarketUI"] = { "BlackMarketFrame" },
	["Blizzard_Calendar"] = { "CalendarCreateEventFrame", "CalendarFrame", "CalendarViewEventFrame", "CalendarViewHolidayFrame" },
	["Blizzard_ChallengesUI"] = { "ChallengesKeystoneFrame" },
	["Blizzard_Collections"] = { "CollectionsJournal" },
	["Blizzard_EncounterJournal"] = { "EncounterJournal" },
	["Blizzard_GarrisonUI"] = { "GarrisonLandingPage", "GarrisonMissionFrame", "GarrisonCapacitiveDisplayFrame", "GarrisonBuildingFrame", "GarrisonRecruiterFrame", "GarrisonRecruitSelectFrame", "GarrisonShipyardFrame" },
	["Blizzard_GMChatUI"] = { "GMChatStatusFrame" },
	["Blizzard_GMSurveyUI"] = { "GMSurveyFrame" },
	["Blizzard_GuildBankUI"] = { "GuildBankFrame" },
	["Blizzard_GuildControlUI"] = { "GuildControlUI" },
	["Blizzard_GuildUI"] = { "GuildFrame", "GuildLogFrame" },
	["Blizzard_InspectUI"] = { "InspectFrame" },
	["Blizzard_ItemAlterationUI"] = { "TransmogrifyFrame" },
	["Blizzard_ItemSocketingUI"] = { "ItemSocketingFrame" },
	["Blizzard_ItemUpgradeUI"] = { "ItemUpgradeFrame" },
	["Blizzard_LookingForGuildUI"] = { "LookingForGuildFrame" },
	["Blizzard_MacroUI"] = { "MacroFrame" },
	["Blizzard_OrderHallUI"] = { "OrderHallTalentFrame" },
	["Blizzard_QuestChoice"] = { "QuestChoiceFrame" },
	["Blizzard_TalentUI"] = { "PlayerTalentFrame" },
	["Blizzard_TalkingHeadUI"] = { "TalkingHeadFrame" },
	["Blizzard_TradeSkillUI"] = { "TradeSkillFrame" },
	["Blizzard_TrainerUI"] = { "ClassTrainerFrame" },
	["Blizzard_VoidStorageUI"] = { "VoidStorageFrame" }
}

function B:RemoveBlizzard()
	for _, Frame in pairs(B.BlizzardFrames) do
		E:Remove(Frame)
	end
end

local function OnDragStart(self)
    self:StartMoving()
    self.isMoving = true
end

local function OnDragStop(self)
	self:StopMovingOrSizing()
	self.isMoving = false
end

function B:AddMovableFunc(F)
	F:EnableMouse(true)
	F:SetMovable(true)
	F:SetClampedToScreen(true)
	F:RegisterForDrag("LeftButton")

	F:SetScript("OnDragStart", OnDragStart)
	F:SetScript("OnDragStop", OnDragStop)
end

function B:MakeMovable()
	local Frame
	for _,f in pairs(B.MovableFrames) do
		-- f:HookScript("OnShow", function(self)
			Frame = _G[f]
			if Frame then
				B:AddMovableFunc(Frame)
			end
		-- end)
	end
end

-- Initial register if some addons are already loaded
-- Somehow those addons were already loaded and the method below would not work
-- This, for some reason, happens with ArkInventory. This is probably a taint issue
function B:TryToRegisterAllMovers()
	for addon, frames in pairs(B.MovableAddonFrames) do
		if IsAddOnLoaded(addon) then
			for _, v in pairs(frames) do
				B:AddMovableFunc(_G[v])
			end
		end
	end
end
-- /dump CUI:GetModule("Blizzard"):TryToRegisterAllMovers()
function B:RegisterAddonMover()
	AddonLoader:RegisterEvent("ADDON_LOADED")
	
	AddonLoader:SetScript("OnEvent", function(self, event, AddOn)
		if B.MovableAddonFrames[AddOn] then
			if IsAddOnLoaded(AddOn) then
				for _, v in pairs(B.MovableAddonFrames[AddOn]) do
					if _G[v] then
						B:AddMovableFunc(_G[v])
					end
				end
			end
		end
		
		return
	end)
end

function B:ToggleZoneAbility(state)
	-- We have to register/unregister a bunch of events here, since the frame otherwise would hide after a spellcast
	--has been made and the button normally would NOT exist!
	local self = ZoneAbilityFrame
	
	if state == true then
		self:UnregisterEvent("UNIT_AURA")
		self:UnregisterEvent("SPELL_UPDATE_COOLDOWN")
		self:UnregisterEvent("SPELL_UPDATE_USABLE")
		self:UnregisterEvent("SPELL_UPDATE_CHARGES")
		self:UnregisterEvent("SPELLS_CHANGED")
		self:UnregisterEvent("ACTIONBAR_SLOT_CHANGED")
		
		self:Show()
	else
		self:RegisterUnitEvent("UNIT_AURA", "player")
		self:RegisterEvent("SPELL_UPDATE_COOLDOWN")
		self:RegisterEvent("SPELL_UPDATE_USABLE")
		self:RegisterEvent("SPELL_UPDATE_CHARGES")
		self:RegisterEvent("SPELLS_CHANGED")
		self:RegisterEvent("ACTIONBAR_SLOT_CHANGED")
		
		self:Hide()
	end
end

function B:ToggleAltPowerBar(state)
	if state == true then
		UnitPowerBarAlt_SetUp(PlayerPowerBarAlt, 26)
		local textureInfo = {
			frame = { "Interface\\UNITPOWERBARALT\\UndeadMeat_Horizontal_Frame", 1, 1, 1 },
			background = { "Interface\\UNITPOWERBARALT\\Generic1Player_Horizontal_Bgnd", 1, 1, 1 },
			fill = { "Interface\\UNITPOWERBARALT\\Generic1_Horizontal_Fill", 0.16862745583057, 0.87450987100601, 0.24313727021217 },
			spark = { nil, 1, 1, 1 },
			flash = { "Interface\\UNITPOWERBARALT\\Meat_Horizontal_Flash", 1, 1, 1 },
		}
		for name, info in next, textureInfo do
			local texture = PlayerPowerBarAlt[name]
			local path, r, g, b = unpack(info)
			texture:SetTexture(path)
			texture:SetVertexColor(r, g, b)
		end

		PlayerPowerBarAlt:UpdateFill()
		PlayerPowerBarAlt:Show()
		
		E:UpdateMoverDimensions(PlayerPowerBarAlt)
	else
		UnitPowerBarAlt_TearDown(PlayerPowerBarAlt)
		PlayerPowerBarAlt:Hide()
	end
end

function B:RemoveFrameCluster(name, maxIndex)
	for i=1,maxIndex do
		local f = _G[string.format(name, i)]
		if f then			
			f:UnregisterAllEvents()
			f:Hide()
			
			f:SetParent(HiddenFrame)
		end
	end
end

function B:AddGameMenuButton()
	local width, height = _G["GameMenuButtonHelp"]:GetWidth(), _G["GameMenuButtonHelp"]:GetHeight()


	local button = CreateFrame("Button", "CUI_GameMenuConfigButton", _G["GameMenuButtonAddons"], "GameMenuButtonTemplate")
		button:SetWidth(width)
		button:SetHeight(height)
		button:SetScript("OnClick", function() if not InCombatLockdown() then CO:OpenOptions() ToggleGameMenu() else E:print("You cannot open the settings while in combat!") end end)
		button:SetText(string.format("|cff9482c9CUI %s|r", CHAT_CONFIGURATION))

	_G["GameMenuFrame"]:HookScript("OnShow", function()
			_G["GameMenuButtonLogout"]:ClearAllPoints()
			_G["GameMenuFrame"]:SetHeight(_G["GameMenuFrame"]:GetHeight() + 17 + (height * 1))
			button:SetPoint("BOTTOM", _G["GameMenuButtonAddons"], "CENTER", 0, -33)
		
		_G["GameMenuButtonLogout"]:SetPoint("BOTTOM", button, "CENTER", 0, -49)
	end)
end

function B:MoveAlerts()
	AlertFrame:ClearAllPoints()
	AlertFrame:SetPoint("TOP", AlertFrameHolder, "BOTTOM")
end

function B:Init()
	CO = E:GetModule("Config")
	HiddenFrame:Hide()
	
	B:RemoveFrameCluster("PartyMemberFrame%s", 4) -- Remove Blizz party frames
	B:RemoveFrameCluster("Boss%sTargetFrame", 5) -- Remove Blizz boss frames
	B:RemoveFrameCluster("ArenaEnemyFrame%s", 5) -- Remove Blizz arena frames
	B:MakeMovable() -- Make blizz frames movable
	B:RegisterAddonMover()
	B:TryToRegisterAllMovers()
	
	E:CreateMover(BNToastFrame, "BattleNet Notification")
	
		B:ToggleAltPowerBar(true) -- To get initial dimensions. Without this, the bar would never be visible, since the mover has no size at all (0, 0)
	E:CreateMover(PlayerPowerBarAlt, "Alternate Boss Energy")
		B:ToggleAltPowerBar(false) -- Hide the bar again
		
	E:CreateMover(VehicleSeatIndicator, L["vehicleSeatFrame"])
		
	E:CreateMover(AlertFrameHolder, "Alertframe Anchor")
	E:SecureHook(AlertFrame, "UpdateAnchors", B.MoveAlerts)
	-- @TODO: Create a mover for alert frames (loot, orderhall and garrison notifications a.e.)
	
	B:AddGameMenuButton()
	
--	CollectionsJournal:SetScript("OnShow", function(self) print(Show) end)
	
	SlashCmdList["TEST_ALERTS"] = function()
			PlaySound(12891)
			AchievementFrame_LoadUI()
			AchievementAlertSystem:AddAlert(5192)
			--MoneyWonAlertSystem:AddAlert(2171010101)
			--NewRecipeLearnedAlertSystem:AddAlert(204)
			--LegendaryItemAlertSystem:AddAlert("\124cffa335ee\124Hitem:18832::::::::::\124h[Brutality Blade]\124h\124r")
			--StorePurchaseAlertSystem:AddAlert("\124cffa335ee\124Hitem:180545::::::::::\124h[Mystic Runesaber]\124h\124r", "", "", 214)
	end
	SLASH_TEST_ALERTS1 = "/cuitestalerts"


	--[[ Code you can use for alert testing
			--Queued Alerts:
			/run AchievementAlertSystem:AddAlert(5192)
			/run CriteriaAlertSystem:AddAlert(9023, "Doing great!")
			/run LootAlertSystem:AddAlert("\124cffa335ee\124Hitem:18832::::::::::\124h[Brutality Blade]\124h\124r", 1, 1, 1, 1, false, false, 0, false, false)
			/run LootUpgradeAlertSystem:AddAlert("\124cffa335ee\124Hitem:18832::::::::::\124h[Brutality Blade]\124h\124r", 1, 1, 1, nil, nil, false)
			/run MoneyWonAlertSystem:AddAlert(815)
			/run NewRecipeLearnedAlertSystem:AddAlert(204)

			--Simple Alerts
			/run GuildChallengeAlertSystem:AddAlert(3, 2, 5)
			/run InvasionAlertSystem:AddAlert(1)
			/run WorldQuestCompleteAlertSystem:AddAlert(112)
			/run GarrisonBuildingAlertSystem:AddAlert("Barracks")
			/run GarrisonFollowerAlertSystem:AddAlert(204, "Ben Stone", 90, 3, false)
			/run GarrisonMissionAlertSystem:AddAlert(681) (Requires a mission ID that is in your mission list.)
			/run GarrisonShipFollowerAlertSystem:AddAlert(592, "Test", "Transport", "GarrBuilding_Barracks_1_H", 3, 2, 1)
			/run LegendaryItemAlertSystem:AddAlert("\124cffa335ee\124Hitem:18832::::::::::\124h[Brutality Blade]\124h\124r")
			/run StorePurchaseAlertSystem:AddAlert("\124cffa335ee\124Hitem:180545::::::::::\124h[Mystic Runesaber]\124h\124r", "", "", 214)
			/run DigsiteCompleteAlertSystem:AddAlert(1)

			--Bonus Rolls
			/run BonusRollFrame_StartBonusRoll(242969,1,179,1273,14)
		]]




	-- This adds an entry to every friendly player popup-menu
	--[[
		UnitPopupButtons["GUILD_INVITE"] = { text = "Invite to Guild", dist = 0 };

	-- Add it to the FRIEND and PLAYER menus as the 2nd to last option (before Cancel)
	table.insert(UnitPopupMenus["FRIEND"], #UnitPopupMenus["FRIEND"]-1, "GUILD_INVITE");
	table.insert(UnitPopupMenus["PLAYER"], #UnitPopupMenus["FRIEND"]-1, "GUILD_INVITE");
	]]--
end

E:AddModule("Blizzard", B)