local addonName, addon = ...

addon:RegisterDefaultSetting("lockFrames", false)


--[[-----------------------------------------------------------------------------
Frames to allow moving and saving
-------------------------------------------------------------------------------]]
--["FrameName"] =	false  - move the frame
--true   - move the frame's parent instead
--string - move the named frame instead

DefGMoveableFrames = {
			['MiniMapLFGFrame'] = false,
			['ShardBarFrame'] = false,
			['BNToastFrame'] = false,
			['SpellBookFrame'] = false,
			['QuestLogFrame'] = false,
			['FriendsFrame'] = false,
			['LFDParentFrame'] = false,
			['KnowledgeBaseFrame'] = true,
			['MerchantFrame'] = false,
			['MailFrame'] = false,
			['DressUpFrame'] = false,
			['TaxiFrame'] = false,
			['QuestLogFrame'] = false,
			['PaperDollFrame'] = true,
			['PVPFrame'] = false,
			['WatchFrameHeader'] = true,
			['VehicleMenuBar'] = false,
			['InspectFrame'] = false,
			['PlayerTalentFrame'] = false,
			['AchievementFrame'] = false,
			['AchievementFrameHeader'] = true,
			['AchievementFrameCategoriesContainer'] = 'AchievementFrame',
			['GlyphFrame'] = 'PlayerTalentFrame',
			['CalendarFrame'] = false,
			['ContainerFrame1'] = false,
			['ContainerFrame2'] = false,
			['ContainerFrame3'] = false,
			['ContainerFrame4'] = false,
			['ContainerFrame5'] = false,
			['Minimap'] = false,
			
			--GrimUI Frames
			['GrimUIPlayerFrame'] = false,
			['GrimUIPartyFrame1'] = false,
			['GrimUIPartyFrame2'] = false,
			['GrimUIPartyFrame3'] = false,
			['GrimUIPartyFrame4'] = false,
			['GrimExpBar'] = false,
			['GrimRepBar'] = false,
			['GDevBar'] = false,
			['GUITTAnchor'] = false,
}

function addon:DefaultMoveableFrames()
	if not GMoveableFrames then
		GMoveableFrames = GMoveableFrames or DefGMoveableFrames
	end
end


--[[-----------------------------------------------------------------------------
Frame hooking
-------------------------------------------------------------------------------]]
local hookedFrame, parentFrame, movedFrames, oldPoint, oldX, oldY = { }, { }

local function GetRelativePosition(frame)
	local _, _, uiWidth, uiHeight = UIParent:GetRect()
	local left, bottom, width, height = frame:GetRect()
	if bottom + height / 2 >= uiHeight / 2 then
		if left + width / 2 >= uiWidth / 2 then
			return 'TOPRIGHT', left + width - uiWidth - 1, bottom + height - uiHeight - 1
		else
			return 'TOPLEFT', left, bottom + height - uiHeight - 1
		end
	elseif left + width / 2 >= uiWidth / 2 then
		return 'BOTTOMRIGHT', left + width - uiWidth - 1, bottom
	end
	return 'BOTTOMLEFT', left, bottom
end

local function OnShow(self)
	local frame = parentFrame[self] or self
	
	if self == Minimap then
		if addon.settings.NotSoMinimap == true then
			self = _G["NSMiniMapAnchor"]
			frame = _G["NSMiniMapAnchor"]
		else 
			self = _G["GMiniMapAnchor"]
			frame = _G["GMiniMapAnchor"]
		end
	end
	
	local position = movedFrames[self:GetName()]
	if position then
		addon:UnlockFrame(frame)
		frame:ClearAllPoints()
		frame:SetPoint(unpack(position))
		addon:LockFrame(frame)
	end
end

local function OnMouseDown(self, button)
	if button ~= 'LeftButton' or addon.settings.lockFrames then return end
	if IsControlKeyDown() and button == 'LeftButton' then
	local frame = parentFrame[self] or self
	
	if self == Minimap then
		if addon.settings.NotSoMinimap == true then
			self = _G["NSMiniMapAnchor"]
			frame = _G["NSMiniMapAnchor"]
		else 
			self = _G["GMiniMapAnchor"]
			frame = _G["GMiniMapAnchor"]
		end
	end
	
	oldPoint, oldX, oldY = GetRelativePosition(frame)
	addon:UnlockFrame(frame)
	frame:StartMoving()
	end
end

local function OnMouseUp(self, button)
	if button ~= 'LeftButton' or not oldPoint then return end
	local frame = parentFrame[self] or self
	
	if self == Minimap then
		if addon.settings.NotSoMinimap == true then
			self = _G["NSMiniMapAnchor"]
			frame = _G["NSMiniMapAnchor"]
		else 
			self = _G["GMiniMapAnchor"]
			frame = _G["GMiniMapAnchor"]
		end
	end
	
	frame:StopMovingOrSizing()
	addon:LockFrame(frame)
	local point, x, y = GetRelativePosition(frame)
	if point ~= oldPoint or x ~= oldX or y ~= oldY then
		movedFrames[frame:GetName()] = { point, 'UIParent', x, y }
	end
	oldPoint, oldX, oldY = nil, nil, nil
end

local HookFrame
function HookFrame(name, parent)
	if hookedFrame[name] then 
		return true
	end
	local frame = _G[name]
	if not frame then
		return 
	end
	if parent then
		if type(parent) == 'string' then
			parent = _G[parent]
		else
			if frame:GetParent() ~= UIParent then
				parent = frame:GetParent()
			else
				parent = frame
			end
		end
		if not parent then 
			return 
		end
		HookFrame(parent:GetName())
		while(parentFrame[parent]) do
			parent = parentFrame[parent]
		end
		parentFrame[frame] = parent
	elseif not name:match("^" .. addonName) then
		frame:HookScript('OnShow', OnShow)
	end
	frame:EnableMouse(true)
	frame:EnableKeyboard(true)
	frame:SetMovable(true)
	frame:SetClampedToScreen(false)
	frame:HookScript('OnMouseDown', OnMouseDown)
	frame:HookScript('OnMouseUp', OnMouseUp)
	hookedFrame[name] = true
	if movedFrames[name] and frame:IsShown() then
		OnShow(frame)
	end
	return true
end

--[[-----------------------------------------------------------------------------
Initialize
-------------------------------------------------------------------------------]]
local moveableframes = {}

local function VerCheckUpdate()
	local CurVer = GetAddOnMetadata(addonName, 'Version')
	local LastVer = _G[addonName .. "Settings"].version
	
	if LastVer then
		if CurVer > LastVer then 
			for gname, gparent in pairs(DefGMoveableFrames) do 
				local TabCont = tContains( GMoveableFrames, gname )
				if TabCont == nil then
					GMoveableFrames[gname] = gparent
				end
			end
		end
	end
end

addon.RegisterEvent("MoveFrames-Initialize", 'PLAYER_LOGIN', function(self, event)
	addon.UnregisterEvent(self, event)

	movedFrames = addon.settings.movedFrames
	if type(movedFrames) ~= 'table' then
		movedFrames = { }
		addon.settings.movedFrames = movedFrames
	end
	addon:RegisterDefaultSetting("movedFrames", true)	-- Prevent it from being removed on PLAYER_LOGOUT
	

	local function HookFrames(self, event)
		addon:DefaultMoveableFrames()
		VerCheckUpdate()
		
		moveableframes = CopyTable(GMoveableFrames)

		for name, parent in pairs(moveableframes) do
			if HookFrame(name, parent) then
				moveableframes[name] = nil
			end
		end
		if next(moveableframes) then return end
		addon.UnregisterEvent(self, event)
	end

	addon.RegisterEvent("MoveFrames-Hook", 'ADDON_LOADED', HookFrames)
	HookFrames("MoveFrames-Hook", 'ADDON_LOADED')
end)



--[[-----------------------------------------------------------------------------
in game add remove functions
-------------------------------------------------------------------------------]]
function addon:AddMoveableFrame(name, parvar)
	if parvar then
		if parvar == string then
			parvar = _G[parvar]
		end
		GMoveableFrames[name] = parvar
		HookFrame(name, parvar)
	elseif not parvar or parvar == "" or parvar == nil then 
		parvar = false
		GMoveableFrames[name] = parvar
		HookFrame(name, parvar)
	end
end

function addon:RemMoveableFrame(name)
	GMoveableFrames[name] = nil
end

SlashCmdList["GADDMOVE_SHORTHAND"] = function(cmd)
	local name, parvar = strsplit(" ", cmd) 
	if parvar then
		if parvar == "true" then
			parvar = true
		elseif parvar == "false" then
			parvar = false
		end
	end
	if not parvar then parvar = false end
	addon:AddMoveableFrame(name, parvar)
end
SLASH_GADDMOVE_SHORTHAND1 = "/gaddmove"

SlashCmdList["GREMMOVE_SHORTHAND"] = function(cmd)
	addon:RemMoveableFrame(cmd)
end
SLASH_GREMMOVE_SHORTHAND1 = "/gremmove"