
local lib = Nurfed_UnitFrames:New();
local utility = Nurfed_Utility:New();

NURFED_SAVED_UNITFRAMES = {};
local saved = nil;
local player = nil;
local version = "01.14.2006";
--local currtime = 0;
local checks = {};
local sliders = {};
local swatches = {};
local cycles = {};
local inputs = {};

function ComboPointsFrame_OnEvent()
end

function Nurfed_UnitFrames_OnLoad()
	this:RegisterEvent("PLAYER_LOGIN");
	this:RegisterEvent("PLAYER_ENTERING_WORLD");
	this:RegisterEvent("PLAYER_CONTROL_LOST");
	this:RegisterEvent("CVAR_UPDATE");
end

function Nurfed_UnitFrames_OnEvent(event)
	if (event == "PLAYER_LOGIN") then
		this:UnregisterEvent(event);
		player = UnitName("player").." - "..GetRealmName();

		if (not NURFED_SAVED_UNITFRAMES[player]) then
			NURFED_SAVED_UNITFRAMES[player] = utility:TableCopy(lib.Default);
		else
			Nurfed_UpdateUnitSaved();
		end
		Nurfed_UnitFrames_Init();
		return;
	end

	if (event == "PLAYER_ENTERING_WORLD") then
		lib:UpdateAll();
		return;
	end

	if (event == "PLAYER_CONTROL_LOST") then
		if (saved.preservetarget == 1) then
			TargetLastTarget();
		end
		return;
	end

	if (event == "CVAR_UPDATE" and (arg1 == "gxColorBits" or arg1 == "gxDepthBits" or arg1 == "gxRefresh" or arg1 == "gxResolution")) then
		lib:ScaleAll();
	end
end

function Nurfed_UpdateUnitSaved()
	for k, v in lib.Default do
		if (not NURFED_SAVED_UNITFRAMES[player][k]) then
			NURFED_SAVED_UNITFRAMES[player][k] = v;
		elseif (type(v) ~= type(NURFED_SAVED_UNITFRAMES[player][k])) then
			NURFED_SAVED_UNITFRAMES[player][k] = nil;
			NURFED_SAVED_UNITFRAMES[player][k] = v;
		end
	end
end

function Nurfed_ToT_OnUpdate(arg1)
	this.update = this.update + arg1;
	if (this.update > 0.5) then
		lib:UpdateToTInfo("targettarget");
		lib:UpdateToTInfo("targettargettarget");
		this.update = 0;
	end
end

function Nurfed_ToP_OnUpdate(arg1)
	this.update = this.update + arg1;
	if (this.update > 0.5) then
		lib:UpdateToTInfo("pettarget");
		this.update = 0;
	end
end

function Nurfed_UnitFramesOptions_Reset()
	NURFED_SAVED_UNITFRAMES[player] = nil;
	NURFED_SAVED_UNITFRAMES[player] = utility:TableCopy(lib.Default);
	Nurfed_UnitFrames_Init();
end

function Nurfed_UnitFrames_Init()
	saved = NURFED_SAVED_UNITFRAMES[player];
	lib:InitAll();
end

function Nurfed_HPBar_OnUpdate(arg1)
	this.update = this.update + arg1;
	if (this.update > 0.04) then
		this.update = 0;
		local now = GetTime();
		local frame, texture, p;
		if (now - this.flashtime > 0.3) then
			this.flashdct = this.flashdct * (-1);
			this.flashtime = now;
		end

		if (this.flashdct == 1) then
			p = (1 - (now - this.flashtime + 0.001) / 0.3 * 0.7);
		else
			p = ( (now - this.flashtime + 0.001) / 0.3 * 0.7 + 0.3);
		end
		this:SetAlpha(p);
	end
end

function Nurfed_SetAuraTooltip()
	if (not this:IsVisible()) then return; end
	GameTooltip:SetOwner(this, "ANCHOR_BOTTOMRIGHT");
	local unit = this:GetParent().unit;
	if (this.isdebuff == 1) then
		if (unit == "party") then
			GameTooltip:SetUnitDebuff("party"..this:GetParent():GetID(), this:GetID());
		else
			GameTooltip:SetUnitDebuff(unit, this:GetID());
		end
	else
		GameTooltip:SetUnitBuff(unit, this:GetID());
	end
end

function Nurfed_Player_OnEvent(event)
	if (event == "PLAYER_UPDATE_RESTING") then
		lib:Status("player");
		return;
	end

	if (event == "PLAYER_ENTER_COMBAT" or event == "PLAYER_REGEN_DISABLED") then
		this.inCombat = true;
		lib:Status("player");
		return;
	end

	if (event == "PLAYER_LEAVE_COMBAT" or event == "PLAYER_REGEN_ENABLED") then
		this.inCombat = nil;
		lib:Status("player");
		return;
	end

	if (event == "PARTY_LEADER_CHANGED") then
		lib:Leader();
		return;
	end

	if (event == "PARTY_LOOT_METHOD_CHANGED") then
		lib:Loot();
		return;
	end

	if (event == "PARTY_MEMBERS_CHANGED" or event == "RAID_ROSTER_UPDATE") then
		lib:UpdateGroupNum();
		return;
	end

	if (arg1 == "player") then
		if (event == "UNIT_PVP_UPDATE") then
			lib:PvP("player");
			return;
		end

		if (event == "UNIT_HEALTH" or event == "UNIT_MAXHEALTH") then
			lib:UpdateHealth("player");
			return;
		end

		if (event == "UNIT_MANA" or event == "UNIT_ENERGY" or event == "UNIT_RAGE" or event == "UNIT_MAXMANA" or event == "UNIT_MAXENERGY" or event == "UNIT_MAXRAGE") then
			lib:UpdateMana("player");
			return;
		end

		if (event == "UNIT_DISPLAYPOWER") then
			lib:UpdateManaColor("player");
			return;
		end

		if (event == "UNIT_LEVEL") then
			lib:UpdateLevel("player");
			return;
		end
	end
end

function Nurfed_player_Update()
	lib:Status("player");
	lib:PvP("player");
	lib:Rank("player");
	lib:UpdateHealth("player");
	lib:UpdateMana("player");
	lib:UpdateManaColor("player");
	lib:UpdateLevel("player");
	lib:UpdateGroupNum();
	lib:Leader();
	lib:Loot();
end

function Nurfed_Target_OnEvent(event)
	if (event == "PLAYER_TARGET_CHANGED") then
		Nurfed_target_Update();
		return;
	end

	if (event == "PLAYER_COMBO_POINTS") then
		lib:UpdateCombo();
		return;
	end

	if (arg1 == "target") then
		if (event == "UNIT_PVP_UPDATE") then
			lib:PvP("target");
			return;
		end

		if (event == "UNIT_HEALTH" or event =="UNIT_MAXHEALTH") then
			lib:UpdateHealth("target");
			return;
		end

		if (event == "UNIT_MANA" or event == "UNIT_ENERGY" or event == "UNIT_RAGE" or event == "UNIT_FOCUS" or event == "UNIT_MAXMANA" or event == "UNIT_MAXENERGY" or event == "UNIT_MAXRAGE" or event == "UNIT_MAXFOCUS") then
			lib:UpdateMana("target");
			return;
		end

		if (event == "UNIT_DISPLAYPOWER") then
			lib:UpdateManaColor("target");
			return;
		end

		if (event == "UNIT_CLASSIFICATION_CHANGED") then
			lib:UpdateTargetLevel();
			return;
		end

		if (event == "UNIT_AURA") then
			lib:UpdateAuras("target");
			return;
		end

		if (event == "UNIT_DYNAMIC_FLAGS") then
			lib:UpdateName("target");
		end
	end
end

function Nurfed_target_Update()
	if (UnitExists("target")) then
		lib:PvP("target");
		lib:Rank("target");
		lib:UpdateHealth("target");
		lib:UpdateMana("target");
		lib:UpdateManaColor("target");
		lib:UpdateName("target");
		lib:UpdateAuras("target");
		lib:UpdateTargetLevel();
		lib:UpdateTargetAuras();
		lib:UpdateCombo();
		this:Show();
	else
		this:Hide();
	end
end

function Nurfed_Party_OnEvent(event)
	if (event == "PARTY_MEMBERS_CHANGED") then
		Nurfed_party_UpdateMember();
		lib:UpdatePartyBackground();
		return;
	end

	if (event == "PARTY_LEADER_CHANGED") then
		lib:Leader();
		return;
	end

	if (event == "PARTY_LOOT_METHOD_CHANGED") then
		lib:Loot();
		return;
	end

	if (event == "PLAYER_TARGET_CHANGED") then
		lib:UpdatePartyBG(this.unit);
		return;
	end

	if (arg1 == this.unit) then
		if (event == "UNIT_NAME_UPDATE") then
			lib:UpdateName(arg1);
			return;
		end

		if (event == "UNIT_HEALTH" or event == "UNIT_MAXHEALTH") then
			lib:UpdateHealth(arg1);
			return;
		end

		if (event == "UNIT_MANA" or event == "UNIT_ENERGY" or event == "UNIT_RAGE" or event == "UNIT_MAXMANA" or event == "UNIT_MAXENERGY" or event == "UNIT_MAXRAGE") then
			lib:UpdateMana(arg1);
			return;
		end

		if (event == "UNIT_DISPLAYPOWER") then
			lib:UpdateManaColor(arg1);
			return;
		end

		if (event == "UNIT_AURA") then
			lib:UpdateAuras(arg1);
			return;
		end

		if (event == "UNIT_PET") then
			lib:UpdatePartyPet();
			return;
		end
	end
end

function Nurfed_party_UpdateMember(id)
	if (not id) then
		id = this:GetID();
	else
		this = getglobal("Nurfed_party"..id);
	end
	if (UnitExists("party"..id)) then
		lib:UpdateHealth("party"..id);
		lib:UpdateMana("party"..id);
		lib:UpdateManaColor("party"..id);
		lib:UpdateName("party"..id);
		lib:UpdateAuras("party"..id);
		lib:UpdatePartyPet();
		lib:Loot();
		this:Show();
	else
		this:Hide();
	end
end

function Nurfed_Test()
	local i, button;
	for i = 1, 16 do
		button = getglobal("Nurfed_party1Buff"..i);
		icon = getglobal(button:GetName().."Icon");
		icon:SetTexture("Interface\\Icons\\Spell_Holy_HolyProtection");
		button:Show();

		button = getglobal("Nurfed_party1DeBuff"..i);
		if (button) then
			icon = getglobal(button:GetName().."Icon");
			icon:SetTexture("Interface\\Icons\\Spell_Shadow_FingerOfDeath");
			button:Show();
		end
	end
end

function Nurfed_Pet_OnEvent(event)
	if (event == "UNIT_PET" and arg1 == "player") then
		Nurfed_pet_Update();
		return;
	end

	if (event == "PET_ATTACK_START") then
		this.inCombat = true;
		lib:Status("pet");
		return;
	end

	if (event == "PET_ATTACK_STOP") then
		this.inCombat = nil;
		lib:Status("pet");
		return;
	end

	if (arg1 == "pet") then
		if (event == "UNIT_NAME_UPDATE" or event == "UNIT_LEVEL") then
			lib:UpdateName("pet");
			return;
		end

		if (event == "UNIT_HEALTH" or event == "UNIT_MAXHEALTH") then
			lib:UpdateHealth("pet");
			return;
		end

		if (event == "UNIT_MANA" or event == "UNIT_ENERGY" or event == "UNIT_RAGE" or event == "UNIT_FOCUS" or event == "UNIT_MAXMANA" or event == "UNIT_MAXENERGY" or event == "UNIT_MAXRAGE" or event == "UNIT_MAXFOCUS") then
			lib:UpdateMana("pet");
			return;
		end

		if (event == "UNIT_DISPLAYPOWER") then
			lib:UpdateManaColor("pet");
			return;
		end

		if (event == "UNIT_AURA") then
			lib:UpdateAuras("pet");
			return;
		end

		if (event == "UNIT_HAPPINESS") then
			lib:UpdateHappiness();
			return;
		end
	end
end

function Nurfed_pet_Update()
	if (UnitExists("pet")) then
		lib:UpdateName("pet");
		lib:UpdateHealth("pet");
		lib:UpdateMana("pet");
		lib:UpdateManaColor("pet");
		lib:UpdateAuras("pet");
		lib:Status("pet");
		lib:UpdateHappiness();
		this:Show();
	else
		this:Hide();
	end
end

function Nurfed_Unit_OnDragStart(frame)
	if (NURFED_LOCKALL ~= 1 and frame:IsMovable()) then
		CloseDropDownMenus();
		frame.BeingDragged = 1;
		frame:StartMoving();
	end
end

function Nurfed_Unit_OnDragStop(frame)
	if (frame:IsMovable()) then
		frame:StopMovingOrSizing();
		frame.BeingDragged = nil;
		utility:ValidatePosition(frame);
	end
end

function Nurfed_Unit_OnClick(button)
	local name, dropdown;
	if (SpellIsTargeting() and arg1 == "RightButton") then
		SpellStopTargeting();
		return;
	end
	if ( arg1 == "LeftButton" ) then
		if (SpellIsTargeting() and  SpellCanTargetUnit(this.unit)) then
			SpellTargetUnit(this.unit);
		elseif (CursorHasItem()) then
			if (this.unit == "player") then
				AutoEquipCursorItem();
			else
				DropItemOnUnit(this.unit);
			end
		else
			TargetUnit(this.unit);
		end
	else
		if (string.find(this.unit, "party[1-4]")) then
			name = "PartyMemberFrame"..this:GetID();
			dropdown = getglobal(name.."DropDown");
		else
			name = string.gsub(this.unit, "^%l", string.upper);
			dropdown = getglobal(name.."FrameDropDown");
		end
		if (dropdown) then
			ToggleDropDownMenu(1, nil, dropdown, "Nurfed_"..this.unit, 106, 27);
		end
		return;
	end
end

function Nurfed_UnitFramesOptions_OnShow()
	this:SetHeight(200);
	this:SetWidth(400);
	this.tabbed = 1;
	if (not this.selectedTab) then
		this.selectedTab = 1;
	end
	Nurfed_UnitFramesOptionsFrame:SetHeight(170);
	Nurfed_UnitFramesOptionsFrame:SetWidth(392);
	Nurfed_UnitFramesOptionsFrameHeadline:SetWidth(380);
	Nurfed_UnitFramesOptionsFrameHeadline:SetText("Nurfed UnitFrames - "..version);
	PanelTemplates_SetNumTabs(this, 5);
	PanelTemplates_SetTab(this, this.selectedTab);

	Nurfed_UnitFramesOptionsVars:SetBackdropColor(0, 0, 0, 0.75);
	Nurfed_UnitFramesOptionsVars:SetBackdropBorderColor(1, 1, 1, 1);
	Nurfed_UnitFramesOptionsVars:Show();
end

function Nurfed_UnitFramesOptionsInit()
	checks = {
		[1] = { name = NURFEDUNITPRESERVE, option = "preservetarget", page = 1 },
		[2] = { name = NURFEDUNITBLIZZPLAYER, option = "blizzplayer", func = function() lib:UnitInit("blizzplayer") end, page = 2 },
		[3] = { name = NURFEDUNITPLAYER, option = "player", func = function() lib:UnitInit("player") end, page = 2 },
		[4] = { name = NURFEDUNITBLIZZTARGET, option = "blizztarget", func = function() lib:UnitInit("blizztarget") end, page = 3 },
		[5] = { name = NURFEDUNITTARGET, option = "target", func = function() lib:UnitInit("target") end, page = 3 },
		[6] = { name = NURFEDUNITBLIZZPET, option = "blizzpet", func = function() lib:UnitInit("blizzpet") end, page = 4 },
		[7] = { name = NURFEDUNITPET, option = "pet", func = function() lib:UnitInit("pet") end, page = 4 },
		[8] = { name = NURFEDUNITBLIZZPARTY, option = "blizzparty", func = function() lib:PartyInit("blizzparty") end, page = 5 },
		[9] = { name = NURFEDUNITPARTY, option = "party", func = function() lib:PartyInit("party") end, page = 5 },

		[10] = { name = NURFEDUNITPLAYERHPTEXT, option = "playerhptext", func = function() lib:StatusText("player") end, page = 2 },
		[11] = { name = NURFEDUNITPLAYERMPTEXT, option = "playermptext", func = function() lib:StatusText("player") end, page = 2 },
		[12] = { name = NURFEDUNITTARGETHPTEXT, option = "targethptext", func = function() lib:StatusText("target") end, page = 3 },
		[13] = { name = NURFEDUNITTARGETMPTEXT, option = "targetmptext", func = function() lib:StatusText("target") end, page = 3 },
		[14] = { name = NURFEDUNITPETHPTEXT, option = "pethptext", func = function() lib:StatusText("pet") end, page = 4 },
		[15] = { name = NURFEDUNITPETMPTEXT, option = "petmptext", func = function() lib:StatusText("pet") end, page = 4 },
		[16] = { name = NURFEDUNITPARTYHPTEXT, option = "partyhptext", func = function() lib:StatusText("party") end, page = 5 },
		[17] = { name = NURFEDUNITPARTYMPTEXT, option = "partymptext", func = function() lib:StatusText("party") end, page = 5 },
		[18] = { name = NURFEDUNITTEXTOUTLINE, option = "outlinetext", func = function() lib:InitText() end, page = 1 },

		[19] = { name = NURFEDUNITTARGETTARGET, option = "targettarget", page = 3 },
		[20] = { name = NURFEDUNITTARGETTARGETTARGET, option = "targettargettarget", page = 3 },
		[21] = { name = NURFEDUNITTARGETCLASS, option = "targetclass", func = function() lib:UpdateName("target") end, align="right", page = 3 },

		[22] = { name = NURFEDUNITPLAYERHPMISSING, option = "playerhpmissing", func = function() lib:InitText() end, page = 2 },
		[23] = { name = NURFEDUNITTARGETHPMISSING, option = "targethpmissing", func = function() lib:InitText() end, align="right", page = 3 },
		[24] = { name = NURFEDUNITPETHPMISSING, option = "pethpmissing", func = function() lib:InitText() end, page = 4 },
		[25] = { name = NURFEDUNITPARTYHPMISSING, option = "partyhpmissing", func = function() lib:InitText() end, page = 5 },
		[26] = { name = NURFEDUNITPLAYERMODELCOLOR, option = "playermodelrecolor", func = function() lib:Status("player") end, page = 2 },
		[27] = { name = NURFEDUNITPARTYLINKED, option = "partylink", func = function() lib:LinkParty() end, page = 5 },
	};

	sliders = {
		[1] = { name = NURFEDUNITHEALTHFLASH, option = "healthflash", min = 0, max = 100, step = 1, page = 1 },
		[2] = { name = NURFEDUNITPLAYERSCALE, option = "playerscale", min = 0.5, max = 2.5, step = 0.01, func = function() lib:ScaleFrame("player") end, page = 2 },
		[3] = { name = NURFEDUNITTARGETSCALE, option = "targetscale", min = 0.5, max = 2.5, step = 0.01, func = function() lib:ScaleFrame("target") end, page = 3 },
		[4] = { name = NURFEDUNITPETSCALE, option = "petscale", min = 0.5, max = 2.5, step = 0.01, func = function() lib:ScaleFrame("pet") end, page = 4 },
		[5] = { name = NURFEDUNITPARTYSCALE, option = "partyscale", min = 0.5, max = 2.5, step = 0.01, func = function() lib:ScaleFrame("party") end, page = 5 },
		[6] = { name = NURFEDUNITTEXTSIZE, option = "textsize", min = 5, max = 12, step = 1, func = function() lib:InitText() end, page = 1 },
	};

	swatches = {
		[1] = { name = NURFEDUNITPLAYERBG, option = "playerbg", func = function() lib:Background("player") end, page = 2 },
		[2] = { name = NURFEDUNITPLAYERBORDER, option = "playerborder", func = function() lib:Background("player") end, page = 2 },
		[3] = { name = NURFEDUNITTARGETBG, option = "targetbg", func = function() lib:Background("target") end, page = 3 },
		[4] = { name = NURFEDUNITTARGETBORDER, option = "targetborder", func = function() lib:Background("target") end, page = 3 },
		[5] = { name = NURFEDUNITPETBG, option = "petbg", func = function() lib:Background("pet") end, page = 4 },
		[6] = { name = NURFEDUNITPETBORDER, option = "petborder", func = function() lib:Background("pet") end, page = 4 },
		[7] = { name = NURFEDUNITPARTYBG, option = "partybg", func = function() lib:Background("party") end, page = 5 },
		[8] = { name = NURFEDUNITPARTYBORDER, option = "partyborder", func = function() lib:Background("party") end, page = 5 },
	};

	cycles = {
		[1] = { name = NURFEDUNITBARTEXTURE, option = "bartexture", func = function() lib:UpdateBarTexture() end, min = 1, max = 6, page = 1 },
		[2] = { name = NURFEDUNITBORDER, option = "border", func = function() lib:UpdateBorder() end, min = 1, max = 3, page = 1 },
		[3] = { name = NURFEDUNITHPTEXTALIGN, option = "hptextalign", func = function() lib:InitText() end, min = 1, max = 3, page = 1 },
		[4] = { name = NURFEDUNITMPTEXTALIGN, option = "mptextalign", func = function() lib:InitText() end, min = 1, max = 3, page = 1 },
		[5] = { name = NURFEDUNITPLAYERMODEL, option = "playermodel", func = function() lib:UpdatePlayerModel() end, min = 1, max = 3, page = 2 },
	};

	inputs = {
		[1] = {name = NURFEDUNITPARTYNAMEFORMAT, option = "partyname", func = function() lib:UpdatePartyNames() end, page = 5 },
		[2] = {name = NURFEDUNITSTATUSBARFORMAT, option = "textformat", func = function() lib:UpdateTextFormat() end, page = 1 },
	};
end

function Nurfed_UnitFramesOptionsFrameCheckOnShow()
	local id = this:GetID();
	local text = getglobal(this:GetName().."Text");
	local value = saved[checks[id].option];
	local align = checks[id].align;
	if (align == "right") then
		text:ClearAllPoints();
		text:SetPoint("RIGHT", this:GetName(), "LEFT", 0, 0);
	end
	text:SetText(checks[id].name);
	if (value == 1) then
		text:SetTextColor(0,1,0);
	else
		text:SetTextColor(1,0,0);
	end
	this:SetChecked(value);
end

function Nurfed_UnitFramesOptionsFrameCheckOnClick()
	local id = this:GetID();
	local text = getglobal(this:GetName().."Text");
	local func = checks[id].func;
	local value;
	if (this:GetChecked() == 1) then
		text:SetTextColor(0,1,0);
		value = 1;
	else
		text:SetTextColor(1,0,0);
		value = 0;
	end
	saved[checks[id].option] = value;
	if (func) then
		func();
	end
end

function Nurfed_UnitFramesOptionsFrameSliderOnShow()
	local id = this:GetID();
	local text = getglobal(this:GetName().."Text");
	local minLabel = getglobal(this:GetName().."Low");
	local maxLabel = getglobal(this:GetName().."High");
	text:SetTextColor(0,1,0);
	text:SetText(sliders[id].name);
	minLabel:SetText(sliders[id].min);
	maxLabel:SetText(sliders[id].max);
	this:SetMinMaxValues(sliders[id].min, sliders[id].max);
	this:SetValueStep(sliders[id].step);
	this:SetValue(saved[sliders[id].option]);
end

function Nurfed_UnitFramesOptionsFrameSliderOnValueChanged()
	local id = this:GetID();
	local text = getglobal(this:GetName().."Value");
	local value = this:GetValue();
	if (strfind(value, ".")) then
		value = format("%.2f", value);
	end
	local func = sliders[id].func;
	text:SetText("("..value..")");
	text:ClearAllPoints();
	if (this:GetValue() < ((sliders[id].max - sliders[id].min) / 4) + sliders[id].min) then
		text:SetPoint("LEFT", this:GetName().."Thumb", "RIGHT", -6, 0);
	else
		text:SetPoint("RIGHT", this:GetName().."Thumb", "LEFT", 6, 0);
	end
	if (this.tip ~=1) then return; end
	local option = sliders[id].option;
	saved[option] = this:GetValue();
	if (func) then
		func();
	end
end

function Nurfed_UnitSetColor(frame)
	local id = frame:GetID();
	local option = swatches[id].option;
	local func = swatches[id].func;
	local r,g,b = ColorPickerFrame:GetColorRGB();
	local a = OpacitySliderFrame:GetValue();
	local swatch = getglobal(frame:GetName().."NormalTexture");
	swatch:SetVertexColor(r,g,b);
	frame.r = r;
	frame.g = g;
	frame.b = b;
	saved[option].r  = r;
	saved[option].g  = g;
	saved[option].b  = b;
	saved[option].a  = a;
	func();
end

function Nurfed_UnitCancelColor(frame, prev)
	local id = frame:GetID();
	local option = swatches[id].option;
	local func = swatches[id].func;
	local r = prev.r;
	local g = prev.g;
	local b = prev.b;
	local a = prev.a;
	local swatch = getglobal(frame:GetName().."NormalTexture");
	swatch:SetVertexColor(r, g, b);
	frame.r = r;
	frame.g = g;
	frame.b = b;
	saved[option].r  = r;
	saved[option].g  = g;
	saved[option].b  = b;
	saved[option].a  = a;
	func();
end

function Nurfed_UnitFramesOptionsFrameSwatchOnShow()
	local id = this:GetID();
	local frame = this;
	local swatch = getglobal(this:GetName().."NormalTexture");
	local option = swatches[id].option;
	local info = {};
	info = saved[option];

	this.r = info.r;
	this.g = info.g;
	this.b = info.b;
	this.swatchFunc = function() Nurfed_UnitSetColor(frame) end;
	this.cancelFunc = function(x) Nurfed_UnitCancelColor(frame, x) end;
	this.hasOpacity = 1;
	this.opacityFunc = function() Nurfed_UnitSetColor(frame) end;
	this.opacity = info.a;
	swatch:SetVertexColor(info.r, info.g, info.b);
	getglobal(this:GetName().."Text"):SetText(swatches[id].name);
end

function Nurfed_UnitFramesOptionsFrameCycleOnShow()
	local id = this:GetID();
	local text = getglobal(this:GetName().."Text");
	local option = cycles[id].option;
	local optiontext = cycles[id]["text"..saved[option]];
	if (optiontext) then
		text:SetText(optiontext);
	else
		text:SetText(cycles[id].name.." "..saved[option]);
	end
end

function Nurfed_UnitFramesOptionsFrameCyclePrevOnClick()
	local id = this:GetParent():GetID();
	local text = getglobal(this:GetParent():GetName().."Text");
	local option = cycles[id].option;
	local func = cycles[id].func;
	if (saved[option] == cycles[id].min) then
		saved[option] = cycles[id].max;
	else
		saved[option] = saved[option] - 1;
	end
	local optiontext = cycles[id]["text"..saved[option]];
	if (optiontext) then
		text:SetText(optiontext);
	else
		text:SetText(cycles[id].name.." "..saved[option]);
	end
	if (func) then
		func();
	end
end

function Nurfed_UnitFramesOptionsFrameCycleNextOnClick()
	local id = this:GetParent():GetID();
	local text = getglobal(this:GetParent():GetName().."Text");
	local option = cycles[id].option;
	local func = cycles[id].func;
	if (saved[option] == cycles[id].max) then
		saved[option] = cycles[id].min;
	else
		saved[option] = saved[option] + 1;
	end
	local optiontext = cycles[id]["text"..saved[option]];
	if (optiontext) then
		text:SetText(optiontext);
	else
		text:SetText(cycles[id].name.." "..saved[option]);
	end
	if (func) then
		func();
	end
end

function Nurfed_UnitFramesOptionsFrameInputOnShow()
	local id = this:GetID();
	local text = getglobal(this:GetName().."Text");
	local inputtext = getglobal(this:GetName().."Input");
	local option = inputs[id].option;
	text:SetText(inputs[id].name);
	inputtext:SetText(saved[option]);
end

function Nurfed_UnitFramesOptionsFrameSetInput()
	local id = this:GetParent():GetID();
	local inputtext = getglobal(this:GetParent():GetName().."Input");
	local text = inputtext:GetText();
	local option = inputs[id].option;
	local func = inputs[id].func;
	inputtext:ClearFocus();
	saved[option] = text;
	if (func) then
		func();
	end
end

function Nurfed_UnitFramesOptions_TabOnClick()
	local id = this:GetID();
	local frame = "Nurfed_UnitFramesOptionsFrame";
	if (not id or id < 1) then
		id = this.selectedTab;
	end
	local check, slider, swatch, cycle, input;
	for k, v in checks do
		check = getglobal(frame.."Check"..k);
		if (v.page == id) then
			check:Show();
		else
			check:Hide();
		end
	end

	for k, v in sliders do
		slider = getglobal(frame.."Slider"..k);
		if (v.page == id) then
			slider:Show();
		else
			slider:Hide();
		end
	end

	for k, v in swatches do
		swatch = getglobal(frame.."Swatch"..k);
		if (v.page == id) then
			swatch:Show();
		else
			swatch:Hide();
		end
	end

	for k, v in cycles do
		cycle = getglobal(frame.."Cycle"..k);
		if (v.page == id) then
			cycle:Show();
		else
			cycle:Hide();
		end
	end

	for k, v in inputs do
		input = getglobal(frame.."Input"..k);
		if (v.page == id) then
			input:Show();
		else
			input:Hide();
		end
	end
end

function Nurfed_UnitFrames_Config()
	if (Nurfed_UnitFramesOptions:IsVisible()) then
		HideUIPanel(Nurfed_UnitFramesOptions);
	else
		ShowUIPanel(Nurfed_UnitFramesOptions);
	end
end
