local DGV = DugisGuideViewer
if not DGV then return end

local WF = DGV:RegisterModule("DugisWatchFrame")
WF.essential = true

local function IncompatibleAddonLoaded()
	return DGV.carboniteloaded or DGV.sexymaploaded or DGV.nuiloaded or DGV.elvuiloaded or DGV.tukuiloaded or DGV.shestakuiloaded or DugisGuideUser.PetBattleOn
end

function WF:Initialize()
	local flashGroup, flash
	local L, RegisterFunctionReaction, RegisterMemberFunctionReaction = DugisLocals, DGV.RegisterFunctionReaction, DGV.RegisterMemberFunctionReaction
	
	function WF:ShouldModWatchFrame(forceLoaded)
		if forceLoaded then return true end
		return not IncompatibleAddonLoaded() and (WF.loaded or forceLoaded)
	end

	function WF:Reset()
	end
	
	local function GetBottomElement()
		return BONUS_OBJECTIVE_TRACKER_MODULE.lastBlock or ObjectiveTrackerBlocksFrame.currentBlock or
			DugisGuideViewer:IsModuleRegistered("SmallFrame") and DGV.SmallFrame.loaded and not DGV.SmallFrame.IsFloating() and DGV.SmallFrame.Frame
	end
	
	local header
	local function GetLeftElement()
		return ObjectiveTrackerBlocksFrame or
			DugisGuideViewer:IsModuleRegistered("SmallFrame") and DGV.SmallFrame.loaded and not DGV.SmallFrame.IsFloating() and header
	end
	
	local function GetObjectiveTrackerAnchorInfo()
		local anchorY = 0
		local buffsAnchorY = min(0, MINIMAP_BOTTOM_EDGE_EXTENT - BuffFrame.bottomEdgeExtent);
		-- Count right action bars
		local rightActionBars = 0;
		if ( IsNormalActionBarState() ) then
			if ( SHOW_MULTI_ACTIONBAR_3 ) then
				rightActionBars = 1;
				if ( SHOW_MULTI_ACTIONBAR_4 ) then
					rightActionBars = 2;
				end
			end
		end
		 
		-- Capture bars - need to move below buffs/debuffs if at least 1 right action bar is showing
		if ( NUM_EXTENDED_UI_FRAMES ) then
			local captureBar;
			local numCaptureBars = 0;
			for i=1, NUM_EXTENDED_UI_FRAMES do
				captureBar = _G["WorldStateCaptureBar"..i];
				if ( captureBar and captureBar:IsShown() ) then
					numCaptureBars = numCaptureBars + 1
					if ( numCaptureBars == 1 and rightActionBars > 0 ) then
						anchorY = min(anchorY, buffsAnchorY);
					end
					--captureBar:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", -CONTAINER_OFFSET_X, anchorY);
					anchorY = anchorY - captureBar:GetHeight() - 4;
				end
			end
		end
		 
		--Setup Vehicle seat indicator offset - needs to move below buffs/debuffs if both right action bars are showing
		if ( VehicleSeatIndicator and VehicleSeatIndicator:IsShown() ) then
			if ( rightActionBars == 2 ) then
				anchorY = min(anchorY, buffsAnchorY);
				--VehicleSeatIndicator:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", -100, anchorY);
			elseif ( rightActionBars == 1 ) then
				--VehicleSeatIndicator:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", -62, anchorY);
			else
				--VehicleSeatIndicator:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", 0, anchorY);
			end
			anchorY = anchorY - VehicleSeatIndicator:GetHeight() - 4;   --The -4 is there to give a small buffer for things like the QuestTimeFrame below the Seat Indicator
		end
		 
		-- Boss frames - need to move below buffs/debuffs if both right action bars are showing
		local numBossFrames = 0;
		for i = 1, MAX_BOSS_FRAMES do
			if ( _G["Boss"..i.."TargetFrame"]:IsShown() ) then
				numBossFrames = i;
			end
		end
		if ( numBossFrames > 0 ) then
			if ( rightActionBars > 1 ) then
				anchorY = min(anchorY, buffsAnchorY);
			end
			--Boss1TargetFrame:SetPoint("TOPRIGHT", "MinimapCluster", "BOTTOMRIGHT", -(CONTAINER_OFFSET_X * 1.3) + 60, anchorY * 1.333);  -- by 1.333 because it's 0.75 scale
			anchorY = anchorY - (numBossFrames * (68 + BOSS_FRAME_CASTBAR_HEIGHT) + BOSS_FRAME_CASTBAR_HEIGHT);
		end
		 
		-- Setup durability offset
		if ( DurabilityFrame ) then
			--DurabilityFrame:SetPoint("TOPRIGHT", "MinimapCluster", "BOTTOMRIGHT", -CONTAINER_OFFSET_X, anchorY);
			if ( DurabilityFrame:IsShown() ) then
				anchorY = anchorY - DurabilityFrame:GetHeight();
			end
		end
		 
		--[[if ( ArenaEnemyFrames ) then
			ArenaEnemyFrames:ClearAllPoints();
			ArenaEnemyFrames:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", -CONTAINER_OFFSET_X, anchorY);
		end
		 
		if ( ArenaPrepFrames ) then
			ArenaPrepFrames:ClearAllPoints();
			ArenaPrepFrames:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", -CONTAINER_OFFSET_X, anchorY);
		end]]
	 
		-- ObjectiveTracker - needs to move below buffs/debuffs if at least 1 right action bar is showing
		if ( rightActionBars > 0 ) then
			anchorY = min(anchorY, buffsAnchorY);
		end
	
		local numArenaOpponents = GetNumArenaOpponents();
		if ( ArenaEnemyFrames and ArenaEnemyFrames:IsShown() and (numArenaOpponents > 0) ) then
			return "ArenaEnemyFrame"..numArenaOpponents, 2, -35
		elseif ( ArenaPrepFrames and ArenaPrepFrames:IsShown() and (numArenaOpponents > 0) ) then
			return "ArenaPrepFrame"..numArenaOpponents, 2, -35
		else
			return "MinimapCluster", -OBJTRACKER_OFFSET_X, anchorY
		end
	end
	
	

	function WF:Update()
		if DugisGuideViewer:IsModuleRegistered("SmallFrame") then DGV:OnWatchFrameUpdate() end

		local bottomElement = GetBottomElement()
		if bottomElement then
			ObjectiveTrackerFrame.HeaderMenu:Show()
		end
		local anchorFrame, xOff, yOff = GetObjectiveTrackerAnchorInfo()
		if WF:ShouldModWatchFrame()
			and bottomElement
		then
			if ObjectiveTrackerFrame.collapsed then
				WF.WatchBackground:Hide()
				ObjectiveTrackerFrame:SetPoint("TOPRIGHT", anchorFrame, "BOTTOMRIGHT", xOff-3, yOff-13)
				ObjectiveTrackerFrame.HeaderMenu:SetPoint("TOPRIGHT", ObjectiveTrackerFrame, -10, 0)
			else
				if DGV:UserSetting(DGV_WATCHFRAMEBORDER) then
					DGV:SetFrameBackdrop(WF.WatchBackground, DGV.BACKGRND_PATH, DGV:GetBorderPath(), 10, 4, 12, 6)
					WF.WatchBackground:SetBackdropColor(0,0,0,1)
				else
					DGV:SetFrameBackdrop(WF.WatchBackground)
					WF.WatchBackground:SetBackdropColor(0,0,0,0)
				end
				WF.WatchBackground:ClearAllPoints()
				if DugisGuideViewer:IsModuleRegistered("SmallFrame") and DGV.SmallFrame.Frame and DGV.SmallFrame.loaded and not DGV.SmallFrame.IsFloating() then
					header:ClearAllPoints()
					header:SetPoint("TOPRIGHT", anchorFrame, "BOTTOMRIGHT", xOff-12, yOff-13)
					header:Show()
					DGV.SmallFrame:AnchorSmallFrame(header)
					ObjectiveTrackerFrame:SetPoint("TOPRIGHT", anchorFrame, "BOTTOMRIGHT", xOff-3, ((header:GetHeight() + DGV.SmallFrame.Frame:GetHeight() + 22) * -1) + yOff)
					ObjectiveTrackerFrame.HeaderMenu:SetPoint("TOPRIGHT", header, -1, 0)
				else
					header:Hide()
					ObjectiveTrackerFrame:SetPoint("TOPRIGHT", anchorFrame, "BOTTOMRIGHT", xOff-3, yOff-13)
					ObjectiveTrackerFrame.HeaderMenu:SetPoint("TOPRIGHT", ObjectiveTrackerFrame, -10, 0)
				end
				WF.WatchBackground:SetPoint("TOPRIGHT", anchorFrame, "BOTTOMRIGHT", xOff, yOff)
				WF.WatchBackground:SetPoint("BOTTOM", bottomElement, 0, -20)
				WF.WatchBackground:SetPoint("LEFT", GetLeftElement(), -40, 0)
				WF.WatchBackground:Show()
			end
		else
			WF.WatchBackground:Hide()
			ObjectiveTrackerFrame:SetPoint("TOPRIGHT", anchorFrame, "BOTTOMRIGHT", xOff, yOff)
			ObjectiveTrackerFrame.HeaderMenu:SetPoint("TOPRIGHT", ObjectiveTrackerFrame)
		end
        
        if DugisGuideViewer:IsModuleRegistered("SmallFrame") and DugisGuideViewer.SmallFrame.IsFloating ~= nil then
            if DugisGuideViewer.SmallFrame.IsFloating() then
                DugisGuideViewer.SmallFrame.Frame:SetClampedToScreen(true)
            else
                DugisGuideViewer.SmallFrame.Frame:SetClampedToScreen(false)
            end
        end
	end

	local objectiveTrackerUpdateReaction, manageFramePositionsReaction
	function WF:Load()
		objectiveTrackerUpdateReaction = RegisterFunctionReaction("ObjectiveTracker_Update", nil, WF.Update)
		manageFramePositionsReaction = RegisterFunctionReaction("UIParent_ManageFramePositions", nil, WF.Update)
		if DugisWatchBackground and (GetNumQuestWatches() > 0 or GetNumTrackedAchievements() > 0) then 
			WF.WatchBackground = DugisWatchBackground 
			WF.WatchBackground:Show()
			WF:Update()
		else
			WF.WatchBackground = CreateFrame("Frame", "DugisWatchBackground", ObjectiveTrackerFrame)
			WF.WatchBackground:SetFrameStrata("BACKGROUND")
			WF.WatchBackground:SetFrameStrata("LOW")
			header = CreateFrame("Frame", nil, WF.WatchBackground, "ObjectiveTrackerHeaderTemplate")
			DEFAULT_OBJECTIVE_TRACKER_MODULE:SetHeader(header, "Guides", OBJECTIVE_TRACKER_UPDATE_QUEST_ADDED)
		end

		function WF:PlayFlashAnimation()
			if not WF.FlashFrame then
				flashGroup, flash, WF.FlashFrame = DGV:CreateFlashFrame(DugisWatchBackground)
			end
			
			header.animating = true;
			header.HeaderOpenAnim:Stop();
			header.HeaderOpenAnim:Play();
			
			if WF:ShouldModWatchFrame() and DGV:UserSetting(DGV_WATCHFRAMEBORDER)
				and DGV:UserSetting(DGV_SMALLFRAMETRANSITION) == L["Flash"]
			then
				--DGV:DebugFormat("PlayFlashAnimation showing", "flashGroup", flashGroup)
				WF.FlashFrame:Show()
				WF.FlashFrame:SetWidth(WF.WatchBackground:GetWidth() - 14)
				WF.FlashFrame:SetHeight(WF.WatchBackground:GetHeight() - 17)
				flashGroup:Play()
			else
				WF.FlashFrame:Hide()
			end
		end
	end

	function WF:Unload()
		objectiveTrackerUpdateReaction:Dispose()
		manageFramePositionsReaction:Dispose()
		if WF.FlashFrame then WF.FlashFrame:Hide() end
		--SnapWatchFrame()
		if WF.WatchBackground then
			WF.WatchBackground:Hide()
			WF.WatchBackground = nil
		end
	end
end
