------------------------------------------------
--                CT_BuffMod                  --
--                                            --
-- Mod that allows you to heavily customize   --
-- the display of buffs to your liking.       --
-- Please do not modify or otherwise          --
-- redistribute this without the consent of   --
-- the CTMod Team. Thank you.                 --
------------------------------------------------

local _G = getfenv(0);
local module = _G.CT_BuffMod;
local buffObjectList = module.buffList;
local buffModFrame = module.buffFrame;

-- Options frame
local function updateSortType(frame, sortType)
	sortType = sortType or module:getOption("sortType");
	
	local windowOptions = frame.windowOptions;
	local sortOptions = frame.sortOptions;

	local keepRecastPosition = sortOptions.keepRecastPosition;
	if ( sortType == 1 ) then
		-- Type
		sortOptions.subSortTypeFont:Show();
		sortOptions.subSortType:Show();
		
		local subSortType = module:getOption("subSortType");
		if ( subSortType == 2 ) then
			keepRecastPosition:Show();
--			keepRecastPosition:SetPoint("TOPLEFT", 60, -315);
		else
			keepRecastPosition:Hide();
		end
		
	elseif ( sortType == 3 ) then
		-- Order
		sortOptions.subSortTypeFont:Hide();
		sortOptions.subSortType:Hide();
		keepRecastPosition:Show();
--		keepRecastPosition:SetPoint("TOPLEFT", 60, -295);
	else
		sortOptions.subSortTypeFont:Hide();
		sortOptions.subSortType:Hide();
		keepRecastPosition:Hide();
	end
end

local function updateSortTypeSequence()
	local buffTypes = {"AURA", "BUFF", "DEBUFF", "ITEM"};  -- Same sequence as in dropdown menu
	local buffType;
	local seqUsed = {};

	if (not module.sortTypeSequence) then
		module.sortTypeSequence = {};
	end

	module.sortTypeSequence[1] = (module.sortSeq1 or 1); -- Default first to AURA (item 1 in drop down menu)
	module.sortTypeSequence[2] = (module.sortSeq2 or 2); -- Default second to BUFF (item 2 in drop down menu)
	module.sortTypeSequence[3] = (module.sortSeq3 or 4); -- Default third to ITEM (item 4 in drop down menu)
	module.sortTypeSequence[4] = (module.sortSeq4 or 3); -- Default fourth to DEBUFF (item 3 in drop down menu)

	for k, v in ipairs(buffTypes) do
		module.buffSortTypes[v] = nil;
	end
	for k, v in ipairs(module.sortTypeSequence) do
		seqUsed[k] = false;
		buffType = buffTypes[v];
		if (buffType) then
			-- First item with this buffType gets the sequence number
			if (not module.buffSortTypes[buffType]) then
				module.buffSortTypes[buffType] = k;
				seqUsed[k] = true;
			end
		end
	end
	-- Check for items with the same sequence number
	for k, v in ipairs(buffTypes) do
		if (not module.buffSortTypes[v]) then
			-- Assign an unused sequence number
			local seq = 1;
			for k2, v2 in ipairs(seqUsed) do
				if (not v2) then
					seq = k2;
					break;
				end
			end
			module.buffSortTypes[v] = seq;
			seqUsed[seq] = true;
		end
	end
end

module.frame = function()
	local updateFunc = function(self, value)
		local timeLeft = floor( ( value or self:GetValue() )*10+0.5)/10;

		if ( timeLeft == 0 ) then
			self.title:SetText("Off");
		else
			self.title:SetText(module.humanizeTime(timeLeft));
		end
		local option = self.option;
		if ( option ) then
			self.object:setOption(option, value);
		end
	end;
	local buffExpirationSlider = {
		["onvaluechanged"] = updateFunc,
		["onload"] = updateFunc
	};

	local options = {};
	local yoffset = 5;

	-- Window Options
	options["frame#tl:0:-".. yoffset .."#r#i:windowOptions"] = {
		"font#tl:0:0#v:GameFontNormalLarge#Window Options",
		"checkbutton#tl:10:-20#o:showTitle:true#Show Title",
		"checkbutton#tl:10:-40#o:unlockWindow:true#Unlock Window",
		"font#tl:0:-57#r#s:0:40#(When unlocked, click to drag the frame. Use the lower right corner to resize the window)#0.5:0.5:0.5",
		"font#tl:10:-92#v:ChatFontNormal#Background Color:",
		"colorswatch#tl:120:-92#o:backgroundColor:0,0,0,0.25#s:16:16#true",
		"font#tl:10:-112#v:ChatFontNormal#Aura Color:",
		"colorswatch#tl:120:-112#o:bgColorAURA:0.35,0.8,0.15,0.5#s:16:16#true",
		"font#tl:10:-132#v:ChatFontNormal#Buff Color:",
		"colorswatch#tl:120:-132#o:bgColorBUFF:0.1,0.4,0.85,0.5#s:16:16#true",
		"font#tl:10:-152#v:ChatFontNormal#Debuff Color:",
		"colorswatch#tl:120:-152#o:bgColorDEBUFF:1,0,0,0.85#s:16:16#true",
		"font#tl:10:-172#v:ChatFontNormal#Item Buff Color:",
		"colorswatch#tl:120:-172#o:bgColorITEM:0.75,0.25,1,0.75#s:16:16#true",
		"checkbutton#tl:10:-190#o:expandBuffs:true#Auto Expand Window",
		"checkbutton#tl:10:-210#o:showBorder#Show Window Border",
		"checkbutton#tl:10:-230#o:expandUpwards#Expand Buffs Upwards",
		"checkbutton#tl:10:-250#o:rightAlign#Display Icons on Right Side",
	};
	yoffset = yoffset + 290;
		
	-- Sort Options
	options["frame#tl:0:-".. yoffset .."#r#i:sortOptions"] = {
		"font#tl:0:0#v:GameFontNormalLarge#Sort Options",
		"font#tl:10:-20#v:ChatFontNormal#Sort by:",
		"dropdown#tl:50:-22#o:sortType:1#s:100:50#n:CTBuffModDropdown#Type#Time#Order#Name",
		"font#hidden#i:subSortTypeFont#tl:30:-50#v:ChatFontNormal#Sub-Sort by:",
		"dropdown#hidden#i:subSortType#tl:100:-52#o:subSortType:1#s:100:50#n:CTBuffModDropdown2#Time#Order#Name",
		"checkbutton#hidden#i:keepRecastPosition#tl:25:-70#o:keepRecastPosition#Keep Recast Buff Position",
		"font#tl:10:-100#v:ChatFontNormal#Use this sequence when sorting by Type:",
		"font#tl:30:-120#v:ChatFontNormal#First:",
		"dropdown#tl:70:-122#o:sortSeq1:1#s:100:50#n:CTBuffModSeq1Dropdown#Auras#Buffs#Debuffs#Items",
		"font#tl:30:-145#v:ChatFontNormal#Second:",
		"dropdown#tl:70:-147#o:sortSeq2:2#s:100:50#n:CTBuffModSeq2Dropdown#Auras#Buffs#Debuffs#Items",
		"font#tl:30:-170#v:ChatFontNormal#Third:",
		"dropdown#tl:70:-172#o:sortSeq3:4#s:100:50#n:CTBuffModSeq3Dropdown#Auras#Buffs#Debuffs#Items",
		"font#tl:30:-195#v:ChatFontNormal#Fourth:",
		"dropdown#tl:70:-197#o:sortSeq4:3#s:100:50#n:CTBuffModSeq4Dropdown#Auras#Buffs#Debuffs#Items",
		"checkbutton#tl:10:-220#o:sortReverse#Reverse the direction of the sort",
	};
	yoffset = yoffset + 260;
		
	-- Buff Options
	options["frame#tl:0:-".. yoffset .. "#r#i:buffOptions"] = {
		"font#tl:0:0#v:GameFontNormalLarge#Buff Options",
		"slider#t:0:-35#s:170:17#o:buffSize:20#Buff Size - <value>#15:45:1",
		"slider#t:0:-70#s:170:17#o:buffSpacing:0#Buff Spacing - <value>#0:30:1",
		"checkbutton#tl:10:-95#o:showNames:true#Show Buff Names",
		"checkbutton#tl:10:-115#o:showTimers:true#Show Buff Duration",
		"font#tl:50:-140#v:ChatFontNormal#Format:",
		"dropdown#tl:95:-142#o:durationFormat#s:145:50#n:CTBuffModDropdown3#"
			.. "1 hour / 35 minutes#1 hour / 35 min#1h / 35m#1h 35m / 35m 15s#1:35h / 35:15",
		"font#tl:50:-165#v:ChatFontNormal#Location:",
		"dropdown#tl:95:-167#o:durationLocation#s:145:50#n:CTBuffModDropdown4#Side#Below",
		"checkbutton#tl:10:-190#o:colorCodeDebuffs#Color Code Debuff Names",
		"checkbutton#tl:10:-210#o:showItemBuffs:true#Show Item Buffs",
		"checkbutton#tl:10:-230#o:colorBuffs:true#Color Buffs",
		"checkbutton#tl:60:-250#o:showBuffTimer:true#Show Buff Timers",
		"checkbutton#tl:110:-270#o:showTimerBackground:true#Show Timer Background",
	};
	yoffset = yoffset + 310;

	-- Buff Expiration
	options["frame#tl:0:-".. yoffset .. "#r#i:buffExpiration"] = {
		"font#tl:0:0#v:GameFontNormalLarge#Buff Expiration",
		"checkbutton#tl:10:-20#o:flashIcons:true#Flash Icons on Buff Fade",
		"checkbutton#tl:10:-40#o:enableExpiration:true#Enable Buff Expiration Warning",
		"checkbutton#tl:60:-60#o:expirationCastOnly#Only for buffs you can cast",
		"checkbutton#tl:60:-80#o:expirationSound:true#Play Expiration Sound",
	};
	yoffset = yoffset + 115;

	-- Buff Expiration Timers
	options["frame#tl:0:-".. yoffset .. "#r#i:buffExpirationTimers"] = {
		"font#tl:0:0#v:GameFontNormalLarge#Buff Expiration Timers",
		"font#t:-85:-20#v:ChatFontNormal#Buff Duration",
		"font#t:75:-20#v:ChatFontNormal#Expiration Warning Time",
		"font#t:-85:-50#2:00  -  10:00",
		"font#t:-85:-90#10:01  -  30:00",
		"font#t:-85:-130#30:01  - >",
		["slider#t:75:-50#o:expirationTime1:15#:Off:1 min.#0:60:5"] = buffExpirationSlider,
		["slider#t:75:-90#o:expirationTime2:60#:15 sec.:3 min.#15:180:5"] = buffExpirationSlider,
		["slider#t:75:-130#o:expirationTime3:180#:15 sec.:5 min.#15:300:5"] = buffExpirationSlider,
	};
	yoffset = yoffset + 165;

	options["frame#tl:0:-".. yoffset .."#r"] = {
		"font#tl:0:0#v:GameFontNormalLarge#Reset Options",
		"checkbutton#tl:20:-20#o:resetAll#Reset options for all of your characters",
		["button#t:0:-50#s:120:30#v:UIPanelButtonTemplate#Reset options"] = {
			["onclick"] = function(self)
				if (module:getOption("resetAll")) then
					CT_BuffModOptions = {};
				else
					if (not CT_BuffModOptions or not type(CT_BuffModOptions) == "table") then
						CT_BuffModOptions = {};
					else
						CT_BuffModOptions[module:getCharKey()] = nil;
					end
				end
				ConsoleExec("RELOADUI");
			end,
		},
		"font#t:0:-80#s:0:40#l#r#Note: Resetting options to default will reload your UI.#0.5:0.5:0.5",
	};
		
	options["onload"] = updateSortType;

	return "frame#all", options;
end

local options = {
	showTitle = function(self, value)
		if ( value ~= false ) then
			buffModFrame.title:Show();
		else
			buffModFrame.title:Hide();
		end
	end,
	
	unlockWindow = function(self, value)
		value = value ~= false;
		buffModFrame:EnableMouse(value);
		
		if ( value ) then
			buffModFrame.resize:Show();
		else
			buffModFrame.resize:Hide();
		end
	end,
	
	expandBuffs = function(self, value)
		module:expandBuffs(value ~= false);
	end,
	
	showBorder = function(self, value)
		buffModFrame:SetBackdropBorderColor(1, 1, 1, ( value and 1 ) or 0);
	end,
	
	expandUpwards = function(self, value)
		module.expandUpwards = value;
		buffObjectList:position();
	end,
	
	rightAlign = function(self, value)
		module.rightAlign = value;
		buffObjectList:display();
	end,
	
	showNames = function(self, value)
		module.showNames = value ~= false;
		buffObjectList:display();
	end,
	
	colorBuffs = function(self, value)
		module.colorBuffs = value ~= false;
		buffObjectList:display();
	end,
	
	showBuffTimer = function(self, value)
		module:showBuffTimers(value ~= false);
	end,
	
	buffSize = function(self, value)
		module:setBuffSize(value);
	end,
	
	showTimers = function(self, value)
		module.showTimers = value ~= false;
		buffObjectList:display();
	end,
	
	showTimerBackground = function(self, value)
		module.showTimerBackground = value ~= false;
		buffObjectList:display();
	end,
	
	showItemBuffs = function(self, value)
		module:showItemBuffs(value ~= false);
	end,
	
	flashIcons = function(self, value)
		module.flashIcons = value ~= false;
		buffObjectList:checkExpiration();
	end,
	
	enableExpiration = function(self, value)
		module.enableExpiration = value ~= false;
		buffObjectList:checkExpiration();
	end,
	
	expirationSound = function(self, value)
		module.expirationSound = value ~= false;
	end,
	
	expirationCastOnly = function(self, value)
		module.expirationCastOnly = value;
	end,
	
	sortType = function(self, value)
		module:setSortType(value or 1);
		
		local frame = module.frame;
		if ( type(frame) ~= "function" ) then
			updateSortType(frame, value or 1);
		end
	end,
	
	subSortType = function(self, value)
		module:setSubSortType(value or 1);
		local frame = module.frame;
		if ( type(frame) ~= "function" ) then
			updateSortType(frame);
		end
	end,
	
	keepRecastPosition = function(self, value)
		module.keepRecastPosition = value;
	end,

	sortReverse = function(self, value)
		module:setSortReverse(value);
	end,

	sortSeq1 = function(self, value)
		module.sortSeq1 = value;
		updateSortTypeSequence();
		module:setSortType();
	end,
	
	sortSeq2 = function(self, value)
		module.sortSeq2 = value;
		updateSortTypeSequence();
		module:setSortType();
	end,

	sortSeq3 = function(self, value)
		module.sortSeq3 = value;
		updateSortTypeSequence();
		module:setSortType();
	end,

	sortSeq4 = function(self, value)
		module.sortSeq4 = value;
		updateSortTypeSequence();
		module:setSortType();
	end,

	expirationTime1 = function(self, value)
		module:setExpiration(1, value or 15);
	end,
	
	expirationTime2 = function(self, value)
		module:setExpiration(2, value or 60);
	end,
	
	expirationTime3 = function(self, value)
		module:setExpiration(3, value or 180);
	end,
	
	durationFormat = function(self, value)
		module:setTimeFormat(value or 1);
	end,
	
	durationLocation = function(self, value)
		module.durationBelow = value == 2;
		buffObjectList:display();
	end,
	
	backgroundColor = function(self, value)
		if ( value ) then
			buffModFrame:SetBackdropColor(unpack(value));
		else
			buffModFrame:SetBackdropColor(0, 0, 0, 0.25);
		end
	end,
	
	colorCodeDebuffs = function(self, value)
		module.colorCodeDebuffs = value;
		buffObjectList:display();
	end,
	
	buffSpacing = function(self, value)
		module:setSpacing(value or 0);
		buffObjectList:position();
	end,
	
	bgColorAURA = function(self, value)
		module:updateBackgroundColor("AURA", value);
		buffObjectList:display();
	end,
	
	bgColorBUFF = function(self, value)
		module:updateBackgroundColor("BUFF", value);
		buffObjectList:display();
	end,

	bgColorDEBUFF = function(self, value)
		module:updateBackgroundColor("DEBUFF", value);
		buffObjectList:display();
	end,
	
	bgColorITEM = function(self, value)
		module:updateBackgroundColor("ITEM", value);
		buffObjectList:display();
	end
};

module.update = function(self, type, value)
	self:mainupdate(type, value);
	if ( type == "init" ) then
		for key, val in pairs(options) do
			val(self, self:getOption(key));
		end
	else
		local f = options[type];
		if ( f ) then
			f(self, value);
		end
	end
end