-- This work is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
-- To view a copy of this license, visit http://creativecommons.org/licenses/by-sa/3.0/
-- or send a letter to Creative Commons, 444 Castro Street, Suite 900, Mountain View, California, 94041, USA.

local MereHealingFrames, privateVars = ...

local GetOpt = Library.LibGetOpt
GetOpt.DebugLevel = 0

MereHealingFrames.Commands = {}

local function mhfCommands(eventHandler, params)

	local getoptParams = GetOpt.dequote(params)

	if #getoptParams == 0 then
		MereHealingFrames.Commands.Help()
		return
	end

	if getoptParams[1] == "show" then
			MereHealingFrames.SetVisible(true)
	elseif getoptParams[1] == "hide" then
			MereHealingFrames.SetVisible(false)
	elseif getoptParams[1] == "list" then
		for key, layout in pairs(MereHealingFrames.Layouts) do
			print(key)
		end
	elseif getoptParams[1] == "debug" then
		MereHealingFrames.Commands.Debug(getoptParams)
	elseif getoptParams[1] == "config" then
		MereHealingFrames.Config.window:show()
	elseif getoptParams[1] == "layout" then
		MereHealingFrames.Commands.Layout(getoptParams)
	elseif getoptParams[1] == "spell" then
		MereHealingFrames.Commands.Spells(getoptParams)
	elseif getoptParams[1] == "colours" or getoptParams[1] == "colors" then
		MereHealingFrames.Commands.Colours(getoptParams)
	elseif getoptParams[1] == "tooltips" then
		local newValue = not MereHealingFrames.ToolTip.showToolTips
		MereHealingFrames.ToolTip.showToolTips = newValue
		if newValue then
			print("Tooltips enabled")
		else
			print("Tooltips disabled")
		end
	else
		MereHealingFrames.Commands.Help()
	end
end

function MereHealingFrames.SetVisible(visible)
	for key, layout in pairs(MereHealingFrames.Layouts) do
		layout:SetVisible(visible)
	end
end

Command.Event.Attach(Command.Slash.Register("mhf"), mhfCommands, "mhfCommands")

function MereHealingFrames.Commands.Help()
	print ("/mhf show -- Show layouts")
	print ("/mhf hide -- Hide layouts")
	print ("/mhf list -- List layouts")
    print ("/mhf layout -- layout configuration")
	print ("/mhf tooltips -- Toggle tooltip display")
	print ("/mhf debug -- debug/tracing options")
	print ("/mhf spell -- spell configuration options")
	print ("/mhf colours -- colour configuration options")
end


local LayoutOptions = {
		{"add", "a", nil, "add a new layout"},
		{"list", "l", nil, "list layouts" },
		{"name", "n", ":", "layout name" },
		{"rename", "r", ":", "new layout name" },
		{"display", "d", nil, "display the named layout details" },
		{"unlock", nil, nil, "unlock all layouts for moving" },
		{"lock", nil, nil, "lock all layouts from moving" },
		{"filter", "f", ":+", "enable filter, list role types, tank, dps, support or heal " },
		}
function MereHealingFrames.Commands.Layout(params)
	table.remove(params,1)

	local getOptParams = GetOpt.getopt(LayoutOptions, params);

	if getOptParams == nil then
        print("/mhf layout should be followed by the options:")
        GetOpt.print(LayoutOptions)
        return
    end
	if (getOptParams.list) then
		print("Found ".. #MereHealingFrames.Layouts .. " layout")
		for key, layout in pairs(MereHealingFrames.Layouts) do
			print(key)
		end
	elseif (getOptParams.unlock) then
		print("Layouts are now unlocked.")
		MereHealingFrames.HealingPanelsLocked = false
		for key, layout in pairs(MereHealingFrames.Layouts) do
			layout:UnlockLayout()
		end
	elseif (getOptParams.lock) then
		print("Layouts are now locked.")
		MereHealingFrames.HealingPanelsLocked = true
		for key, layout in pairs(MereHealingFrames.Layouts) do
			layout:LockLayout()
		end
	elseif (getOptParams.name) then
		local layout = MereHealingFrames.Layouts[getOptParams.name]

		if not layout then
			print("Layout not found: " .. getOptParams.name)
			return
		end

		if (getOptParams.filter) then
			if not layout:SetRoleFilter(getOptParams.filter) then
				print("Invalid filter settings")
			end
        end
    else
        print("/mhf layout should be followed by the options:")
        GetOpt.print(LayoutOptions)
	end
end

local SpellOptions = {
		{"list", "l", nil, "list current spell settings" },
		{"button", "b", ":", "mouse button (left, right, middle, four, five, up, down)"},
		{"modifier", "m", ":", "modifier to apply (alt, shift, ctrl)"},
		{"spell", "s", ":", "spellname" },
		{"empty", "e", nil, "empty out a mouse button configuration"},
		{"target", "t", nil, "target" },
		{"custom", "c", ":", "custom" },
		{"name", "n", ":", "name of the spell set to apply action to (defaults to active spell set for current soul spec)" },
		{"reset", "r", nil, "resets all mouse bindings" },
		{"mere", nil, nil, "Setup Mere's test spells"},
		}
local buttonNameToInternalName = {
	left = "LeftClick",
	right = "RightClick",
	middle = "MiddleClick",
	four = "Mouse4Click",
	five = "Mouse5Click",
	up = "WheelForward",
	down = "WheelBack"
	}

function MereHealingFrames.Commands.Spells(params)
	table.remove(params,1)

	local getOptParams = GetOpt.getopt(SpellOptions, params);
	if (getOptParams == nil) then
        print("/mhf spell should be followed by the options:")
        GetOpt.print(SpellOptions)
        return
    end

	if (getOptParams.list) then
		print("Listing current spell set")
        MereHealingFrames.Spells.printSpellSet(MereHealingFrames.CurrentSpellSet)
		return
	elseif (getOptParams.button) then
		local spellSetName = getOptParams.name
		local internalButton = buttonNameToInternalName[getOptParams.button]
		if not internalButton then
			print("Invalid button name, please use one of: left, right, middle, four, five, up or down")
			return
		end

		if getOptParams.empty then
			if not MereHealingFrames.Spells.ClearSpell(spellSetName, internalButton, getOptParams.modifier or "none") then
				print("Failed to clear button")
				return
			end
			MereHealingFrames.Spells.UpdateCurrentSpells()
			print("Mouse button cleared")
			return
		end

		if not getOptParams.spell and not getOptParams.target and not getOptParams.custom then
			print("must select a spell, target or custom macro")
		end

		if not MereHealingFrames.Spells.UpdateSpell(spellSetName, internalButton,
													getOptParams.modifier or "none",
													getOptParams.spell,
													getOptParams.target,
													getOptParams.custom)
													then
			print("Failed to update button")
			return
		end
		MereHealingFrames.Spells.UpdateCurrentSpells()

		print("Configured button")
	elseif (getOptParams.mere) then
		MereHealingFrames.Spells.CreateMagicMere()
		MereHealingFrames.Spells.UpdateCurrentSpells()
	elseif (getOptParams.reset) then
		if not MereHealingFrames.Spells.ResetSpells(getOptParams.name) then
			print("Failed to reset spell set")
			return
		end
		MereHealingFrames.Spells.UpdateCurrentSpells()
		print("Spell set reset, and reloaded")
    else
        print("/mhf spell should be followed by the options:")
        GetOpt.print(SpellOptions)
	end
end

local ColourOptions = {
		{"alpha", "a", "#", "alpha (optional, scale 0.0-1.0, defaults to 1.0 if not specified)"},
		{"red", "r", "#", "red (scale 0.0-1.0)" },
		{"green", "g", "#", "green (scale 0.0-1.0)" },
		{"blue", "b", "#", "blue (scale 0.0-1.0)" },
		{"name", "n", ":", "name of colour to adjust" },
		{"list", "l", nil, "list current colours" },
		{"default", "d", nil, "list default colours" },
		{"clear", "c", nil, "clear named colour" },
		{"reset", nil, nil, "Reset all non-default colours" },
		--{"set", "s", ":", "name of set to act on" },
		}
function MereHealingFrames.Commands.Colours(params)
	table.remove(params,1)

	local getOptParams = GetOpt.getopt(ColourOptions, params);

    if(getOptParams == nil) then
        print("/mhf colours should be followed by the options:")
        GetOpt.print(ColourOptions)
        return
    end

	if (getOptParams.list) then
		print ("Non default colours\nName: red, green, blue, alpha")
		for colour, colourvalues in pairs(MereHealingFrames.CurrentColours) do
			print (string.format("%s: %f, %f, %f, %f", colour, colourvalues.r, colourvalues.g, colourvalues.b, colourvalues.a))
		end
	elseif (getOptParams.default) then
		print ("Default colours\nName: red, green, blue, alpha")
		for colour, colourvalues in pairs(MereHealingFrames.DefaultColours) do
            print (string.format("%s: %f, %f, %f, %f", colour, colourvalues.r, colourvalues.g, colourvalues.b, colourvalues.a))
		end
	elseif (getOptParams.reset) then
		print ("All non-default colour choices have been reset, a /reloadui may be needed for colour change to take effect")
		MereHealingFrames.Colours.ResetAll()
	elseif (getOptParams.name) then
		if (getOptParams.clear) then
			 MereHealingFrames.Colours.Clear(getOptParams.name)
		elseif not (getOptParams.red and getOptParams.green and getOptParams.blue) then
			print ("All 3 colour values must be specified")
			return
		else
			if MereHealingFrames.Colours.Update(getOptParams.name, getOptParams.red, getOptParams.green, getOptParams.blue, getOptParams.alpha) then
				print ("Updated colour :" .. getOptParams.name)
				print ("Currently a /reloadui will be needed for colour change to take full effect")
			else
				print ("Unable to find colour called: " .. getOptParams.name)
			end
        end
    else
        print("/mhf colours should be followed by the options:")
        GetOpt.print(ColourOptions)
	end
end

local DebugOptions = {
		{"level", "l", "#", "debug level"},
		{"eventcounters", "e", nil, "list eventcounters" },
		{"stratas", "s", nil, "list stratas for first layout found" },
		{"panelwalk", "p", nil, "walk the panels and list them out" },
		{"strays", nil, nil, "check for strays" },
		{"fiveman", "f", nil, "add some fake players to layouts" },
		{"tenman", "t", nil, "add some fake players to layouts" },
		{"twentyman", "w", nil, "add some fake players to layouts" },
		{"nofakes", "n", nil, "remove fake players from layouts" },
		}
function MereHealingFrames.Commands.Debug(params)
	table.remove(params,1)

	local getOptParams = GetOpt.getopt(DebugOptions, params);

	if getOptParams == nil then
        print("/mhf debug should be followed by the options:")
        GetOpt.print(DebugOptions)
        return
    end

	if (getOptParams.eventcounters) then
		for key, value in pairs(MereHealingFrames.EventCounters) do
			print(key .. ":\t" .. value)
		end
	elseif (getOptParams.level) then
		local oldDebugLevel = MereHealingFrames.DebugLevel
        MereHealingFrames.ChangeDebugLevel(getOptParams.level)
		print(string.format("Changed debug level from %d to %d", oldDebugLevel, getOptParams.level))
	elseif (getOptParams.stratas) then
		for k, v in pairs (MereHealingFrames.context:GetStrataList()) do
			print (k .. ":\t" .. v)
		end
	elseif (getOptParams.panelwalk) then
		MereHealingFrames.PanelWalk()
	elseif (getOptParams.strays) then
		MereHealingFrames.RaidManagement.CheckForStrays()
	elseif (getOptParams.fiveman) then
		MereHealingFrames.RaidManagement.AddFakes(5, false, 1, 1, 1, 2)
	elseif (getOptParams.tenman) then
		MereHealingFrames.RaidManagement.AddFakes(10, false, 2, 3, 1, 4)
	elseif (getOptParams.twentyman) then
		MereHealingFrames.RaidManagement.AddFakes(20, false, 3, 6, 2, 9)
	elseif (getOptParams.nofakes) then
		MereHealingFrames.RaidManagement.RemoveFakes()
    else
        print("/mhf debug should be followed by the options:")
        GetOpt.print(DebugOptions)
	end
end

function MereHealingFrames.PanelWalk()
		for unitId, panels in ipairs(MereHealingFrames.UnitIdPanels) do
			print("Panels for unit ID: " .. unitId)
			for key, panel in pairs(panels) do
				print("Panel: " .. panel.unitId)
			end
		end
end