local L = LibStub("AceLocale-3.0"):GetLocale("MNT2", true)

local mountedit -- id of the mount we are adjusting
local MountEditSpeeds = {}
local currentSpeed
local currentType

local customContainer = LibStub("AceGUI-3.0"):Create("MNT2_Frame")
local customContainerShow = customContainer.Show
local dummyFunc = function() end
customContainer:Hide()

function MNT2:OpenCustomContainer(app, title)
	customContainer.Show = customContainerShow
	LibStub("AceConfigDialog-3.0"):Open(app, customContainer)
	customContainer:SetTitle(title)
end

function MNT2:CloseCustomContainer()
	customContainer:Hide()
	customContainer.Show = dummyFunc
	self:UpdateMountOptions()
end

MNT2.mountSpeeds = {
	[0] = L['0%'],
	[20] = L['20%'],
	[40] = L['40%'],
	[50] = L['50%'],
	[60] = L['60%'],
	[100] = L['100%'],
	[280] = L['280%'],
	[310] = L['310%'],
}

local mountTypes = {
	['ground'] = L['Ground'],
	['flying'] = L['Flying'],
	['water'] = L['Water'],
	['aq'] = L["Ahn'Qiraj"], -- will always be 100% speed :)
}

local SpeedsPerType = { -- 0 is always an option :P
	['ground'] = {0,40,60,100},
	['flying'] = {0,60,280,310},
	['water'] = {0,20,50},
	['aq'] = {0,100},
}

local emptyTable = {}

local sliderspeedtest = 0
local continent, zone, numContinent
MNT2.MainOption = {
	type="group",
	width = 'fill',
	handler = MNT2,
	childGroups = 'tab',
	args={
		alwaysdifferent  = {
			name = L["Gurantee Different Mount"],
			order = 1,
			type = 'toggle',
			width = 'full',
			get = function() return MNT2.db.profile.alwaysdifferent end,
			set = function(info, val) MNT2.db.profile.alwaysdifferent = val end,
		},
		continent = {
			name = CONTINENT,
			order = 10,
			type = 'select',
			values = function()
				local c = {GetMapContinents()}
				numContinent = #c
				c[#c+1] = INSTANCE
				c[#c+1] = BATTLEGROUND
				return c
			end,
			get = function() return continent end,
			set = function(info, val)
				continent = val
				zone = nil
			end,
		},
		zone = {
			name = ZONE,
			order = 20,
			type = 'select',
			disabled = function() return not continent end,
			values = function()
				if continent then
					local zones = {}
					if continent == numContinent+1 then
						for instance in LibStub('LibTourist-3.0'):IterateInstances() do
							if not MNT2.db.profile.macrosets[instance] then
								zones[instance] = instance
							end
						end
					elseif continent == numContinent+2 then
						for bg in LibStub('LibTourist-3.0'):IterateBattlegrounds() do
							if not MNT2.db.profile.macrosets[bg] then
								zones[bg] = bg
							end
						end
					else
						local z = {GetMapZones(continent)}
						for i, zo in ipairs(z) do
							if not MNT2.db.profile.macrosets[zo] then
								zones[zo] = zo
							end
						end
					end
					return zones
				else
					return emptyTable
				end
			end,
			get = function() return zone end,
			set = function(info, val) zone = val end,
		},
		ADD = {
			name = ADD,
			desc = L['ADD desc'],
			type = 'execute',
			order = 30,
			disabled = function() return not (continent and  zone) end,
			confirm  = function() return string.format(L['ADD confirm'], zone) end,
			func = function(info)
				MNT2.db.profile.macrosets[zone] = {
					['inCombat'] = 'Unassigned',
					['isIndoors'] = 'Unassigned',
					['isSwimming'] = 'Unassigned',
					['isFlyable'] = 'Unassigned',
					['ground'] = 'Unassigned',
				}
				if continent > numContinent then
					MNT2.db.profile.instanceMacroSets[zone] = true
				end
				zone = nil
				continent = nil
				MNT2:UpdateMainOptions()
			end,
		},
	},
	plugins={
		MA = {},
	},
}

local macroAssignments = {
	type = 'group',
	name = function(info) return _G[info[#info]] or L[info[#info]] end,
	order = function(info) return MNT2.macroSetOrder[info[#info]] end,
	args = {
		enable = {
			name = ENABLE,
			desc = function(info)
				if info[#info-1] == 'isMoving' then
					return L['isMoving desc']
				else
					return L['ENABLE desc']
				end
			end,
			type = 'toggle',
			order = 1,
			disabled = function(info) return info[#info-1] == 'DEFAULT' and true or false end,
			get = function(info)
				return MNT2.db.profile.activeMacroSets[info[#info-1]]
			end,
			set = function(info, val)
				MNT2.db.profile.activeMacroSets[info[#info-1]] = val
				if info[#info-1] == 'isMoving' then
					if MNT2.db.profile.activeMacroSets.isMoving then
						MNT2:SetScript("OnUpdate", MNT2.OnUpdate)
					else
						MNT2:SetScript("OnUpdate", nil)
					end
				end
				MNT2:GenerateMacro()
			end,
		},
		DELETE = {
			name = DELETE,
			desc = L['DELETE desc'],
			type = 'execute',
			order = 2,
			disabled = function(info) return info[#info-1] == 'DEFAULT' and true or info[#info-1] == 'isMoving' and true or false end,
			confirm = function(info) return string.format(L['DELETE confirm'], info[#info-1]) end,
			func = function(info)
				MNT2.db.profile.macrosets[info[#info-1]] = nil
				MNT2.db.profile.activeMacroSets[info[#info-1]] = nil
				MNT2.db.profile.instanceMacroSets[info[#info-1]] = nil
				MNT2:UpdateMainOptions()
				MNT2:GenerateMacro()
			end,
		},
	},
}

local macrosOrder = {
	['isFlyable'] = 2,
	['ground'] = 3,
	['inCombat'] = 4,
	['isSwimming'] = 5,
	['isIndoors'] = 6,
}
local macroselect = {
	name = function(info) return L[info[#info]] end,
	type = 'select',
	width = 'full',
	order = function(info) return macrosOrder[info[#info]] end,
	values = function(info)
		local macros = {}
		for macroName in pairs(MNT2.db.global.macros) do
			macros[macroName] = macroName
		end
		return macros
	end,
	get = function(info)
		return MNT2.db.profile.macrosets[info[#info-1]][info[#info]]
	end,
	set = function(info, val)
		MNT2.db.profile.macrosets[info[#info-1]][info[#info]] = val
		MNT2:GenerateMacro()
	end,
}
for macroType in pairs(macrosOrder) do
	macroAssignments.args[macroType] = macroselect
end


function MNT2:UpdateMainOptions() -- lets not worry about garbage this should never be called often
	self.macroSetOrder = {}
	local setOrder = {}
	for name in pairs(self.db.profile.macrosets) do
		setOrder[#setOrder+1] = name
	end
	table.sort(setOrder)
	wipe(self.MainOption.plugins.MA) -- reset the plugins so we can move on and repopulate
	for i, setName in ipairs(setOrder) do
		if setName == 'DEFAULT' then
			self.macroSetOrder[setName] = 1
		elseif setName == 'isMoving' then
			self.macroSetOrder[setName] = 50
		else
			self.macroSetOrder[setName] = i*100
		end
		self.MainOption.plugins.MA[setName] = macroAssignments
	end

end

MNT2.MountOptions = {
	type="group",
	width = 'fill',
	handler = MNT2,
	childGroups = 'tab',
	args={
		AddSpell = {
			name = L['AddSpell'],
			desc = L['AddSpell desc'],
			type = 'input',
			order = 1,
			width = 'full',
			validate = function(info, val)
				local name, rank, _, _, _, _, castTime = GetSpellInfo(val)
				if GetSpellLink(name or '', rank) then
					local mountSpellID = tonumber(string.match(GetSpellLink(name, rank), 'spell:(%d+)'))
					if MNT2:MountExists(mountSpellID) then
						print('MNT2: '..string.format(L['Already Exists'], val))
						return string.format(L['Already Exists'], val)
					else
						return true
					end
				else
					print('MNT2: '..string.format(L['Invalid Spell'], val))
					return string.format(L['Invalid Spell'], val)
				end
			end,
			set = function(info, val)
				local name, rank, _, _, _, _, castTime = GetSpellInfo(val)
				mountedit = tonumber(string.match(GetSpellLink(name, rank), 'spell:(%d+)'))
				MNT2.db.char.mountSummonMode[mountedit] = castTime == 0 and 'instant' or 'cast'
				wipe(MountEditSpeeds)
				currentSpeed = nil
				currentType = nil
				MNT2:OpenCustomContainer('MNT2MountEditor', L['Mount Editor'])
			end
		},
	},
	plugins={
		MA = {},
	},
}
function MNT2:GetPriority(info)
	local mountType, mountSpeed = string.match(info[#info-2], '(.+):(.+)')
	local mountID = tonumber(info[#info-1])
	if mountID then
		return self.db.char.mounts[mountType][tonumber(mountSpeed)][mountID]
	else
		return self.db.char.mountSetsPriority[mountType][tonumber(mountSpeed)][info[#info-1]]
	end
end
function MNT2:SetPriority(info, num)
	local mountType, mountSpeed = string.match(info[#info-2], '(.+):(.+)')
	local mountID = tonumber(info[#info-1])
	if mountID then
		self.db.char.mounts[mountType][tonumber(mountSpeed)][mountID] = num
	else
		self.db.char.mountSetsPriority[mountType][tonumber(mountSpeed)][info[#info-1]] = num
	end
end

local SetName
local SetType
local existingSet
local SetMounts
local mountgroup = {
	type = 'group',
	inline = true,
	name = function(info) 
		if tonumber(info[#info]) then
			return '|cff71d5ff'..GetSpellInfo(info[#info])..FONT_COLOR_CODE_CLOSE
		else
			return HIGHLIGHT_FONT_COLOR_CODE..info[#info]..FONT_COLOR_CODE_CLOSE
		end
	end,
	order = function(info) return MNT2.OrderMounts[tonumber(info[#info])] or string.byte(info[#info]) end,
	hidden = function(info)
		local mountType, mountSpeed = string.match(info[#info-1], '(.+):(.+)')
		local mountID = tonumber(info[#info])
		if mountType and mountID then
			return MNT2:IsInSet(mountID, mountType, tonumber(mountSpeed))
		else
			return false
		end
	end,
	args = {
		priority = {
			name = L['Summon Priority'],
			order = 100,
			type = 'range',
			min = 0,
			max = 10,
			step = .1,
			get = 'GetPriority',
			set = 'SetPriority',
		},
		edit = {
			name = L['Edit'],
			desc = L['Edit desc'],
			type = 'execute',
			order = 200,
			width = 'half',
			func = function(info)
				local mountID = tonumber(info[#info-1])
				if mountID then
					mountedit = mountID
					wipe(MountEditSpeeds)
					for MountType in pairs(MNT2.db.char.mounts) do
						for speed, t in pairs(MNT2.db.char.mounts[MountType]) do
							if t[mountedit] then
								MountEditSpeeds[MountType] = MountEditSpeeds[MountType] or {}
								MountEditSpeeds[MountType][speed] = true
							end
						end
					end
					currentSpeed = nil
					currentType = nil
					MNT2:OpenCustomContainer('MNT2MountEditor', L['Mount Editor'])
				else
					local mountType, mountSpeed = string.match(info[#info-2], '(.+):(.+)')
					SetName = info[#info-1]
					SetType = info[#info-2]
					existingSet = true
					SetMounts = CopyTable(MNT2.db.char.mountSets[mountType][tonumber(mountSpeed)][SetName])
					MNT2:OpenMounSetOptions()
				end
			end,
		},
	}
}

MNT2.MountEditor = {
	name = L['Mount Editor'],
	type = 'group',
	inline = true,
	args = {
		header = {
			name = function(info) return '|cff71d5ff'..GetSpellInfo(mountedit)..'|r' end,
			type = 'header',
			order = 100,
		},
		list = {
			type = 'description',
			order = 200,
			name = function()
				local text = {}
				for MountType, t in pairs(MountEditSpeeds) do
					for MountSpeed in pairs(t) do
						text[#text+1] = string.format(L['type/speed format'], mountTypes[MountType], MNT2.mountSpeeds[MountSpeed])
					end
				end
				return table.concat(text, L[', '])
			end,
		},
		MountType = {
			name = L["Mount Type"],
			type = "select",
			order = 400,
			values = mountTypes,
			set = function(info,type)
				currentType = type
				currentSpeed = nil
			end,
			get = function(info) return currentType end,
		},
		MountSpeed = {
			name = L["Mount Speed"],
			type = "select", dialogControl = 'List_Slider',
			order = 500,
			disabled = function() return not currentType end,
			values = function()
				if not currentType then return emptyTable end
				local speeds = {}
				for i, speed in ipairs(SpeedsPerType[currentType]) do
					speeds[speed] = MNT2.mountSpeeds[speed]
				end
				return speeds
			end,
			set = function(info,speed)
				currentSpeed = speed
			end,
			get = function(info) return currentSpeed end,
		},
		AddSpeed = {
			name = L['Add Speed'],
			desc = L['Add Speed desc'],
			type = 'execute',
			order = 700,
			width = 'full',
			disabled = function() return not (currentSpeed and  currentType) end,
			func = function(info)
				MountEditSpeeds[currentType] = MountEditSpeeds[currentType] or {}
				MountEditSpeeds[currentType][currentSpeed] = true
				currentSpeed = nil
				currentType = nil
			end,
		},
		SAVE = {
			name = SAVE,
			desc = L['SAVE desc'],
			type = 'execute',
			order = 800,
			width = 'half',
			confirm = true,
			confirmText = L['SAVE confirm'],
			disabled = function() return not next(MountEditSpeeds) end,
			func = function(info)
				for MountType in pairs(MNT2.db.char.mounts) do
					for speed, t in pairs(MNT2.db.char.mounts[MountType]) do
						if t[mountedit] then
							MNT2.db.char.mounts[MountType][speed][mountedit] = nil
							if not next(MNT2.db.char.mounts[MountType][speed]) then
								MNT2.db.char.mounts[MountType][speed] = nil
							end
						end
					end
				end
				for MountType, t in pairs(MountEditSpeeds) do
					for MountSpeed in pairs(t) do
						MNT2.db.char.mounts[MountType] = MNT2.db.char.mounts[MountType] or {}
						MNT2.db.char.mounts[MountType][MountSpeed] = MNT2.db.char.mounts[MountType][MountSpeed] or {}
						MNT2.db.char.mounts[MountType][MountSpeed][mountedit] = 5
					end
				end
				MNT2:CloseCustomContainer()
				MNT2:LocalizeIDs()
				MNT2:GenerateMacro()
			end,
		},
		CLEAR_ALL = {
			name = CLEAR_ALL,
			desc = L['CLEAR_ALL desc'],
			type = 'execute',
			order = 900,
			disabled = function() return not next(MountEditSpeeds) end,
			func = function(info)
				wipe(MountEditSpeeds)
			end,
		},
		DELETE = {
			name = DELETE,
			desc = L['DELETE Mdesc'],
			type = 'execute',
			order = 900,
			width = 'half',
			confirm = true,
			confirmText = L['DELETE Mconfirm'],
			disabled = function() return not MNT2:MountExists(mountedit) end,
			func = function(info)
				for MountType in pairs(MNT2.db.char.mounts) do
					for speed, t in pairs(MNT2.db.char.mounts[MountType]) do
						if t[mountedit] then
							MNT2.db.char.mounts[MountType][speed][mountedit] = nil
							if not next(MNT2.db.char.mounts[MountType][speed]) then
								MNT2.db.char.mounts[MountType][speed] = nil
							end
						end
					end
				end
				MNT2.db.char.mountSummonMode[mountedit] = nil
				MNT2:CloseCustomContainer()
				MNT2:LocalizeIDs()
				MNT2:GenerateMacro()
			end,
		},
	},
}
LibStub("AceConfig-3.0"):RegisterOptionsTable('MNT2MountEditor', MNT2.MountEditor)
LibStub("AceConfigDialog-3.0"):SetDefaultSize('MNT2MountEditor', 395, 225)

MNT2.mountSetOptions = {
	name = L['Mount Set Options'],
	type = 'group',
	args = {
		name = {
			name = L['Mount Set Name'],
			type = 'input',
			order = 1,
			width = 'double',
			disabled = function() return existingSet end,
			validate = function(info, val)
				if tonumber(val) then
					return L['Mount Set Name may not be a number.']
				elseif not val or val == ''  then
					return L['Mount Set Name may not be a empty string.']
				else
					return true
				end
			end,
			get = function(info) return SetName end,
			set = function(info, val) SetName = val end,
		},
		save = {
			name = SAVE,
			type = 'execute',
			order = 2,
			disabled = function() return SetMounts and not next(SetMounts) or not SetName or SetName == '' end,
			func = function(info)
				local mountType, mountSpeed = string.match(SetType, '(.+):(.+)')
				MNT2.db.char.mountSets[mountType][tonumber(mountSpeed)] = MNT2.db.char.mountSets[mountType][tonumber(mountSpeed)] or {}
				MNT2.db.char.mountSets[mountType][tonumber(mountSpeed)][SetName] = SetMounts
				MNT2.db.char.mountSetsPriority[mountType][tonumber(mountSpeed)] = MNT2.db.char.mountSetsPriority[mountType][tonumber(mountSpeed)] or {}
				MNT2.db.char.mountSetsPriority[mountType][tonumber(mountSpeed)][SetName] = 5
				SetMounts = nil
				MNT2:CloseCustomContainer()
			end,
		},
		delete = {
			name = DELETE,
			type = 'execute',
			order = 3,
			disabled = function() return not existingSet end,
			func = function(info)
				local mountType, mountSpeed = string.match(SetType, '(.+):(.+)')
				MNT2.db.char.mountSets[mountType][tonumber(mountSpeed)][SetName] = nil
				if not next(MNT2.db.char.mountSets[mountType][tonumber(mountSpeed)]) then
					MNT2.db.char.mountSets[mountType][tonumber(mountSpeed)] = nil
				end
				MNT2.db.char.mountSetsPriority[mountType][tonumber(mountSpeed)][SetName] = nil
				if not next(MNT2.db.char.mountSetsPriority[mountType][tonumber(mountSpeed)]) then
					MNT2.db.char.mountSetsPriority[mountType][tonumber(mountSpeed)] = nil
				end
				SetMounts = nil
				MNT2:CloseCustomContainer()
			end,
		},
	},
	plugins={
		MA = {},
	},
}

local mountCheckMark = {
	name = function(info) return GetSpellInfo(info[#info]) end,
	type = 'toggle',
	width = 'full',
	disabled = function(info)
		local mountType, mountSpeed = string.match(SetType, '(.+):(.+)')
		return MNT2:IsInSet(tonumber(info[#info]), mountType, tonumber(mountSpeed), SetName)
	end,
	order = function(info) return tonumber(info[#info]) end,
	get = function(info) return SetMounts and SetMounts[tonumber(info[#info])] end,
	set = function(info, val)
		if val == false then val = nil end
		SetMounts[tonumber(info[#info])] = val
	end,
}

function MNT2:OpenMounSetOptions()
	local mountType, mountSpeed = string.match(SetType, '(.+):(.+)')
	mountSpeed = tonumber(mountSpeed)
	wipe(MNT2.mountSetOptions.plugins.MA)
	for mount in pairs(self.db.char.mounts[mountType][mountSpeed]) do
		MNT2.mountSetOptions.plugins.MA[tostring(mount)] = mountCheckMark
	end
	MNT2:OpenCustomContainer('MNT2mountSetOptions', L['Mount Set Options'])
end

function MNT2:IsInSet(mountID, mountType, mountSpeed, CurrentSet)
	CurrentSet = CurrentSet or '__nil'
	if self.db.char.mountSets[mountType][mountSpeed] then
		for setName, sNt in pairs(self.db.char.mountSets[mountType][mountSpeed]) do
			if setName ~= CurrentSet then
				for mount in pairs(sNt) do
					if mount == mountID then
						return setName
					end
				end
			end
		end
	end
	return false
end
LibStub("AceConfig-3.0"):RegisterOptionsTable('MNT2mountSetOptions', MNT2.mountSetOptions)
LibStub("AceConfigDialog-3.0"):SetDefaultSize('MNT2mountSetOptions', 395, 395)

local mountSetsButton = {
	name = L['Create Mount Set'],
	type = 'execute',
	order = 1,
	width = 'full',
	func = function(info) 
		SetName = nil
		SetType = info[#info-1]
		existingSet = nil
		SetMounts = {}
		MNT2:OpenMounSetOptions()
	end,
}

function MNT2:UpdateMountOptions()
	local mountTypesPriority = { -- shouldn't be called often so we can create it each time and let the GC deal with it later
		'flying',
		'ground',
		'water',
		'aq',
	}
	local mOrder = 100
	MNT2.MountOptions.plugins.MA = {}
	for i=1, #mountTypesPriority do
		local mounttype = mountTypesPriority[i]
		if next(self.db.char.mounts[mounttype]) then
			local speeds = {}
			for speed in pairs(self.db.char.mounts[mounttype]) do
				speeds[#speeds+1] = speed
			end
			table.sort(speeds, function(a,b) return b<a end)
			for i, speed in ipairs(speeds) do
				if next(self.db.char.mounts[mounttype][speed]) then
					MNT2.MountOptions.plugins.MA[mounttype..':'..speed] = {
						name = mountTypes[mounttype]..' '..self.mountSpeeds[speed],
						order = mOrder,
						type = 'group',
						width = 'full',
						args = {},
					}
					MNT2.MountOptions.plugins.MA[mounttype..':'..speed].args['mountSetsButton'] = mountSetsButton
					for mount in pairs(self.db.char.mounts[mounttype][speed]) do
						MNT2.MountOptions.plugins.MA[mounttype..':'..speed].args[tostring(mount)] = mountgroup
					end
					if self.db.char.mountSets[mounttype][speed] then
						for set in pairs(self.db.char.mountSets[mounttype][speed]) do
							MNT2.MountOptions.plugins.MA[mounttype..':'..speed].args[set] = mountgroup
						end
					end
					mOrder = mOrder + 100
				end
			end
		end
	end
	LibStub("AceConfigDialog-3.0"):ConfigTableChanged(nil,'MNT2MountOptions')
end

local selectedMacro
MNT2.MacroOptions = {
	type="group",
	width = 'fill',
	handler = MNT2,
	childGroups = 'tab',
	args={
		macroselect = {
			name = L['Select Macro:'],
			name = L['Select Macro:'],
			order = 1,
			type = 'select',
			width = 'full',
			values = function()
				local m = {}
				for macro in pairs(MNT2.db.global.macros) do
					m[macro] = macro
				end
				return m
			end,
			get = function() return selectedMacro end,
			set = function(info, val) selectedMacro = val end,
		},
		NEW = {
			name = NEW,
			desc = L['NEW desc'],
			type = 'execute',
			order = 2,
			width = 'half',
			func = function(info)
				MNT2:OpenMacroEditor()
			end,
		},
		EDIT = {
			name = L['EDIT'],
			desc = L['EDIT desc'],
			type = 'execute',
			order = 3,
			width = 'half',
			disabled = function() return not selectedMacro or MNT2.resevedMacroName[selectedMacro] end,
			func = function(info)
				MNT2:OpenMacroEditor(MNT2.db.global.macros[selectedMacro], selectedMacro)
			end,
		},
		DELETE = {
			name = DELETE,
			desc = L['DELETE desc'],
			type = 'execute',
			order = 4,
			width = 'half',
			confirm  = function() return string.format(L['DELETE macro confirm'], selectedMacro) end,
			disabled = function() return not selectedMacro or MNT2.resevedMacroName[selectedMacro] end,
			func = function(info)
				MNT2.db.global.macros[selectedMacro] = nil
			end,
		},
		MacroPreview = {
			name = function()
				local valid, macro = MNT2:ParseMacro(MNT2.db.global.macros[selectedMacro])
				return string.format(L['|cffffd200Macro Preview:|r\n%s'],tostring(macro))..'\n\n'..string.format(L['|cffffd200Macro Text:|r\n%s'], MNT2.db.global.macros[selectedMacro] or '')
			end,
			type = 'description',
			order = 5,
		}
	},
}

MNT2.optframe = {}
LibStub("AceConfig-3.0"):RegisterOptionsTable('MNT2', MNT2.MainOption)
MNT2.optframe.MNT2 = LibStub("AceConfigDialog-3.0"):AddToBlizOptions('MNT2', 'Mounted')
-- function addapted from the RegisterModuleOptions function in Mapster
function MNT2:RegisterModuleOptions(name, optionTbl, displayName)
	local cname = "MNT2"..name
	LibStub("AceConfigRegistry-3.0"):RegisterOptionsTable(cname, optionTbl)
	self.optframe[name] = LibStub("AceConfigDialog-3.0"):AddToBlizOptions(cname, displayName, "Mounted")
end
MNT2:RegisterModuleOptions('MountOptions', MNT2.MountOptions, L['Mount Options'])
MNT2:RegisterModuleOptions('MacroOptions', MNT2.MacroOptions, L['Macro Options'])

--/script MNT2:OpenMacroEditor(macrotext, name)
do
	local MacroFrame
	local currmacrotext
	local preview = false
	local function SetTooltip(frame)
		GameTooltip:ClearLines()
		GameTooltip:SetOwner(frame, 'ANCHOR_BOTTOMRIGHT', -305,20)
		GameTooltip:AddLine(L["FAQheader"])
		GameTooltip:AddLine("|cffffffff"..L["FAQdesc"])
		GameTooltip:SetToplevel(true)
		GameTooltip:Show()
	end
	function MNT2:OpenMacroEditor(macrotext, macroname)
		if MacroFrame then
			MacroFrame:Show()
		else
			local FrameBackdrop = {
					bgFile="Interface\\DialogFrame\\UI-DialogBox-Background",
					edgeFile="Interface\\DialogFrame\\UI-DialogBox-Border",
					tile = true, tileSize = 32, edgeSize = 32,
					insets = { left = 8, right = 8, top = 8, bottom = 8 }
				}
			local ControlBackdrop = {
					bgFile = "Interface\\Tooltips\\UI-Tooltip-Background",
					edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
					tile = true, tileSize = 16, edgeSize = 16,
					insets = { left = 3, right = 3, top = 3, bottom = 3 }
				}
			MacroFrame = CreateFrame("Frame","MNT2_Macro_Edit_Frame",UIParent)
				MacroFrame:SetFrameStrata("TOOLTIP")
				MacroFrame:SetWidth(350)
				MacroFrame:SetHeight(243)
				MacroFrame:SetPoint("CENTER",UIParent,"CENTER",0,0)
				MacroFrame:SetBackdrop(FrameBackdrop)
				MacroFrame:SetBackdropColor(0,0,0,1)
				MacroFrame:SetMovable(true)
			local SaveButton = CreateFrame("Button",nil,MacroFrame,"UIPanelButtonTemplate")
				SaveButton:SetHeight(24)
				SaveButton:SetWidth(100)
				local SaveText = SaveButton:GetFontString()
					SaveText:SetPoint("LEFT",SaveButton,"LEFT",15,0)
					SaveText:SetPoint("RIGHT",SaveButton,"RIGHT",-15,0)
					SaveText:SetText(SAVE)
				SaveButton:SetPoint("BOTTOMLEFT",MacroFrame,"BOTTOMLEFT",15,15)
			local CloseButton = CreateFrame("Button",nil,MacroFrame,"UIPanelButtonTemplate")
				CloseButton:SetHeight(24)
				CloseButton:SetWidth(100)
				local CloseText = CloseButton:GetFontString()
					CloseText:SetPoint("LEFT",CloseButton,"LEFT",15,0)
					CloseText:SetPoint("RIGHT",CloseButton,"RIGHT",-15,0)
					CloseText:SetText(CANCEL)
				CloseButton:SetPoint("BOTTOMRIGHT",MacroFrame,"BOTTOMRIGHT",-15,15)
			local PreviewButton = CreateFrame("Button",nil,MacroFrame,"UIPanelButtonTemplate")
				PreviewButton:SetHeight(24)
				PreviewButton:SetWidth(100)
				local PreviewText = PreviewButton:GetFontString()
					PreviewText:SetPoint("LEFT",PreviewButton,"LEFT",15,0)
					PreviewText:SetPoint("RIGHT",PreviewButton,"RIGHT",-15,0)
					PreviewText:SetText(L['Preview'])
				PreviewButton:SetPoint("BOTTOM",MacroFrame,"BOTTOM",0,15)
			local MacroEditBox = CreateFrame("Frame", nil, MacroFrame)
				MacroEditBox:SetHeight(150)
				MacroEditBox:SetPoint("BOTTOMLEFT",SaveButton,"TOPLEFT",0,0)
				MacroEditBox:SetPoint("BOTTOMRIGHT",CloseButton,"TOPRIGHT",0,0)
				MacroEditBox:EnableMouse(true)
				local MacroEditBoxbackdrop = CreateFrame("Frame", nil, MacroEditBox)
					MacroEditBoxbackdrop:SetBackdrop(ControlBackdrop)
					MacroEditBoxbackdrop:SetBackdropColor(0, 0, 0)
					MacroEditBoxbackdrop:SetBackdropBorderColor(0.4, 0.4, 0.4)
					MacroEditBoxbackdrop:SetPoint("TOPLEFT",MacroEditBox,"TOPLEFT",0, -20)
					MacroEditBoxbackdrop:SetPoint("BOTTOMRIGHT",MacroEditBox,"BOTTOMRIGHT",0,0)
					MacroEditBoxbackdrop:SetScript("OnEnter",function() SetTooltip(MacroEditBoxbackdrop) end)
					MacroEditBoxbackdrop:SetScript("OnLeave",function() GameTooltip:Hide() end)
				local MacroEditScrollframe = CreateFrame("ScrollFrame", 'MNT2_MacroEditScrollframe', MacroEditBoxbackdrop, "UIPanelScrollFrameTemplate")
					MacroEditScrollframe:SetPoint("TOPLEFT", 5, -6)
					MacroEditScrollframe:SetPoint("BOTTOMRIGHT", -28, 6)
					MacroEditScrollframe:SetScript("OnEnter",function() SetTooltip(MacroEditBoxbackdrop) end)
					MacroEditScrollframe:SetScript("OnLeave",function() GameTooltip:Hide() end)
				local MacroEditScrollchild = CreateFrame("Frame", nil, MacroEditScrollframe)
					MacroEditScrollframe:SetScrollChild(MacroEditScrollchild)
					MacroEditScrollchild:SetHeight(MacroEditScrollframe:GetHeight())
					MacroEditScrollchild:SetWidth(MacroEditScrollframe:GetWidth())
					MacroEditScrollchild:SetScript("OnEnter",function() SetTooltip(MacroEditBoxbackdrop) end)
					MacroEditScrollchild:SetScript("OnLeave",function() GameTooltip:Hide() end)
				local MacroEditLabel = MacroEditBox:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
					MacroEditLabel:SetPoint("TOPLEFT",MacroEditBox,"TOPLEFT",0,-2)
					MacroEditLabel:SetPoint("TOPRIGHT",MacroEditBox,"TOPRIGHT",0,-2)
					MacroEditLabel:SetJustifyH("LEFT")
					MacroEditLabel:SetHeight(18)
					MacroEditLabel:SetText(ENTER_MACRO_LABEL)
				local MacroEditEditbox = CreateFrame("EditBox", nil, MacroEditScrollchild)
					MacroEditEditbox:SetPoint("TOPLEFT")
					MacroEditEditbox:SetHeight(50)
					MacroEditEditbox:SetWidth(MacroEditScrollframe:GetWidth())
					MacroEditEditbox:SetMultiLine(true)
					MacroEditEditbox:SetTextInsets(5, 5, 3, 3)
					MacroEditEditbox:EnableMouse(true)
					MacroEditEditbox:SetAutoFocus(false)
					MacroEditEditbox:SetFontObject(ChatFontNormal)
					MacroEditEditbox:SetScript("OnEscapePressed",function() MacroEditEditbox:ClearFocus() end)
					MacroEditEditbox:SetScript("OnEnter",function() SetTooltip(MacroEditBoxbackdrop) end)
					MacroEditEditbox:SetScript("OnLeave",function() GameTooltip:Hide() end)
				MacroEditScrollframe:EnableMouse(true)
				MacroEditScrollframe:SetScript("OnMouseUp", function() MacroEditEditbox:SetFocus() end)
			local MacroNameBox = CreateFrame("Frame", nil, MacroFrame)
				MacroNameBox:SetHeight(44)
				MacroNameBox:SetPoint("BOTTOMLEFT",MacroEditBox,"TOPLEFT",0,0)
				MacroNameBox:SetPoint("BOTTOMRIGHT",MacroEditBox,"TOPRIGHT",0,0)
				local MacroNameEditbox = CreateFrame("EditBox","MNT2_MacroNameBox",MacroNameBox,"InputBoxTemplate")
					MacroNameEditbox:SetFontObject(ChatFontNormal)
					MacroNameEditbox:SetTextInsets(0,0,3,3)
					MacroNameEditbox:SetMaxLetters(16)
					MacroNameEditbox:SetPoint("BOTTOMLEFT",MacroNameBox,"BOTTOMLEFT",6,0)
					MacroNameEditbox:SetPoint("BOTTOMRIGHT",MacroNameBox,"BOTTOMRIGHT",0,0)
					MacroNameEditbox:SetHeight(19)
					MacroNameEditbox:EnableMouse(true)
					MacroNameEditbox:SetAutoFocus(false)
					MacroNameEditbox:SetScript("OnEscapePressed",function() MacroNameEditbox:ClearFocus() end)
				local MacroNameLabel = MacroNameBox:CreateFontString(nil,"OVERLAY","GameFontNormalSmall")
					MacroNameLabel:SetPoint("TOPLEFT",MacroNameBox,"TOPLEFT",0,-2)
					MacroNameLabel:SetPoint("TOPRIGHT",MacroNameBox,"TOPRIGHT",0,-2)
					MacroNameLabel:SetJustifyH("LEFT")
					MacroNameLabel:SetHeight(18)
					MacroNameLabel:SetText(MACRO_POPUP_TEXT)
			CloseButton:SetScript("OnClick",function()
					MacroEditEditbox:SetText('')
					MacroNameEditbox:SetText('')
					currmacrotext = nil
					preview = false
					MacroFrame:Hide()
				end)
			PreviewButton:SetScript("OnClick",function()
					MacroEditEditbox:ClearFocus()
					MacroNameEditbox:ClearFocus()
					if not preview then
						currmacrotext = tostring(MacroEditEditbox:GetText())
					end
					local valid, macro = MNT2:ParseMacro(currmacrotext)
					MacroEditEditbox:SetText(macro)
					preview = true
				end)
			MacroEditEditbox:SetScript("OnEditFocusGained",function()
					if currmacrotext then
						MacroEditEditbox:SetText(currmacrotext)
						currmacrotext = nil
					end
					preview = false
				end)
			SaveButton:SetScript("OnClick",function()
					if not MacroNameEditbox:GetText() or MacroNameEditbox:GetText() == '' or MNT2.resevedMacroName[MacroNameEditbox:GetText()] then
						return print(string.format(L['NameError'], tostring(MacroNameEditbox:GetText())))
					end
					local macrotext = currmacrotext or MacroEditEditbox:GetText()
					if macrotext and string.gsub(macrotext, ' ', '') ~= '' then
						for i=1,10 do
							if string.len(select(2,MNT2:ParseMacro(macrotext))) > 255 then
								return print(L["Macro length error"])
							end
						end
					else
						return print(L["No Macro Text"])
					end
					MNT2.db.global.macros[MacroNameEditbox:GetText()] = macrotext
					currmacrotext = nil
					preview = false
					LibStub("AceConfigDialog-3.0"):ConfigTableChanged(nil,'MNT2MacroOptions')
					MacroFrame:Hide()
				end)
			MacroFrame.macro = MacroEditEditbox
			MacroFrame.name = MacroNameEditbox
			tinsert(UISpecialFrames, "MNT2_Macro_Edit_Frame")
		end
		MacroFrame.name:SetText(macroname or '')
		MacroFrame.macro:SetText(macrotext or '')
	end
end
