local registry = LibStub('AceConfigRegistry-3.0')
local optionsTitle = " |cff00ccff" .. WhatsNextLocal:Localize("TITLE") .. "|r"
local icon
WhatsNext.optionsClass = select(2,UnitClass("player"))

local function GetFontList()
	return AceGUIWidgetLSMlists.font
end

function DeepCopy(object)
    local lookup_table = {}
    local function _copy(object)
        if type(object) ~= "table" then
            return object
        elseif lookup_table[object] then
            return lookup_table[object]
        end
        local new_table = {}
        lookup_table[object] = new_table
        for index, value in pairs(object) do
            new_table[_copy(index)] = _copy(value)
        end
        return new_table
    end
    return _copy(object)
end

local function GetDefaults()	
	return {
		global = {
			minimap = {
				hide = false,
			},
			placeHolders = {
			},
			spellMemory = {
			},
		},
		profile = {	
			enabled = true,
			locked = false,
			timeBetweenUpdates = .4,
			hideOutOfCombat = false,
			pos = {
				p1 = "TOPLEFT",
				p2 = "CENTER",
				x = 0,
				y = 0,
			},
			configPos = {
				p1 = "CENTER",
				p2 = "CENTER",
				x = 0,
				y = 0,
			},
			font = "Yellow Jacket",
			outline = 'OUTLINE',
			scale = 1,
			subsequentScale = .8,
			stackDirection = "bottom",
			showAbilityName = true,
			showIcon = true,
			showCDText = false,
			showBlockIndex = false,
			textColor = {r=1,b=0,g=0.8196079,a=1},
			backgroundColor = {r=.6,b=0,g=0,a=.5},
			borderFullCDColor = {r=1,b=1,g=1,a=1},
			borderNoCDColor = {r=0,b=0,g=0,a=1},
			maxSuggestions = 3,
			switchFrame = {
				locked = false,
				scale = 1,
				font = "Yellow Jacket",
				outline = 'OUTLINE',
				iconOn = "Interface\\Icons\\INV_Misc_QuestionMark",
				iconOff = "Interface\\Icons\\INV_MISC_NOTE_05",
				textColorOn = {r=1,b=0,g=0.8196079,a=1},
				textColorOff = {r=.7,b=.7,g=.7,a=1},
				bgColorOn = {r=0,b=0,g=0,a=1},
				bgColorOff = {r=.3,b=.3,g=.3,a=1},
				borderColorOn = {r=0,b=0,g=0,a=1},
				borderColorOff = {r=0,b=0,g=0,a=1},
				pos = {p1="TOPLEFT",p2="CENTER",x=-300,y=0},
			}
		}
	}
end

local function SetValue(info,value) 
	WhatsNext.db.profile[info.arg] = value
	if info.arg == "showIcon" and not value then
		WhatsNext.db.profile["showAbilityName"] = true 
		WhatsNext.db.profile["showCDText"] = false 
		WhatsNext.db.profile["showBlockIndex"] = false 
	elseif info.arg == "showAbilityName" and not value then
		WhatsNext.db.profile["showIcon"] = true 
	elseif info.arg == "showBlockIndex" and value then
		WhatsNext.db.profile["showIcon"] = true 
	elseif info.arg == "showCDText" and value then
		WhatsNext.db.profile["showIcon"] = true 
	end
	WhatsNext:ApplyDisplaySettings()
end

local function GetValue(info) 
	return WhatsNext.db.profile[info.arg] 
end

local function SetSwitchValue(info,value) 
	WhatsNext.db.profile.switchFrame[info.arg] = value
	WhatsNext:ApplyDisplaySettings()
end

local function GetSwitchValue(info) 
	return WhatsNext.db.profile.switchFrame[info.arg] 
end

local function GetColorValue(info)
	local color = WhatsNext.db.profile[info.arg]
	return color.r, color.g, color.b, color.a
end

local function SetColorValue(info, r, g, b, a)
	WhatsNext.db.profile[info.arg] = {["r"] = r, ["g"] = g, ["b"] = b, ["a"] = a}
	WhatsNext:ApplyDisplaySettings()
end

local function GetSwitchColorValue(info)
	local color = WhatsNext.db.profile.switchFrame[info.arg]
	return color.r, color.g, color.b, color.a
end

local function SetSwitchColorValue(info, r, g, b, a)
	WhatsNext.db.profile.switchFrame[info.arg] = {["r"] = r, ["g"] = g, ["b"] = b, ["a"] = a}
	WhatsNext:ApplyDisplaySettings()
end
	
local optionsTop = {name = "",type = 'group',desc = "",args = {}}

local optionsGeneral = {
	name = "|cff00ccff" .. WhatsNextLocal:Localize("TITLE") .. "|r " .. WhatsNextLocal:Localize("BY"),
	type = 'group',
	desc = "",
	set = 	SetValue,
	get = 	GetValue,
	handler = WhatsNext,
	args = {
		["ENABLE"] = {
			name = "Enabled",
			type = 'toggle',
			width  = 'full',
			order = 50,
			arg = "enabled",
		},
		["LOCK"] = {
			name = "Locked",
			type = 'toggle',
			width  = 'full',
			order = 150,
			arg = "locked",
		},
		["SHOW_MINIMAP_BUTTON"] = {
			name = "Show Minimap Button",
			type = 'toggle',
			order = 175,
			set = function(info,val) 
				WhatsNext.db.global.minimap.hide = not val
				if val then
					icon:Show("Whats Next?")
				else
					icon:Hide("Whats Next?")
				end
			
			end,
			get = function(info) return not WhatsNext.db.global.minimap.hide end,
			arg = "",
		},
		["HIDEOUTOFCOMBAT"] = {
			name = "Hide Out Of Combat",
			type = 'toggle',
			width  = 'full',
			order = 200,
			arg = "hideOutOfCombat",
		},
		["TIME_BETWEEN_UPDATES"] = {
			name = "Seconds Between Updates",
			type = 'range',
			min = .01, max = 1, step = .01,
			order = 250,
			arg = "timeBetweenUpdates"
		},
	}
}

local function OpenCastLogicDisplay(info)
	InterfaceOptionsFrame:Hide()
	WhatsNext_CastLogicDisplay:SetCastLogicSet(WhatsNext.optionsClass,WhatsNext.optionsSpec)

end

local function GetClassList()
	local classList = {}
	classList["DEATHKNIGHT"] = WhatsNextLocal:Localize("DEATHKNIGHT")
	classList["DRUID"] = WhatsNextLocal:Localize("DRUID")
	classList["HUNTER"] = WhatsNextLocal:Localize("HUNTER")
	classList["MAGE"] = WhatsNextLocal:Localize("MAGE")
	classList["MONK"] = WhatsNextLocal:Localize("MONK")
	classList["PALADIN"] = WhatsNextLocal:Localize("PALADIN")
	classList["PRIEST"] = WhatsNextLocal:Localize("PRIEST")
	classList["ROGUE"] = WhatsNextLocal:Localize("ROGUE")
	classList["SHAMAN"] = WhatsNextLocal:Localize("SHAMAN")
	classList["WARLOCK"] = WhatsNextLocal:Localize("WARLOCK")
	classList["WARRIOR"] = WhatsNextLocal:Localize("WARRIOR")
	return classList
end

local function GetSpecList()
	local specList = {}
	specList[1] = WhatsNextLocal:Localize(WhatsNext.optionsClass..1)
	specList[2] = WhatsNextLocal:Localize(WhatsNext.optionsClass..2)
	specList[3] = WhatsNextLocal:Localize(WhatsNext.optionsClass..3)
	if WhatsNext.optionsClass == "DRUID" then
		specList[4] = WhatsNextLocal:Localize(WhatsNext.optionsClass..4)
	end
	return specList
end

local function SetClass(info,value)
	WhatsNext.optionsClass = value
	WhatsNext.optionsSpec = WhatsNext.optionsClass == "DRUID" and WhatsNext.optionsSpec or math.min(WhatsNext.optionsSpec,3)
end

local function GetAppearanceOptions()
	return {
		name = "|cff00ccff" .. WhatsNextLocal:Localize("TITLE") .. "|r " .. WhatsNextLocal:Localize("BY"),
		type = 'group',
		desc = "",
		set = 	SetValue,
		get = 	GetValue,
		handler = WhatsNext,
		args = {
		
			["BREAK1"] = {
				name = "\n ",
				type = 'description',
				order = 10,
			},
			["SUGGESTION_FRAME"] = {
				name = "Suggestion Frame",
				type = 'group',
				order = 100,
				guiInline = true,
				args = {
			
					["maxSuggestions"] = {
						name = "Max. Suggestion Count",
						type = 'range',
						min =  1, max = 6, step = 1,
						order = 120,
						arg = "maxSuggestions"
					},
					["GrowthDirection"] = {
						name = "Suggestion Stack Direction",
						type = 'select',
						values = {["bottom"] = "Bottom",["top"] = "Top",["left"]="Left",["right"]="Right"},
						order = 130,
						arg = 'stackDirection',
					},
					["BREAK3"] = {
						name = "\n ",
						type = 'description',
						order = 140,
					},
					["SHOW_ICON"] = {
						name = "Show Icons",
						type = 'toggle',
						order = 150,
						arg = "showIcon",
					},
					["SHOW_ABILITY_NAME"] = {
						name = "Show Suggestion Text",
						type = 'toggle',
						order = 250,
						arg = "showAbilityName",
					},
					["BREAK4"] = {
						name = "\n ",
						type = 'description',
						order = 252,
					},
					["SHOW_COOLDOWN_TEXT"] = {
						name = "Show Cooldown Text",
						type = 'toggle',
						order = 255,
						arg = "showCDText",
					},
					["SHOW_BLOCK_INDEX"] = {
						name = "Show Suggestion Index",
						type = 'toggle',
						order = 257,
						arg = "showBlockIndex",
					},
					["BREAK5"] = {
						name = "",
						type = 'description',
						order = 260,
					},
					["SCALE"] = {
						name = "Top Frame Scale",
						type = 'range',
						min = .05, max = 3, step = .05,
						order = 275,
						arg = "scale"
					},
					["SUBSEQUENTSCALE"] = {
						name = "Subsequent Frame Scale",
						type = 'range',
						min = .4, max = 1.5, step = .01,
						order = 279,
						arg = "subsequentScale"
					},
					["BREAK6"] = {
						name = "",
						type = 'description',
						order = 300,
					},
					["FONT"] = {
						name = "Font",
						type = 'select',
						dialogControl = 'LSM30_Font',
						values = GetFontList,
						order = 310,
						arg = 'font',
					},
					["Outline"] = {
						name = "Outline",
						type = 'select',
						desc = "Set font outline.",
						values = {[''] = NONE, OUTLINE = VOICE_CHAT_NORMAL, THICKOUTLINE = "Thick"},
						order = 325,
						arg = 'outline',
					},
					["BREAK8"] = {
						name = "",
						type = 'description',
						order = 340,
					},
					["FColor"] = {
						name = "Text Color",
						type = 'color',
						hasAlpha = true,
						set = SetColorValue,
						get = GetColorValue,
						order = 350,
						arg = 'textColor',
					},
					["BGCOLOR"] = {
						name = "Background Color",
						type = 'color',
						hasAlpha = true,
						set = SetColorValue,
						get = GetColorValue,
						order = 450,
						arg = "backgroundColor",
					},
					["BREAK10"] = {
						name = "",
						type = 'description',
						order = 500,
					},
					["BORDERCDCOLOR"] = {
						name = "Border Full CD Color",
						type = 'color',
						hasAlpha = true,
						set = SetColorValue,
						get = GetColorValue,
						order = 550,
						arg = "borderFullCDColor",
					},
					["BORDERNOCDCOLOR"] = {
						name = "Border Off CD Color",
						type = 'color',
						hasAlpha = true,
						set = SetColorValue,
						get = GetColorValue,
						order = 650,
						arg = "borderNoCDColor",
					},
				},
			},
			["SWITCH_FRAME"] = {
				name = "User Switch Buttons",
				type = 'group',
				order = 200,
				set = 	SetSwitchValue,
				get = 	GetSwitchValue,
				guiInline = true,
				args = {
			
					["Locked"] = {
						name = "Locked",
						type = 'toggle',
						order = 150,
						arg = "locked",
					},
					["SCALE"] = {
						name = "Scale",
						type = 'range',
						min = .05, max = 3, step = .05,
						order = 275,
						arg = "scale"
					},
					["BREAK6"] = {
						name = "",
						type = 'description',
						order = 300,
					},
					["FONT"] = {
						name = "Font",
						type = 'select',
						dialogControl = 'LSM30_Font',
						values = GetFontList,
						order = 310,
						arg = 'font',
					},
					["Outline"] = {
						name = "Outline",
						type = 'select',
						desc = "Set font outline.",
						values = {[''] = NONE, OUTLINE = VOICE_CHAT_NORMAL, THICKOUTLINE = "Thick"},
						order = 325,
						arg = 'outline',
					},
					["BREAK8"] = {
						name = "",
						type = 'description',
						order = 340,
					},
					["FColorOn"] = {
						name = "Text Color On",
						type = 'color',
						hasAlpha = true,
						set = SetSwitchColorValue,
						get = GetSwitchColorValue,
						order = 350,
						arg = 'textColorOn',
					},
					["FColorOff"] = {
						name = "Text Color Off",
						type = 'color',
						hasAlpha = true,
						set = SetSwitchColorValue,
						get = GetSwitchColorValue,
						order = 360,
						arg = 'textColorOff',
					},
					["BREAK9"] = {
						name = "",
						type = 'description',
						order = 380,
					},
					["BGCOLORON"] = {
						name = "Background Color On",
						type = 'color',
						hasAlpha = true,
						set = SetSwitchColorValue,
						get = GetSwitchColorValue,
						order = 450,
						arg = "bgColorOn",
					},
					["BGCOLOROff"] = {
						name = "Background Color Off",
						type = 'color',
						hasAlpha = true,
						set = SetSwitchColorValue,
						get = GetSwitchColorValue,
						order = 460,
						arg = "bgColorOff",
					},
					["BREAK10"] = {
						name = "",
						type = 'description',
						order = 500,
					},
					["BORDERCOLORON"] = {
						name = "Border Color On",
						type = 'color',
						hasAlpha = true,
						set = SetSwitchColorValue,
						get = GetSwitchColorValue,
						order = 550,
						arg = "borderColorOn",
					},
					["BORDERCOLOROFF"] = {
						name = "Border Color Off",
						type = 'color',
						hasAlpha = true,
						set = SetSwitchColorValue,
						get = GetSwitchColorValue,
						order = 650,
						arg = "borderColorOff",
					},
				},
			},
		}
	}
end

function WhatsNext:RegisterOptions()
	self:RegisterMedia()
	local dialog = LibStub('AceConfigDialog-3.0')
	
	self.db = LibStub('AceDB-3.0'):New('WhatsNextDB', GetDefaults()	, 'Default')
	self.db.RegisterCallback(self, "OnProfileChanged", "ApplyMainSettings")
	self.db.RegisterCallback(self, "OnProfileCopied", "ApplyMainSettings")
	self.db.RegisterCallback(self, "OnProfileReset", "ApplyMainSettings")
	
	
	local profileOptions = LibStub("AceDBOptions-3.0"):GetOptionsTable(self.db)
	registry:RegisterOptionsTable("WhatsNext", {name = "",type = 'group',desc = "",args = {}})
	local dummy = dialog:AddToBlizOptions("WhatsNext", optionsTitle)
	dummy:SetScript('OnShow', function(self)
		InterfaceOptionsFrame_OpenToCategory(WhatsNext.mainOptions)
	end)
	
	registry:RegisterOptionsTable("WhatsNext-General", optionsGeneral)
	WhatsNext.mainOptions = dialog:AddToBlizOptions("WhatsNext-General", WhatsNextLocal:Localize("GENERAL"), optionsTitle)
	
	registry:RegisterOptionsTable("WhatsNext-Appearance", GetAppearanceOptions())
	WhatsNext.appearanceOptions = dialog:AddToBlizOptions("WhatsNext-Appearance", WhatsNextLocal:Localize("APPEARANCE"), optionsTitle)
	
	registry:RegisterOptionsTable("WhatsNext-CastLogic", {name = "",type = 'group',desc = "",args = {}})
	dummy = dialog:AddToBlizOptions("WhatsNext-CastLogic", WhatsNextLocal:Localize("LOGICSETS"), optionsTitle)
	dummy:SetScript('OnShow', function(self)
		InterfaceOptionsFrame:Hide()
		WhatsNext_LogicSetManagementDisplay:Show()
	end)
	
	registry:RegisterOptionsTable("WhatsNext-Profile", profileOptions)
	dialog:AddToBlizOptions("WhatsNext-Profile", WhatsNextLocal:Localize("PROFILE"), optionsTitle)
	
	local dataobj = LibStub:GetLibrary('LibDataBroker-1.1'):NewDataObject(WhatsNextLocal:Localize("TITLE"), {
		type = 'launcher',
		text = WhatsNextLocal:Localize("TITLE"),
		label = WhatsNextLocal:Localize("TITLE"),
		icon = 'Interface\\Icons\\INV_Misc_QuestionMark',
	})
	
	if dataobj then
		dataobj.OnClick = function(self,button,down) 
			if button == "LeftButton" then
				WhatsNext:ShowOptions()
			else
				WhatsNext.db.profile.locked = not WhatsNext.db.profile.locked
				WhatsNext:ApplyDisplaySettings()
			end
		end
		dataobj.OnTooltipShow = function(tooltip)
			tooltip:AddLine("|cff00ccff" .. WhatsNextLocal:Localize("TITLE") .. "|r " .. WhatsNextLocal:Localize("BY"))
			tooltip:AddLine("     |cffffffff" .. WhatsNextLocal:Localize("TOOLTIP1"))
			tooltip:AddLine("     |cffffffff" .. WhatsNextLocal:Localize("TOOLTIP2"))
		end
		
		icon = LibStub("LibDBIcon-1.0", true)
		icon:Register("Whats Next?", dataobj, self.db.global.minimap)
	end
end

function WhatsNext:ShowOptions()
	if InterfaceOptionsFrame:IsVisible() then
		InterfaceOptionsFrame:Hide()
	else
		InterfaceOptionsFrame_OpenToCategory(WhatsNext.mainOptions) 
	end
end


function WhatsNext:RegisterMedia()
	local media = LibStub("LibSharedMedia-3.0");
	media:Register("font", "ABF",					[[Interface\Addons\WhatsNext\fonts\ABF.ttf]])
	media:Register("font", "Accidental Presidency",	[[Interface\Addons\WhatsNext\fonts\Accidental Presidency.ttf]])
	media:Register("font", "Adventure",				[[Interface\Addons\WhatsNext\fonts\Adventure.ttf]])
	media:Register("font", "AnonymousPro (Bold)",	[[Interface\Addons\WhatsNext\fonts\AnonymousPro-Bold.ttf]])
	media:Register("font", "Avqest",				[[Interface\Addons\WhatsNext\fonts\Avqest.ttf]])
	media:Register("font", "Bazooka",				[[Interface\Addons\WhatsNext\fonts\Bazooka.ttf]])
	media:Register("font", "BigNoodleTitling",		[[Interface\Addons\WhatsNext\fonts\BigNoodleTitling.ttf]])
	media:Register("font", "BigNoodleTitling-Oblique",[[Interface\Addons\WhatsNext\fonts\BigNoodleTitling-Oblique.ttf]])
	media:Register("font", "BlackChancery",			[[Interface\Addons\WhatsNext\fonts\BlackChancery.ttf]])
	media:Register("font", "CRYSRG__",				[[Interface\Addons\WhatsNext\fonts\CRYSRG__.ttf]])
	media:Register("font", "DejaVuSansMono",		[[Interface\Addons\WhatsNext\fonts\DejaVuSansMono.ttf]])
	media:Register("font", "DorisPP",				[[Interface\Addons\WhatsNext\fonts\DORISPP.ttf]])
	media:Register("font", "Emblem",				[[Interface\Addons\WhatsNext\fonts\Emblem.ttf]])
	media:Register("font", "Enigma__2",				[[Interface\Addons\WhatsNext\fonts\Enigma__2.ttf]])
	media:Register("font", "FSEX300",				[[Interface\Addons\WhatsNext\fonts\FSEX300.ttf]])
	media:Register("font", "JAi_____",				[[Interface\Addons\WhatsNext\fonts\JAi_____.ttf]])
	media:Register("font", "LiberationSans Regular",[[Interface\Addons\WhatsNext\fonts\LiberationSans-Regular.ttf]])
	media:Register("font", "MONOFONT",				[[Interface\Addons\WhatsNext\fonts\MONOFONT.ttf]])
	media:Register("font", "Movie Poster (Bold)",	[[Interface\Addons\WhatsNext\fonts\Movie_Poster-Bold.ttf]])
	media:Register("font", "Porky",					[[Interface\Addons\WhatsNext\fonts\Porky.ttf]])
	media:Register("font", "rm_midse",				[[Interface\Addons\WhatsNext\fonts\rm_midse.ttf]])
	media:Register("font", "Tangerin",				[[Interface\Addons\WhatsNext\fonts\Tangerin.ttf]])
	media:Register("font", "Tw_Cen_MT_Bold",		[[Interface\Addons\WhatsNext\fonts\Tw_Cen_MT_Bold.ttf]])
	media:Register("font", "Ultima Campagnoli",		[[Interface\Addons\WhatsNext\fonts\Ultima_Campagnoli.ttf]])
	media:Register("font", "VeraSe",				[[Interface\Addons\WhatsNext\fonts\VeraSe.ttf]])
	media:Register("font", "WHITRABT",				[[Interface\Addons\WhatsNext\fonts\WHITRABT.ttf]])
	media:Register("font", "Yellow Jacket",			[[Interface\Addons\WhatsNext\fonts\Yellowjacket.ttf]])
end