local L = Rock("LibRockLocale-1.0"):GetTranslationNamespace("NDragIt")
L:AddTranslations("enUS", function() return {
	["Clamp To Screen"] = true,
	["Prevent frames from being dragged past the screen edges."] = true,
	["Add"] = true,
	["Add draggability to a frame."] = true,
	["Frame"] = true,
	["Frame to be made draggable."] = true,
	["Child Frame"] = true,
	["Frame whose parent is to be made draggable."] = true,
	["LOD Frame"] = true,
	["Frame which is part of a LOD addon."] = true,
	["List"] = true,
	["List all frames that are draggable."] = true,
	["Remove"] = true,
	["Remove draggability from a frame."] = true,
	["Remove draggability for %s."] = true,
	["UI Panel Offset"] = true,
	["Change the UI Panel Offset for panels such as Quest Log, Loot, Auction etc."] = true,
	["Enable"] = true,
	["Allow UI Panel Offset modification\n\nWarning: UI will be reloaded when this is disabled."] = true,
	["X"] = true,
	["Set the X offset\n\nHint: positive numbers move right."] = true,
	["<number>"] = true,
	["Y"] = true,
	["Set the Y offset\n\nHint: negatitive numbers move down."] = true,
	["\n\nHint: type /nfi in the chat edit box to show the name of the frame under the mouse."] = true,
	
	["<frame name> e.g. SpellBookFrame"] = true,
	["<frame name> e.g. PaperDollFrame"] = true,
	["<frame name> <addon name> e.g. DBMBossModFrame DBM_GUI"] = true,
	
	["%s added."] = true,
	["%s removed."] = true,
	
	["%s: new version %s; resetting all settings"] = true,
	
	["Error: %s not found."] = true,
	["Error: %s is not a frame."] = true,
	["Error: %s must have UIParent as its immediate parent."] = true,
	["Error: %s already present."] = true,
	["Error: parent is not a frame."] = true,
	["Error: parent must have UIParent as its immediate parent."] = true,
	["Error: incorrect usage; should be <frame name> <addon name>"] = true,
	["Error: not a number."] = true,
	
	["Frames:"] = true,
	["Child Frames:"] = true,
	["LOD Frames:"] = true,
	["LOD Child Frames:"] = true,
} end)
L:AddTranslations("zhCN", function() return {
	["Clamp To Screen"] = "限制在屏幕内",
	["Prevent frames from being dragged past the screen edges."] = "防止将窗体移出窗口可视范围。",
	["Add"] = "增加",
	["Add draggability to a frame."] = "增加一个新的窗体到可移动窗体列表。",
	["Frame"] = "窗体",
	["Frame to be made draggable."] = "增加窗体为可移动窗体。",
	["Child Frame"] = "子窗体",
	["Frame whose parent is to be made draggable."] = "增加一个子窗体以使其上级(窗体)可移动。",
	["LOD Frame"] = "动态载入窗体",
	["Frame which is part of a LOD addon."] = "增加一个动态载入插件的窗体到可移动窗体列表。",
	["List"] = "列表",
	["List all frames that are draggable."] = "列出所有可移动窗体。",
	["Remove"] = "删除",
	["Remove draggability from a frame."] = "将一个窗体从可移动窗体列表中删除。",
	["Remove draggability for %s."] = "删除 %s 的可移动性。",
	["UI Panel Offset"] = "插件面板偏移量",
	["Change the UI Panel Offset for panels such as Quest Log, Loot, Auction etc."] = "设置类似任务日志、拾取窗口、拍卖行等面板的插件面板偏移量",
	["Enable"] = "启用",
	["Allow UI Panel Offset modification\n\nWarning: UI will be reloaded when this is disabled."] = "允许对插件面板偏移量进行修改\n\n警告：插件将会在禁用该选项后重新载入。",
	["X"] = "水平",
	["Set the X offset\n\nHint: positive numbers move right."] = "设置水平方向位移量\n\n提示：输入正数向右偏移。",
	["<number>"] = "<数值>",
	["Y"] = "垂直",
	["Set the Y offset\n\nHint: negatitive numbers move down."] = "设置垂直方向位移量\n\n提示：输入负数想下偏移。",
	["\n\nHint: type /nfi in the chat edit box to show the name of the frame under the mouse."] = "\n\n提示：键入 /nfi 可以在聊天窗口显示当前鼠标悬停的窗体的名称。",
	
	["<frame name> e.g. SpellBookFrame"] = "<窗体名> 例如：SpellBookFrame",
	["<frame name> e.g. PaperDollFrame"] = "<窗体名> 例如：PaperDollFrame",
	["<frame name> <addon name> e.g. DBMBossModFrame DBM_GUI"] = "<窗体名> <插件名> 例如：DBMBossModFrame DBM_GUI",
	
	["%s added."] = "%s 已加入。",
	["%s removed."] = "%s 已删除。",
	
	["%s: new version %s; resetting all settings"] = "%s: 发现新版本 %s，重设所有设置。",
	
	["Error: %s not found."] = "错误：%s 未发现。",
	["Error: %s is not a frame."] = "错误：%s 不是一个窗体。",
	["Error: %s must have UIParent as its immediate parent."] = "错误：%s 必须以UIParent作为它的直系上级(窗体)。",
	["Error: %s already present."] = "错误：%s 已经存在上级。",
	["Error: parent is not a frame."] = "错误：上级不是窗体。",
	["Error: parent must have UIParent as its immediate parent."] = "错误：上级比喻以UIParent作为其直系上级(窗体)。",
	["Error: incorrect usage; should be <frame name> <addon name>"] = "错误；错误使用；正确用法：<窗体名> <插件名>。",
	["Error: not a number."] = "错误：输入的不是一个数字。",

	["Frames:"] = "窗体：",
	["Child Frames:"] = "子窗体：",
	["LOD Frames:"] = "动态载入窗体：",
	["LOD Child Frames:"] = "动态载入子窗体：",
} end)

local FRAMES = {
	-- default UI
	"SpellBookFrame",
	"QuestLogFrame",
	"FriendsFrame",
	"LFGParentFrame",
	"KnowledgeBaseFrame",
	"HelpFrame",
	"GossipFrame",
	"MerchantFrame",
	"MailFrame",
	"OpenMailFrame",
	"GuildRegistrarFrame",
	"DressUpFrame",
	"TabardFrame",
	"TaxiFrame",
	"QuestFrame",
	"TradeFrame",
	"LootFrame",
	"PetStableFrame",
	"StackSplitFrame",
	"PetitionFrame",
	"WorldStateScoreFrame",
	"BattlefieldFrame",
	"ArenaFrame",
	"ItemTextFrame",
	"GameMenuFrame",
	"InterfaceOptionsFrame",
	"MacOptionsFrame",
	"OptionsFrame",
	-- addons
	"LudwigFrame",
	"LootLinkFrame", "LootLinkSearchFrame",
}
local CHILD_FRAMES = {
	-- default UI
	"PetPaperDollFrame", "PaperDollFrame", "ReputationFrame", "SkillFrame", "PVPFrame",
	"InspectPVPFrame", "InspectTalentFrame",
	"SendMailFrame",
	"SoundOptionsFrame", "VoiceOptionsFrame",
}
local LOD_FRAMES = {
	-- default UI
	Blizzard_AuctionUI = "AuctionFrame",
	Blizzard_BindingUI = "KeyBindingFrame",
	Blizzard_CraftUI = "CraftFrame",
	Blizzard_GMSurveyUI = "GMSurveyFrame",
	Blizzard_InspectUI = "InspectFrame",
	Blizzard_ItemSocketingUI = "ItemSocketingFrame",
	Blizzard_MacroUI = "MacroFrame",
	Blizzard_TalentUI = "PlayerTalentFrame",
	Blizzard_TradeSkillUI = "TradeSkillFrame",
	Blizzard_TrainerUI = "ClassTrainerFrame",
	Blizzard_GuildBankUI = "GuildBankFrame",
	Blizzard_TimeManager = "TimeManagerFrame",
	-- addons
	DBM_GUI = "DBMBossModFrame",
}
local DEFAULT_OFFSET_X = UIParent:GetAttribute("LEFT_OFFSET")
local DEFAULT_OFFSET_Y = UIParent:GetAttribute("TOP_OFFSET")

-- for debugging / dev only
local debug = false
local showFrame = false

NDragIt = Rock:NewAddon("NDragIt", "LibRockDB-1.0", "LibRockConfig-1.0", "LibRockHook-1.0", "LibRockEvent-1.0")
NDragIt.revision = tonumber(("$Revision: 77818 $"):match("%d+"))
NDragIt.version = "r"..NDragIt.revision 
NDragIt.date = ("$Date: 2008-07-05 01:52:36 -0400 (Sat, 05 Jul 2008) $"):match("%d%d%d%d%-%d%d%-%d%d")

NDragIt:SetDatabase("NDragItDB")
NDragIt:SetDatabaseDefaults("profile", {
	clamped = false,
	frames = nil,
	childFrames = nil,
	lodFrames = nil,
	offset = {
		enabled = true,
		x = DEFAULT_OFFSET_X,
		y = DEFAULT_OFFSET_Y,
	},
})

local lodLoaded = {}

SLASH_NFI1 = "/nfi"
SlashCmdList["NFI"] = function()
	local frameStack = nil
	local frame = GetMouseFocus()
	while frame do
		frameStack = frameStack and frameStack..", "..frame:GetName() or frame:GetName()
		frame = frame:GetParent()
	end
	
	DEFAULT_CHAT_FRAME:AddMessage(frameStack)
end

function NDragIt:OnInitialize()
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:OnInitialize") end
	
	self:SetupConfig()
	
	local profile = self.db.profile
	if not profile.revision or profile.revision < self.revision then
		DEFAULT_CHAT_FRAME:AddMessage(string.format(L["%s: new version %s; resetting all settings"], self.name, self.version))
		self:ResetDatabase()
		self:LoadDefaultFrames()
	end
end

function NDragIt:OnEnable(first)
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:OnEnable first = "..tostring(first)) end

	if not self.db.profile.frames and not self.db.profile.childFrames and not self.db.profile.lodFrames then
		self:LoadDefaultFrames()
	end
	self.db.profile.revision = self.revision

	for i, v in ipairs(self.db.profile.frames) do
		self:ActivateFrame(v)
	end
	for i, v in ipairs(self.db.profile.childFrames) do
		self:ActivateChildFrame(v)
	end
	local frame = nil
	for k, v in pairs(self.db.profile.lodFrames) do
		frame = getglobal(v)
		if frame then
			self:ADDON_LOADED(_, _, k)
		end
	end
	
	self:BuildRemoveList()
	
	self:AddEventListener("ADDON_LOADED")

	self:SetOffsetEnabled(self.db.profile.offset.enabled)
end

function NDragIt:OnDisable()
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:OnDisable") end
	
	UIParent:SetAttribute("LEFT_OFFSET", DEFAULT_OFFSET_X)
	UIParent:SetAttribute("TOP_OFFSET", DEFAULT_OFFSET_Y)
	
	lodLoaded = {}
end

function NDragIt:OnResetDatabase()
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:OnResetDatabase") end
	
	local wasActive = self:IsActive()
	
	self:ToggleActive(false)
	
	self:LoadDefaultFrames()
	self.db.profile.revision = self.revision
	
	self:ToggleActive(wasActive)
end

function NDragIt:OnProfileEnable()
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:OnProfileEnable") end
	
	local wasActive = self:IsActive()
	
	self:ToggleActive(false)
	
	self:ToggleActive(wasActive)
end

function NDragIt:ADDON_LOADED(_, _, addon)
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:ADDON_LOADED "..tostring(addon)) end
	
	local frame = self.db.profile.lodFrames[addon]
	if frame then
		if not (lodLoaded[addon]) then
			lodLoaded[addon] = frame
			self:ActivateFrame(frame)
		end
	end
end

function NDragIt:ActivateFrame(name)
	frame = getglobal(name)
	if frame then
		if debug then DEFAULT_CHAT_FRAME:AddMessage(" frame: "..name) end
		frame:EnableMouse(true)
		frame:SetMovable(true)
		frame:SetClampedToScreen(self.db.profile.clamped)
		self:AddScriptHook(frame, "OnMouseDown")
		self:AddScriptHook(frame, "OnMouseUp")
	end
end

function NDragIt:ActivateChildFrame(name)
	frame = getglobal(name)
	if frame then
		local parent = frame:GetParent()
		if parent then
			if debug then DEFAULT_CHAT_FRAME:AddMessage(" child frame: "..name) end
			frame:EnableMouse(true)
			frame:SetClampedToScreen(self.db.profile.clamped)
			parent:SetMovable(true)
			parent:SetClampedToScreen(self.db.profile.clamped)
		self:AddScriptHook(frame, "OnMouseDown", "ChildOnMouseDown")
		self:AddScriptHook(frame, "OnMouseUp", "ChildOnMouseUp")
		end
	end
end

function NDragIt:OnMouseDown(frame, button)
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:OnMouseDown") end

	if button == "LeftButton" then
		if frame then
			if showFrame then
				frame:SetBackdrop({ bgFile = "Interface/Tooltips/UI-Tooltip-Background", })
			end
			frame:StartMoving()
			frame:SetUserPlaced(false)
		end
	end
	
	self.hooks[frame].OnMouseDown(frame, button)
end

function NDragIt:OnMouseUp(frame, button)
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:OnMouseUp") end

	if frame then
		if showFrame then
			frame:SetBackdrop({})
		end
		frame:StopMovingOrSizing()
	end
	
	self.hooks[frame].OnMouseUp(frame, button)
end

function NDragIt:ChildOnMouseDown(frame, button)
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:ChildOnMouseDown") end

	if button == "LeftButton" then
		if frame then
			local parentFrame = frame:GetParent()
			if parentFrame then
				if showFrame then
					frame:SetBackdrop({ bgFile = "Interface/Tooltips/UI-Tooltip-Background", })
				end
				parentFrame:StartMoving()
				parentFrame:SetUserPlaced(false)
			end
		end
	end
	
	self.hooks[frame].OnMouseDown(frame, button)
end

function NDragIt:ChildOnMouseUp(frame, button)
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:ChildOnMouseUp") end

	if frame then
		local parentFrame = frame:GetParent()
		if parentFrame then
			if showFrame then
				frame:SetBackdrop({})
			end
			parentFrame:StopMovingOrSizing()
		end
	end
	
	self.hooks[frame].OnMouseUp(frame, button)
end

function NDragIt:AddFrame(argstr)
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:AddFrame "..tostring(argstr)) end
	
	if argstr == "" then
		return
	end
	
	table.insert(self.db.profile.frames, argstr)
	self:ActivateFrame(argstr)
	self:BuildRemoveList()
end

function NDragIt:AddChildFrame(argstr)
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:AddChildFrame "..tostring(argstr)) end
	
	if argstr == "" then
		return
	end

	table.insert(self.db.profile.childFrames, argstr)
	self:ActivateChildFrame(argstr)
	self:BuildRemoveList()
end

function NDragIt:AddLODFrame(argstr)
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:AddLODFrame "..tostring(argstr)) end

	if argstr == "" then
		return
	end
	
	local addon, frame = nil, nil
	for k, v in argstr:gmatch('%s*(%S+)%s+(.+)') do
		frame, addon = k, v
	end

	self.db.profile.lodFrames[addon] = frame
	self:ActivateFrame(frame)
	self:BuildRemoveList()
end

function NDragIt:FramePresent(frame, addon)
	for i, v in ipairs(self.db.profile.frames) do
		if frame == v then
			return true, string.format(L["Error: %s already present."], frame)
		end
	end
	for i, v in ipairs(self.db.profile.childFrames) do
		if frame == v then
			return true, string.format(L["Error: %s already present."], frame)
		end
	end
	for k, v in pairs(self.db.profile.lodFrames) do
		if addon == k then
			return true, string.format(L["Error: %s already present."], addon)
		end
		if frame == v then
			return true, string.format(L["Error: %s already present."], frame)
		end
	end

	return false
end

function NDragIt:ValidFrame(name)
	
	if name == "" then
		return true
	end
	
	local present, msg = self:FramePresent(name)
	if present then
		return false, msg
	end

	local frame = getglobal(name)
	if not frame then
		return false, string.format(L["Error: %s not found."], name)
	end
	if not frame.GetObjectType or frame:GetObjectType() ~= "Frame" then
		return false, string.format(L["Error: %s is not a frame."], name)
	end
	local parent = frame:GetParent()
	if not parent or not parent.GetName or parent:GetName() ~= "UIParent" then
		return false, string.format(L["Error: %s must have UIParent as its immediate parent."], name)
	end
	return true
end

function NDragIt:ValidChildFrame(name)
	if name == "" then
		return true
	end
	
	local present, msg = self:FramePresent(name)
	if present then
		return false, msg
	end
	
	local frame = getglobal(name)
	if not frame then
		return false, string.format(L["Error: %s not found."], name)
	end
	if not frame.GetObjectType or frame:GetObjectType() ~= "Frame" then
		return false, string.format(L["Error: %s is not a frame."], name)
	end
	local parent = frame:GetParent()
	if not parent or not parent.GetObjectType or parent:GetObjectType() ~= "Frame" then
		return false, L["Error: parent is not a frame."]
	end
	local grandParent = parent:GetParent()
	if not grandParent or not grandParent.GetName or grandParent:GetName() ~= "UIParent" then
		return false, L["Error: parent must have UIParent as its immediate parent."]
	end
	
	return true
end

function NDragIt:ValidLODFrame(argstr)
	if argstr == "" then
		return true
	end
	
	local addon, frame = nil, nil
	for k, v in argstr:gmatch('%s*(%S+)%s+(.+)') do
		frame, addon = k, v
	end
	if not addon or not frame then
		return false, L["Error: incorrect usage; should be <frame name> <addon name>"]
	end
	
	local present, msg = self:FramePresent(frame)
	if present then
		return false, msg
	end
	present, msg = self:ValidFrame(frame)
	if not present then
		return false, msg
	end
	
	return true
end

function NDragIt:BuildRemoveList()
	if debug then DEFAULT_CHAT_FRAME:AddMessage("NDragIt:BuildRemoveList") end
	
	local index = 101
	self.options.args.remove.args.frame.args = {}
	table.sort(self.db.profile.frames)
	for i, v in ipairs(self.db.profile.frames) do
		self.options.args.remove.args.frame.args[v] = {
			name = v,
			desc = string.format(L["Remove draggability for %s."], v),
			type = "execute",
			func = function(frame) NDragIt:RemoveFrame(frame) end,
			passValue = v,
			order = index,
		}
		index = index + 1
	end
	
	local index = 101
	self.options.args.remove.args.childFrame.args = {}
	table.sort(self.db.profile.childFrames)
	for i, v in ipairs(self.db.profile.childFrames) do
		self.options.args.remove.args.childFrame.args[v] = {
			name = v,
			desc = string.format(L["Remove draggability for %s."], v),
			type = "execute",
			func = function(frame) NDragIt:RemoveChildFrame(frame) end,
			passValue = v,
			order = index,
		}
		index = index + 1
	end
	
	local index = 101
	self.options.args.remove.args.lodFrame.args = {}
	for k, v in pairs(self.db.profile.lodFrames) do
		self.options.args.remove.args.lodFrame.args[k] = {
			name = format("%s (%s)", v, k),
			desc = string.format(L["Remove draggability for %s."], k),
			type = "execute",
			func = function(addon) NDragIt:RemoveLodFrame(addon) end,
			passValue = k,
			order = index,
		}
		index = index + 1
	end
end

function NDragIt:RemoveFrame(name)
	local index = nil
	for i, v in ipairs(self.db.profile.frames) do
		if v == name then
			index = i
			break
		end
	end
	table.remove(self.db.profile.frames, index)
	local frame = getglobal(name)
	if frame then
		self:RemoveHook(frame, "OnMouseDown")
		self:RemoveHook(frame, "OnMouseUp")
	end
	self:BuildRemoveList()
end

function NDragIt:RemoveChildFrame(name)
	local index = nil
	for i, v in ipairs(self.db.profile.childFrames) do
		if v == name then
			index = i
			break
		end
	end
	table.remove(self.db.profile.childFrames, index)
	local frame = getglobal(name)
	if frame then
		self:RemoveHook(frame, "OnMouseDown")
		self:RemoveHook(frame, "OnMouseUp")
	end
	self:BuildRemoveList()
end

function NDragIt:RemoveLodFrame(addon)
	local index = nil
	local frame = getglobal(self.db.profile.lodFrames[addon])
	if frame then
		self:RemoveHook(frame, "OnMouseDown")
		self:RemoveHook(frame, "OnMouseUp")
	end
	self.db.profile.lodFrames[addon] = nil
	self:BuildRemoveList()
end

function NDragIt:LoadDefaultFrames()
	local profile = self.db.profile
	profile.frames = {}
	for i, v in ipairs(FRAMES) do
		table.insert(profile.frames, v)
	end
	profile.childFrames = {}
	for i, v in ipairs(CHILD_FRAMES) do
		table.insert(profile.childFrames, v)
	end
	profile.lodFrames = {}
	for k, v in pairs(LOD_FRAMES) do
		profile.lodFrames[k] = v
	end
end

function NDragIt:GetClamped()
	return self.db.profile.clamped
end

function NDragIt:SetClamped(value)
	self.db.profile.clamped = value
	
	self:ToggleActive(false)
	self:ToggleActive(true)
end

function NDragIt:GetOffsetEnabled()
	return self.db.profile.offset.enabled
end

function NDragIt:SetOffsetEnabled(value)
	self.db.profile.offset.enabled = value
	if value then
		self:SetOffsetX(self.db.profile.offset.x)
		self:SetOffsetY(self.db.profile.offset.y)
	else
		UIParent:SetAttribute("LEFT_OFFSET", DEFAULT_OFFSET_X)
		UIParent:SetAttribute("TOP_OFFSET", DEFAULT_OFFSET_Y)
	end
end

function NDragIt:GetOffsetX()
	return self.db.profile.offset.x
end

function NDragIt:SetOffsetX(value)
	if self:IsNumber(value) then
		self.db.profile.offset.x = tonumber(value)
		UIParent:SetAttribute("LEFT_OFFSET", value)
	end
end

function NDragIt:GetOffsetY()
	return self.db.profile.offset.y
end

function NDragIt:SetOffsetY(value)
	if self:IsNumber(value) then
		self.db.profile.offset.y = (value)
		UIParent:SetAttribute("TOP_OFFSET", value)
	end
end

function NDragIt:IsNumber(value)
	return tonumber(value), L["Error: not a number."]
end

function NDragIt:SetupConfig()
	self.options = {
    	name = "\231\179\187\231\187\159\230\161\134\230\158\182\231\167\187\229\138\168",--self.name,
    	desc = "\229\143\175\228\187\165\228\184\180\230\151\182\231\167\187\229\138\168\231\179\187\231\187\159\233\187\152\232\174\164\230\161\134\230\158\182\228\189\141\231\189\174",--self.notes,
		type = "group",
		args = {
			clamp = {
				name = L["Clamp To Screen"],
				desc = L["Prevent frames from being dragged past the screen edges."],
				type = "boolean",
				get = "GetClamped",
				set = "SetClamped",
				order = 101,
				disabled = "~IsActive",
			},
			add = {
				name = L["Add"],
				desc = L["Add draggability to a frame."],
				type = "group",
				disabled = "~IsActive",
				args = {
					frame = {
						name = L["Frame"],
						desc = L["Frame to be made draggable."]..L["\n\nHint: type /nfi in the chat edit box to show the name of the frame under the mouse."],
						usage = L["<frame name> e.g. SpellBookFrame"],
						type = "string",
						set = function(argstr) NDragIt:AddFrame(argstr) end,
						get = false,
						validate = "ValidFrame",
						order = 101,
					},
					childFrame = {
						name = L["Child Frame"],
						desc = L["Frame whose parent is to be made draggable."]..L["\n\nHint: type /nfi in the chat edit box to show the name of the frame under the mouse."],
						usage = L["<frame name> e.g. PaperDollFrame"],
						type = "string",
						set = function(argstr) NDragIt:AddChildFrame(argstr) end,
						get = false,
						validate = "ValidChildFrame",
						order = 102,
					},
					lodFrame = {
						name = L["LOD Frame"],
						desc = L["Frame which is part of a LOD addon."]..L["\n\nHint: type /nfi in the chat edit box to show the name of the frame under the mouse."],
						usage = L["<frame name> <addon name> e.g. DBMBossModFrame DBM_GUI"],
						type = "string",
						set = function(argstr) NDragIt:AddLODFrame(argstr) end,
						get = false,
						validate = "ValidLODFrame",
						order = 103,
					},
				},
				order = 102,
			},
			remove = {
				name = L["Remove"],
				desc = L["Remove draggability from a frame."],
				type = "group",
				disabled = "~IsActive",
				args = {
					frame = {
						name = L["Frame"],
						desc = L["Frame to be made draggable."],
						type = "group",
						order = 101,
					},
					childFrame = {
						name = L["Child Frame"],
						desc = L["Frame whose parent is to be made draggable."],
						type = "group",
						order = 102,
					},
					lodFrame = {
						name = L["LOD Frame"],
						desc = L["Frame which is part of a LOD addon."],
						type = "group",
						order = 103,
					},
				},
				order = 103,
			},
			offset = {
				name = L["UI Panel Offset"],
				desc = L["Change the UI Panel Offset for panels such as Quest Log, Loot, Auction etc."],
				type = "group",
				disabled = "~IsActive",
				args = {
					enable = {
						name = L["Enable"],
						desc = L["Allow UI Panel Offset modification\n\nWarning: UI will be reloaded when this is disabled."],
						type = "boolean",
						set = "SetOffsetEnabled",
						get = "GetOffsetEnabled",
						order = 101,
					},
					x = {
						name = L["X"],
						desc = L["Set the X offset\n\nHint: positive numbers move right."],
						usage = L["<number>"],
						type = "string",
						set = "SetOffsetX",
						get = "GetOffsetX",
						validate = "IsNumber",
						disabled = "~GetOffsetEnabled",
						order = 102,
					},
					y = {
						name = L["Y"],
						desc = L["Set the Y offset\n\nHint: negatitive numbers move down."],
						usage = L["<number>"],
						type = "string",
						set = "SetOffsetY",
						get = "GetOffsetY",
						validate = "IsNumber",
						disabled = "~GetOffsetEnabled",
						order = 103,
					},
				},
				order = 104,
			},
		},
	}
	NDragIt:SetConfigTable(self.options)
	NDragIt:SetConfigSlashCommand("/ndragit", "/dragit", "/ndi")
end