local _

--//////////////////////////////////////////

local L = DugisLocals
local DGV = DugisGuideViewer
if not DGV then return end

local SmallFrame, Objectives = DGV:RegisterModule("SmallFrame", "Objectives")--, "Guides")
DGV.SmallFrame = SmallFrame

local headerStub
headerStub = setmetatable({}, {
	__index = function (table, key)
		return headerStub
	end,
	__call = DGV.NoOp
})

DugisSmallFrameMixin = 
{
	IsInDefaultPosition = DGV.NoOp,
	Header = headerStub
}

local DBMUpdate
function SmallFrame:Initialize()
	if SmallFrame.initialized then return end
	SmallFrame.initialized = true
			
	local L = DugisLocals
	local flashGroup, flash
	local container = DugisSmallFrameContainer
	local background = container.Background
	
	function SmallFrame:Reset()
		if DGV:IsSmallFrameFloating() then
			container:ClearAllPoints()	
			container:SetPoint("TOPRIGHT", UIParent, -300, -50)
		end
	end

	function SmallFrame:OnClick(self, button)
		if button == "RightButton" then
			if DugisMainBorder:IsVisible() then
				DugisGuideViewer:HideLargeWindow()
			else
				--UIFrameFadeIn(DugisMainframe, 0.5, 0, 1)
				--UIFrameFadeIn(Dugis, 0.5, 0, 1)
				DugisGuideViewer:ShowLargeWindow()
			end
		elseif button == "LeftButton" and IsShiftKeyDown() then
			DugisGuideViewer.Modules.StickyFrame:AddRow(self.guideIndex) 
		elseif button == "LeftButton" and DGV.actions and DGV.actions[self.guideIndex] and strmatch(DGV.actions[self.guideIndex], "[CNKT]") then 
			local qid = DGV.qid[self.guideIndex]
			if qid then
				--local questIndex = C_QuestLog.GetLogIndexForQuestID(qid)
				--if questIndex and questIndex > 0 then 
					QuestMapFrame_OpenToQuestDetails( qid );
				--end
			end
		end
	end
	
	function SmallFrame:CheckButton_OnEvent(self, event)
		local guideIndex = self:GetParent().guideIndex
		if DugisGuideUser.CurrentQuestIndex then --If a guide is loaded
			if DGV:ReturnTag("NT", guideIndex) then
				--self.Chk:SetChecked(false)
                DGV.UpdateGuideVisualRows()
			elseif guideIndex==DugisGuideUser.CurrentQuestIndex and guideIndex == DGV:GetLastUsedStepIndex() then--LastGuideNumRows then
				--self.Chk:SetChecked(false)
				DugisGuideViewer:LoadNextGuide()
                DGV.UpdateGuideVisualRows()
			else
				DugisGuideViewer:SetChkToComplete(guideIndex, true)
				if guideIndex then
                    LuaUtils:Delay(0.2, function()
                        if DugisGuideViewer:GuideOn() and DugisGuideViewer.chardb.EssentialsMode ~= 1 then
                            DugisGuideViewer:MoveToNextQuest(DugisGuideViewer:FindNextUnchecked())
                        end
                    end)
                    
                    LuaUtils:Delay(0.3, function()
                        DGV.UpdateGuideVisualRows()
                    end)
				end
			end
		end
	end
	
	function SmallFrame:OnDragStart()
		if DGV:IsSmallFrameFloating() and not InCombatLockdown() then
			container:StartMoving()
		end
	end

	function SmallFrame:OnDragStop()
		container:StopMovingOrSizing();
		local point = container:GetPoint()
		local expandUp = strmatch(point, "BOTTOM")
		if(point ~= "TOPLEFT" and not expandUp)
			or (point ~= "BOTTOMLEFT" and expandUp)
		then
			local x, y = container:GetLeft(), -((GetScreenHeight() or 0)  - (container:GetTop() or 0))
			container:ClearAllPoints()

			if expandUp then
				y = -y
				y = y + container:GetHeight()
				local fromBottom = GetScreenHeight() - y
				container:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", x, fromBottom)
			else
				container:SetPoint("TOPLEFT", x, y)
			end
		end
	end	
	
	container:HookScript("OnMouseDown", SmallFrame.OnDragStart)
	container:HookScript("OnMouseUp", SmallFrame.OnDragStop)
	
	function SmallFrame:PlayFlashAnimation()
		LuaUtils:Delay(0.1, function()
			--if header.animating then return end -- stop flash animation spam
			if not SmallFrame.FlashFrame then
				wf_flashGroup, _, SmallFrame.FlashFrame = DGV:CreateFlashFrame(background)
			end
			
			if DGV:UserSetting(DGV_SMALLFRAMEBORDER) and (DGV:UserSetting(DGV_SMALLFRAMETRANSITION) == L["Flash"] or DGV:UserSetting(DGV_SMALLFRAMETRANSITION) == L["Scroll"]) then				
				--DGV:DebugFormat("PlayFlashAnimation showing", "flashGroup", flashGroup)
				SmallFrame.FlashFrame:Show()
				SmallFrame.FlashFrame:SetWidth(background:GetWidth() - 14)
				SmallFrame.FlashFrame:SetHeight(background:GetHeight() - 17)
				wf_flashGroup:Stop()
				wf_flashGroup:Play()
			else
				SmallFrame.FlashFrame:Hide()
			end
		end)
	end
    
	local trackerModule
	SmallFrame.Load = function()
		if SmallFrame.loaded then return end
		SmallFrame.loaded = true

		local function ShouldShow()
			return not DGV:UserSetting(DGV_ANCHOREDSMALLFRAME) 
				and not PetBattleFrame:IsShown() 
				and not DBMUpdate
				and not DGV:IncompatibleAddonLoaded()
		end

		local function LayoutContainer(show)
			if not show then
				container:Hide()
				return
			end
			container:Show()

			DGV.QueueInvocation(container.UpdateHeight, container)
		end

		local function LayoutBackground()
			if DGV:UserSetting(DGV_SMALLFRAMEBORDER)
				and DGV:GuideOn() 
				and ShouldShow()
			then
				if not container.Background.backdropInfo then
					DGV:SetFrameBackdrop(container.Background, DGV.BACKGRND_PATH, DGV:GetBorderPath(), 10, 4, 12, 5)
				end
				container.Background:Show()
			elseif container.Background:IsShown() then
				container.Background:Hide()
			end
		end

		function container:UpdateHeight()
			local height = self.topModulePadding;
			if self.modules then
				for i, module in ipairs(self.modules) do
					if module then
						height = height + module:GetContentsHeight()
					end
				end
			end
			self:SetHeight(height > self.topModulePadding and height or 800);
		end

		function container:GetAvailableHeight()
			return 800
		end

		local baseLayoutContents
		local function LayoutContents(module)
			local show = ShouldShow()
			if show then
				baseLayoutContents(module)
			end
			LayoutBackground()
			LayoutContainer(show)
		end

		local function GetBlockIdentifier(module, stepIndex)
			return "DGVSmall"..stepIndex
		end

		ObjectiveTrackerManager:AddContainer(container)
		if not trackerModule then
			trackerModule = Objectives:CreateTrackerModule(container, "DugisSmallFrameObjectiveModule")
			trackerModule.blockTemplate = "DugisSmallFrameObjectiveBlockTemplate" --identical template, but the pools need to be kept distinct
			baseLayoutContents = trackerModule.LayoutContents
			trackerModule.LayoutContents = LayoutContents
			trackerModule.GetBlockIdentifier = GetBlockIdentifier
		end
		ObjectiveTrackerManager:SetModuleContainer(trackerModule, container)

		
		--[[local module = ObjectiveTracker_GetModuleInfoTable(
			"DGV_SMALL_TRACKER_MODULE", 
			DGV_TRACKER_MODULE, 
			"DugisObjectiveBlockTemplate")
		DGV_SMALL_TRACKER_MODULE = module
		module.BlocksFrame = tracker.BlocksFrame
		module:SetHeader(
			module.BlocksFrame.Header,SmallFrame:Update()
			L["Guides"], 
			OBJECTIVE_TRACKER_UPDATE_MODULE_DGV)

		tracker.HeaderMenu:ClearAllPoints();
		tracker.HeaderMenu:SetPoint("RIGHT", module.Header)
		tracker.HeaderMenu.Title:SetText(L["Guides"])
		--module.Header.MinimizeButton:SetPoint("RIGHT", module.Header, -20, 0)
		module.Header.MinimizeButton:Hide()

		function SmallFrame:UpdateTracker()
			if tracker.isUpdating then
				return;
			end
			tracker.isUpdating = true;
			tracker.BlocksFrame.maxHeight = math.huge
		
			tracker.BlocksFrame.currentBlock = nil;
			tracker.BlocksFrame.contentsHeight = 0;
		
			-- Gather existing headers, only newly added ones will animate
			local headerWasVisible = header.added and header:IsVisible()
		
			-- mark headers unused
			header.added = nil
		
			-- run module updates
			module:Update()
		
			module:UpdatePOIs()
			if not headerWasVisible then
				header:PlayAddAnimation()
			end
		
			-- hide unused headers
			ObjectiveTracker_CheckAndHideHeader(header)
		
			tracker.BlocksFrame.currentBlock = nil
			tracker.isUpdating = false

            local extraHeight = 0
            if DugisGuideViewer.CurrentTitle == nil then
                extraHeight = 10
            end
            container:SetHeight(tracker.BlocksFrame.contentsHeight + 30 + extraHeight)
		end
		
		local function Shown()
			return not DGV:UserSetting(DGV_ANCHOREDSMALLFRAME) 
				and not PetBattleFrame:IsShown() 
				and not DBMUpdate
				and not DGV:IncompatibleAddonLoaded()
		end
		
		local UpdateSmallFrame_firstTime = true
		local updating
		function DGV:UpdateSmallFrame(headerAnim, dontPlayFlash)
		  DGV.DoOutOfCombatCancelOld("DGV:UpdateSmallFrame", function()
			if updating then return end
			updating = true
			local shown = Shown()
			container:SetShown(shown)
			SmallFrameTooltip:SetShown(shown)
			ObjectiveTracker_Update()
			SmallFrame:UpdateTracker()
			if not dontPlayFlash then
				SmallFrame:PlayFlashAnimation(headerAnim)
			end            

			DGV:ShowAutoTooltip()
			
			--Updating
			--container:RegisterForDrag(nil)  --argument is no longer nullable, may need to account for whatever this was meant to do
			
			DGV:SetSmallFrameBorder()

			--container:SetHeight
			DGV:WatchQuest()

			LuaUtils:Delay(1, function()
				if UpdateSmallFrame_firstTime then
					DGV.UpdateWorldQuestAutoGuide(UpdateSmallFrame_firstTime)
				  	if SmallFramePreloader then
                		SmallFramePreloader:HidePreloader() --temp fix, sometimes this doesn't get triggered when loading with other addons like Allthethings
		            end
				end
				UpdateSmallFrame_firstTime = false
			end)
			updating = false
		  end)
		end]]

		local function ModuleCondition(module)
			return module.blockTemplate == "DugisSmallFrameObjectiveBlockTemplate"
		end
	
		function SmallFrame:Update()
			for module in Objectives.IterateModules,ModuleCondition do
				module:MarkDirty()
			end
		end

		function DGV:OnDBMUpdate()
			DBMUpdate = DBM.Options.HideObjectivesFrame and
				not ObjectiveTrackerFrame:IsVisible() 
			SmallFrame:Update()
		end
	end
	SmallFrame.Unload = function()
		if not SmallFrame.loaded then return end
		SmallFrame.loaded = false
		--SmallFrame:Reset()
		SmallFrameTooltip:Hide()
		container:Hide()
	end
        
    --This preloader is not visible. It just prevents mouse clicks.
    GUIUtils:CreatePreloader("SmallFramePreloader", container)
    SmallFramePreloader:SetFrameStrata("BACKGROUND")
    SmallFramePreloader.Icon:Hide()  

	function SmallFrame:UpdateMovable()
		local floating = not DGV:UserSetting(DGV_LOCKSMALLFRAME)
		container:EnableMouse(floating)
		container:SetFrameLevel(2)
	end
    
	SmallFrame:UpdateMovable()
end