local DGV = DugisGuideViewer
if not DGV then return end

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

local smallAndObjectiveFrameOneBkg = true

ObjectiveFrameDugiBkg = CreateFrame("Frame", "ObjectiveFrameDugiBkg", UIParent, "BackdropTemplate")
ObjectiveFrameDugiBkg:SetFrameStrata("BACKGROUND")
ObjectiveFrameDugiBkg:SetFrameLevel(8)
DugisGuideViewer.DoOutOfCombatCancelOld("ObjectiveFrameDugiBkg", ObjectiveFrameDugiBkg.Hide, ObjectiveFrameDugiBkg)

local function GetSmallFrame()
	if DugisGuideViewer.Modules.SmallFrame and DugisSmallFrameContainer and DugisGuideViewer.chardb.EssentialsMode ~= 1 then
		return DugisGuideViewer.Modules.SmallFrame
	end
end

local function IsObjectiveTrackerVisible()
	return ObjectiveTrackerFrame.HeaderMenu:IsVisible()  and not  ObjectiveTrackerFrame.collapsed  and ObjectiveFrameDugiBkg.initialized
end

function DGV.GetMultibarMargin()
	local marginRight = 10
	if MultiBarLeft:IsVisible() then
		marginRight = MultiBarLeft:GetWidth() * 2
	else
		if MultiBarRight:IsVisible() then
			marginRight = MultiBarRight:GetWidth()
		end
	end

	if DugisGuideViewer.luiloaded then
		marginRight = 35
	end		

	if LuaUtils:IsElvUIInstalled() then
		marginRight = marginRight + 30
	end

	return marginRight
end

local oldObjectiveTrackerOriginal

DGV.smallFrameExtendModeChanged = false
WF.OnFrameUpdate = function()
	if not WF.initialized then
		return
	end
	
	if oldObjectiveTrackerOriginal ~= nil 
	and oldObjectiveTrackerOriginal ~= DGV:ObjectiveTrackerOriginal()
	and DGV:ObjectiveTrackerOriginal() then
		WF:OnBeforeObjectiveTrackerOriginal()
	end
	oldObjectiveTrackerOriginal = DGV:ObjectiveTrackerOriginal()

	
	if not DGV:GuideOn() then
		DugisGuideViewer.DoOutOfCombatCancelOld("ObjectiveFrameDugiBkg", ObjectiveFrameDugiBkg.Hide, ObjectiveFrameDugiBkg)
		return
	end
	
	local width = 300
	
	local SmallFrame = GetSmallFrame()
	
	if SmallFrame and (
		(DugisSmallFrameContainer:GetTop() == nil and not DugisGuideViewer:UserSetting(DGV_SMALL_FRAME_EXTEND_UP))
		or 
		(DugisSmallFrameContainer:GetBottom() == nil and DugisGuideViewer:UserSetting(DGV_SMALL_FRAME_EXTEND_UP))
		or DGV.smallFrameExtendModeChanged) then
		local initialY = -200
		local initialX = GetScreenWidth() - 350

		DugisSmallFrameContainer:ClearAllPoints()
		if DugisGuideViewer:UserSetting(DGV_SMALL_FRAME_EXTEND_UP) then
			if GetScreenHeight() then
				local bottomY = GetScreenHeight() - (-initialY) - (DugisSmallFrameContainer:GetHeight() or 0)
				DugisSmallFrameContainer:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", initialX, bottomY)
			end
		else
			DugisSmallFrameContainer:SetPoint("TOPLEFT", UIParent, "TOPLEFT", initialX, initialY)
		end

		if DGV.UpdateSmallFrame then
			DGV.UpdateSmallFrame(false, true)
		end

		DGV.smallFrameExtendModeChanged = false
	end
	
	--Setting original Objective Tracker/small frame position (below minimap) in case SmallFrame/Objective frame is not floating
	--if not DugisGuideViewer:UserSetting(DGV_MOVEWATCHFRAME) then
	
		--Checking space for action bars
		local marginRight = DGV.GetMultibarMargin() or 0
		local marginTop = 0

		if LuaUtils:IsElvUIInstalled() then
			marginTop = marginTop - 40
		end
		
		local top = MinimapCluster:GetHeight()
		
		if DugisGuideViewer.luiloaded then
			top = top  + 50
		end
		
		--Adjustment for Titan Panel addon Top bars 
		if Titan_Bar__Display_Bar2 and Titan_Bar__Display_Bar2:GetHeight() > 0 then
			marginTop = marginTop - 48
		elseif Titan_Bar__Display_Bar and Titan_Bar__Display_Bar:GetHeight() > 0 then
			marginTop = marginTop - 24				
		end		
		
		if not DGV:IsGoldMode() or DGV:IsSmallFrameFloating() then
			if not DGV:IncompatibleAddonLoaded() and not DGV:ObjectiveTrackerOriginal() then
				if DurabilityFrame and DurabilityFrame:IsVisible() then
					marginTop = -DurabilityFrame:GetHeight() - 10
				end
				
				if VehicleSeatIndicator and VehicleSeatIndicator:IsVisible() then
					marginTop = -VehicleSeatIndicator:GetHeight() - 10
				end
								
				--[[if not DugisGuideViewer:UserSetting(DGV_WATCHFRAMEBORDER) then
					ObjectiveTrackerFrame:ClearAllPoints()
					if DugisGuideViewer:UserSetting(DGV_SMALL_FRAME_EXTEND_UP) then
						ObjectiveTrackerFrame:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", GetScreenWidth() - width - marginRight - 1, 150)
					else
						ObjectiveTrackerFrame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", GetScreenWidth() - width - marginRight - 1, -top + marginTop)
					end
				end]]
			end
		else
			if DurabilityFrame and DurabilityFrame:IsVisible() then
				marginTop = -DurabilityFrame:GetHeight() + 5
			end
			
			if VehicleSeatIndicator and VehicleSeatIndicator:IsVisible() then
				marginTop = -VehicleSeatIndicator:GetHeight() + 5
			end
			
			if DugisGuideViewer:IsModuleRegistered("SmallFrame") then 
				
				if DugisGuideViewer:UserSetting(DGV_WATCHFRAMEBORDER) then
					if DugisGuideViewer:UserSetting(DGV_SMALL_FRAME_EXTEND_UP) then
						local dH = ObjectiveTrackerFrame.BlocksFrame.contentsHeight

						LuaUtils.ClearAndSetPoint(DugisSmallFrameContainer, "BOTTOMLEFT", UIParent, "BOTTOMLEFT"
						, GetScreenWidth() - DugisSmallFrameContainer:GetWidth() - marginRight - 5, 110 + dH) 
					else
						LuaUtils.ClearAndSetPoint(DugisSmallFrameContainer, "TOPLEFT", UIParent, "TOPLEFT", GetScreenWidth() - DugisSmallFrameContainer:GetWidth() - marginRight - 5, -top + marginTop + 15) 
					end
				else
					if DugisGuideViewer:UserSetting(DGV_SMALL_FRAME_EXTEND_UP) then
						LuaUtils.ClearAndSetPoint(DugisSmallFrameContainer, "BOTTOMLEFT", UIParent, "BOTTOMLEFT"
						, GetScreenWidth() - DugisSmallFrameContainer:GetWidth() - marginRight - 1, 350) 
					else
						LuaUtils.ClearAndSetPoint(DugisSmallFrameContainer, "TOPLEFT", UIParent, "TOPLEFT", GetScreenWidth() - DugisSmallFrameContainer:GetWidth() - marginRight - 1, -top + marginTop + 15) 
					end
				end				
			end
		end
	--end
	
	local left, top = 0,0
	
	if DGV:IsGoldMode() and SmallFrame then
		 left, top = GUIUtils:GetRealFeamePos(DugisSmallFrameContainer)
	end
	
	local leftTracker, topTracker = GUIUtils:GetRealFeamePos(ObjectiveTrackerFrame)
	
	--[[if not DGV:IncompatibleAddonLoaded() and not DGV:ObjectiveTrackerOriginal() then
		if not DGV:IsGoldMode() or DGV:IsSmallFrameFloating() then
			ObjectiveFrameDugiBkg:ClearAllPoints()

			if DugisGuideViewer:UserSetting(DGV_MOVEWATCHFRAME) and WF.objectiveTrackerX then
				ObjectiveTrackerFrame:ClearAllPoints()

				if WF.objectiveTrackerY > 0 then
					WF.objectiveTrackerY = -WF.objectiveTrackerY
				end

				if WF.objectiveTrackerX < 0 then
					WF.objectiveTrackerX = -WF.objectiveTrackerX
				end

				--Setting ObjectiveTrackerFrame to the current one (WF.objectiveTrackerX) for floating mode
				ObjectiveFrameDugiBkg:SetPoint("TOPLEFT", UIParent, "TOPLEFT", WF.objectiveTrackerX - 40,  WF.objectiveTrackerY + 15)
				ObjectiveTrackerFrame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", WF.objectiveTrackerX - 0,  WF.objectiveTrackerY)
			else
				--Setting ObjectiveTrackerFrame background position to be the same ObjectiveTrackerFrame
				DugisGuideViewer.DoOutOfCombatCancelOld("RestoreOriginalObjectiveTrackerPosition", WF.RestoreOriginalObjectiveTrackerPosition)
				--Storing current objective tracker frame position to be used in the future.
				WF.objectiveTrackerX, WF.objectiveTrackerY = leftTracker, topTracker
			end
			
			ObjectiveTrackerFrame:SetHeight(GetScreenHeight())
		else
			if SmallFrame then
                local height =  DugisSmallFrameContainer:GetHeight()
				ObjectiveFrameDugiBkg:ClearAllPoints()
				
                if DGV.shouldUpdateObjectiveTracker then 
					ObjectiveTrackerFrame:ClearAllPoints()

					local trackerTop = top - height
					local trackerLeft = left + 40

					if trackerTop > 0 then
						trackerTop = -trackerTop
					end

					if trackerLeft < 0 then
						trackerLeft = -trackerLeft
					end

                    ObjectiveTrackerFrame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", trackerLeft, trackerTop)
                    ObjectiveTrackerFrame:SetHeight(GetScreenHeight())
                end
                ObjectiveFrameDugiBkg:SetPoint("TOPLEFT", UIParent, "TOPLEFT", left,  top - height + 10)
			end
			--Storing current objective tracker frame position to be used the future - for example in the essential mode.
			WF.objectiveTrackerX, WF.objectiveTrackerY = GUIUtils:GetRealFeamePos(ObjectiveTrackerFrame)
            
		end
	end]]
	
	if not DGV:IncompatibleAddonLoaded() and not DGV:ObjectiveTrackerOriginal() then
		--ObjectiveFrameDugiBkg:SetWidth(width)
		
        local realH = ObjectiveTrackerFrame.BlocksFrame.contentsHeight
		if realH then
			ObjectiveFrameDugiBkg:SetHeight(realH + 30)
		end
	end
	ObjectiveFrameDugiBkg.initialized = true

	---
	if ObjectiveFrameDugiBkg and not DGV:IncompatibleAddonLoaded() and not DGV:ObjectiveTrackerOriginal() then
		local shouldBeHidden = not ObjectiveTrackerFrame.HeaderMenu:IsVisible()  or ObjectiveTrackerFrame.collapsed  or not ObjectiveFrameDugiBkg.initialized 
		
		if DGV.shouldUpdateObjectiveTracker then
			if shouldBeHidden then
				DugisGuideViewer.DoOutOfCombatCancelOld("ObjectiveFrameDugiBkg", ObjectiveFrameDugiBkg.Hide, ObjectiveFrameDugiBkg)
			else
				DugisGuideViewer.DoOutOfCombatCancelOld("ObjectiveFrameDugiBkg", ObjectiveFrameDugiBkg.Show, ObjectiveFrameDugiBkg)
			end
		end
		
		if shouldBeHidden
		or (smallAndObjectiveFrameOneBkg and (DGV:IsGoldMode() and not DGV:IsSmallFrameFloating()) )then 
			ObjectiveFrameDugiBkg:SetAlpha(0)
		else
			ObjectiveFrameDugiBkg:SetAlpha(1)
		end
	end
	
	--Updating header menu ( [V] button positon)
	if DGV.shouldUpdateObjectiveTracker then 
		--[[if not DGV:IncompatibleAddonLoaded() and not DGV:ObjectiveTrackerOriginal() then
			ObjectiveTrackerFrame.HeaderMenu:ClearAllPoints()
			if not DGV:IsGoldMode() or DGV:IsSmallFrameFloating() then
				local width = ObjectiveFrameDugiBkg:GetWidth()
				if DugisGuideViewer:UserSetting(DGV_MOVEWATCHFRAME) then 
					ObjectiveTrackerFrame.HeaderMenu:SetPoint("TOPLEFT", UIParent, "TOPLEFT", leftTracker + width - 60,  topTracker)	
				else
					ObjectiveTrackerFrame.HeaderMenu:SetPoint("TOPLEFT", UIParent, "TOPLEFT", leftTracker + width - 65,  topTracker - 3)					
				end
			else
				ObjectiveTrackerFrame.HeaderMenu:SetPoint("TOPLEFT", UIParent, "TOPLEFT", left + width - 20,  top - 15)	
			end
		end]]
	end
	
	--Checking if only small frame is visible. If that is the case then an extra header button should be shown
	--[[if SmallFrame and SmallFrame.UpdateProgressBarPosition then
		SmallFrame.UpdateProgressBarPosition()
	end]]
end

local lastTime = GetTime()
function WF:RestoreOriginalObjectiveTrackerPosition(force)
	if (GetTime() - lastTime) < 0.5 and not force then
		return
	end

	lastTime = GetTime()

	local marginX = DGV.GetMultibarMargin()
	ObjectiveFrameDugiBkg:SetPoint("TOPLEFT", ObjectiveTrackerFrame, "TOPLEFT", -47, 10)
	ObjectiveFrameDugiBkg:SetPoint("RIGHT", ObjectiveTrackerFrame, "RIGHT", 10, 0)

	--[[local newX = -22 - marginX

	ObjectiveTrackerFrame:ClearAllPoints()
	
	ObjectiveTrackerFrame:SetPoint("TOPRIGHT", MinimapCluster, "BOTTOMRIGHT", newX, 3)
	ObjectiveTrackerFrame:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT", -10, 85)]]
end

function WF:OnBeforePluginOff()
	if not DGV:IncompatibleAddonLoaded() then
		DugisGuideViewer.DoOutOfCombatCancelOld("RestoreOriginalObjectiveTrackerPosition", WF.RestoreOriginalObjectiveTrackerPosition)
	end
end

function WF:OnBeforeObjectiveTrackerOriginal()
	DugisGuideViewer.DoOutOfCombatCancelOld("RestoreOriginalObjectiveTrackerPosition", WF.RestoreOriginalObjectiveTrackerPosition)
end 

function WF:Initialize()  
	if WF.initialized then return end
	WF.initialized = true

	if ElvUI then
		local ElvUI_ = unpack(ElvUI);

		hooksecurefunc(ElvUI_, "UpdateFontTemplates", function()
			WF.OnFrameUpdate()
			ObjectiveTracker_OnFocusedQuestChanged()
		end)
	end
  
    function WF:ResetWatchFrameMovable()
        WF:DelayUpdate()
	end    
    

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

	function WF:Reset()
	end
	
	local firstTime = true
	function WF:DelayUpdate()
		if DugisGuideViewer:IsModuleRegistered("SmallFrame") then 
			--DGV:UpdateSmallFrame()
			if firstTime then
				LuaUtils:Delay(2, function()
					--DGV:UpdateSmallFrame()
				end)
			end
			firstTime = false
		else
			LuaUtils:Delay(2, function()
				if DugisGuideViewer:IsModuleRegistered("SmallFrame") then 
					--DGV:UpdateSmallFrame()
				end
			end)
		end
	end

	local objectiveTrackerUpdateReaction--, manageFramePositionsReaction
	function WF:Load()
		objectiveTrackerUpdateReaction = RegisterFunctionReaction("ObjectiveTracker_Update", nil, function()
			WF.DelayUpdate()
			if DugisGuideViewer.NamePlate and DugisGuideViewer.NamePlate.OnObjectiveTracker_Update then
				DugisGuideViewer.NamePlate:OnObjectiveTracker_Update()
			end
		end)
		DugisGuideViewer.DoOutOfCombatCancelOld("RestoreOriginalObjectiveTrackerPosition", WF.RestoreOriginalObjectiveTrackerPosition)
	end

	function WF:Unload()
		objectiveTrackerUpdateReaction:Dispose()
	end
	
	if IsAddOnLoaded("DBM-Core") and DugisGuideViewer:GuideOn() and DugisGuideViewer.chardb.EssentialsMode ~= 1 then 
		hooksecurefunc(DBM, "StartCombat", function()
			DGV:OnDBMUpdate()
		end)	
		hooksecurefunc(DBM, "EndCombat", function()
			DGV:OnDBMUpdate()
		end)		
	end

	hooksecurefunc(ObjectiveTrackerFrame, "SetPoint", function()
		local stack = debugstack()
		local isCalledByBlizzard = (string.find(stack, "ManageFramePositions") ~= nil)
		local isCalledByDugisAddon = (string.find(stack, "RestoreOriginalObjectiveTrackerPosition") ~= nil)

		if isCalledByBlizzard and not isCalledByDugisAddon then 
			DugisGuideViewer.DoOutOfCombatCancelOld("RestoreOriginalObjectiveTrackerPosition", WF.RestoreOriginalObjectiveTrackerPosition, true)
		end
	end)
end