local h,m="\084\097\098\071\114\111\117\112",38 local t=LibStub and LibStub("\065\099\101\071\085\073-\051\046\048",true)if not t or(t:GetWidgetVersion(h)or 0)>=m then return end local a,N,z,s,S=pairs,ipairs,assert,type,table.wipe local g=PlaySound local i,j=CreateFrame,UIParent local D=_G local U={}local E={}local Q={}local function L(h,m,t,a,N,z)local s=h:GetName()local S=h.Middle or h.middleTexture or D[s.."\077\105\100\100\108\101"]local g=h.MiddleDisabled or s and D[s.."\077\105\100\100\108\101\068\105\115\097\098\108\101\100"]local i=h.Left or h.leftTexture or D[s.."\076\101\102\116"]local j=2*i:GetWidth()local U=h.Text or D[h:GetName().."\084\101\120\116"]local E=h.HighlightTexture or s and D[s.."\072\105\103\104\108\105\103\104\116\084\101\120\116\117\114\101"]local Q,L local H if z then H=z else U:SetWidth(0)H=U:GetWidth()end if t then if t<j then Q=1 L=j else Q=t-j L=t end U:SetWidth(Q)else if m then Q=H+m else Q=H+24 end if N and Q>N then if m then Q=N+m else Q=N+24 end U:SetWidth(Q)else U:SetWidth(0)end if a and Q<a then Q=a end L=Q+j end if S then S:SetWidth(Q)end if g then g:SetWidth(Q)end h:SetWidth(L)if E then E:SetWidth(L)end end local function H(h)local m=h:GetName()local t=h.Left or D[m.."\076\101\102\116"]local a=h.Middle or D[m.."\077\105\100\100\108\101"]local N=h.Right or D[m.."\082\105\103\104\116"]t:Show()a:Show()N:Show()h:Enable()local z=h.Text or D[m.."\084\101\120\116"]z:SetPoint("\067\069\078\084\069\082",h,"\067\069\078\084\069\082",h.deselectedTextX or 0,h.deselectedTextY or 2)local s=h.LeftDisabled or D[m.."\076\101\102\116\068\105\115\097\098\108\101\100"]local S=h.MiddleDisabled or D[m.."\077\105\100\100\108\101\068\105\115\097\098\108\101\100"]local g=h.RightDisabled or D[m.."\082\105\103\104\116\068\105\115\097\098\108\101\100"]s:Hide()S:Hide()g:Hide()end local function y(h)local m=h:GetName()local t=h.Left or D[m.."\076\101\102\116"]local a=h.Middle or D[m.."\077\105\100\100\108\101"]local N=h.Right or D[m.."\082\105\103\104\116"]t:Hide()a:Hide()N:Hide()h:Disable()h:SetDisabledFontObject(GameFontHighlightSmall)local z=h.Text or D[m.."\084\101\120\116"]z:SetPoint("\067\069\078\084\069\082",h,"\067\069\078\084\069\082",h.selectedTextX or 0,h.selectedTextY or-3)local s=h.LeftDisabled or D[m.."\076\101\102\116\068\105\115\097\098\108\101\100"]local S=h.MiddleDisabled or D[m.."\077\105\100\100\108\101\068\105\115\097\098\108\101\100"]local g=h.RightDisabled or D[m.."\082\105\103\104\116\068\105\115\097\098\108\101\100"]s:Show()S:Show()g:Show()if GameTooltip:IsOwned(h)then GameTooltip:Hide()end end local function J(h)local m=h:GetName()local t=h.Left or D[m.."\076\101\102\116"]local a=h.Middle or D[m.."\077\105\100\100\108\101"]local N=h.Right or D[m.."\082\105\103\104\116"]t:Show()a:Show()N:Show()h:Disable()h.text=h:GetText()h:SetDisabledFontObject(GameFontDisableSmall)local z=h.LeftDisabled or D[m.."\076\101\102\116\068\105\115\097\098\108\101\100"]local s=h.MiddleDisabled or D[m.."\077\105\100\100\108\101\068\105\115\097\098\108\101\100"]local S=h.RightDisabled or D[m.."\082\105\103\104\116\068\105\115\097\098\108\101\100"]z:Hide()s:Hide()S:Hide()end local function f(h)if h.disabled then J(h)elseif h.selected then y(h)else H(h)end end local function W(h,m)h:_SetText(m)local t=h.obj.frame.width or h.obj.frame:GetWidth()or 0 L(h,0,nil,nil,t,(h:GetFontString()):GetStringWidth())end local function P(h,m)h.selected=m f(h)end local function R(h,m)h.disabled=m f(h)end local function v(h)local m=h.obj m:BuildTabs()h:SetScript("\079\110\085\112\100\097\116\101",nil)end local function q(h)if not(h.selected or h.disabled)then g(841)h.obj:SelectTab(h.value)end end local function T(h)local m=h.obj m:Fire("\079\110\084\097\098\069\110\116\101\114",m.tabs[h.id].value,h)end local function x(h)local m=h.obj m:Fire("\079\110\084\097\098\076\101\097\118\101",m.tabs[h.id].value,h)end local function b(h)D[h:GetName().."\072\105\103\104\108\105\103\104\116\084\101\120\116\117\114\101"]:SetWidth(h:GetTextWidth()+30)end local u={OnAcquire=function(h)h:SetTitle()end;OnRelease=function(h)h.status=nil for m in a(h.localstatus)do h.localstatus[m]=nil end h.tablist=nil for h,m in a(h.tabs)do m:Hide()end end,CreateTab=function(h,m)local t=("\065\099\101\071\085\073\084\097\098\071\114\111\117\112\037\100\084\097\098\037\100"):format(h.num,m)local a=i("\066\117\116\116\111\110",t,h.border)a:SetSize(115,24)a.deselectedTextY=-3 a.selectedTextY=-2 a.LeftDisabled=a:CreateTexture(t.."\076\101\102\116\068\105\115\097\098\108\101\100","\066\079\082\068\069\082")a.LeftDisabled:SetTexture("\073\110\116\101\114\102\097\099\101\092\079\112\116\105\111\110\115\070\114\097\109\101\092\085\073-\079\112\116\105\111\110\115\070\114\097\109\101-\065\099\116\105\118\101\084\097\098")a.LeftDisabled:SetSize(20,24)a.LeftDisabled:SetPoint("\066\079\084\084\079\077\076\069\070\084",0,-3)a.LeftDisabled:SetTexCoord(0,.15625,0,1.0)a.MiddleDisabled=a:CreateTexture(t.."\077\105\100\100\108\101\068\105\115\097\098\108\101\100","\066\079\082\068\069\082")a.MiddleDisabled:SetTexture("\073\110\116\101\114\102\097\099\101\092\079\112\116\105\111\110\115\070\114\097\109\101\092\085\073-\079\112\116\105\111\110\115\070\114\097\109\101-\065\099\116\105\118\101\084\097\098")a.MiddleDisabled:SetSize(88,24)a.MiddleDisabled:SetPoint("\076\069\070\084",a.LeftDisabled,"\082\073\071\072\084")a.MiddleDisabled:SetTexCoord(.15625,.84375,0,1.0)a.RightDisabled=a:CreateTexture(t.."\082\105\103\104\116\068\105\115\097\098\108\101\100","\066\079\082\068\069\082")a.RightDisabled:SetTexture("\073\110\116\101\114\102\097\099\101\092\079\112\116\105\111\110\115\070\114\097\109\101\092\085\073-\079\112\116\105\111\110\115\070\114\097\109\101-\065\099\116\105\118\101\084\097\098")a.RightDisabled:SetSize(20,24)a.RightDisabled:SetPoint("\076\069\070\084",a.MiddleDisabled,"\082\073\071\072\084")a.RightDisabled:SetTexCoord(.84375,1.0,0,1.0)a.Left=a:CreateTexture(t.."\076\101\102\116","\066\079\082\068\069\082")a.Left:SetTexture("\073\110\116\101\114\102\097\099\101\092\079\112\116\105\111\110\115\070\114\097\109\101\092\085\073-\079\112\116\105\111\110\115\070\114\097\109\101-\073\110\065\099\116\105\118\101\084\097\098")a.Left:SetSize(20,24)a.Left:SetPoint("\084\079\080\076\069\070\084")a.Left:SetTexCoord(0,.15625,0,1.0)a.Middle=a:CreateTexture(t.."\077\105\100\100\108\101","\066\079\082\068\069\082")a.Middle:SetTexture("\073\110\116\101\114\102\097\099\101\092\079\112\116\105\111\110\115\070\114\097\109\101\092\085\073-\079\112\116\105\111\110\115\070\114\097\109\101-\073\110\065\099\116\105\118\101\084\097\098")a.Middle:SetSize(88,24)a.Middle:SetPoint("\076\069\070\084",a.Left,"\082\073\071\072\084")a.Middle:SetTexCoord(.15625,.84375,0,1.0)a.Right=a:CreateTexture(t.."\082\105\103\104\116","\066\079\082\068\069\082")a.Right:SetTexture("\073\110\116\101\114\102\097\099\101\092\079\112\116\105\111\110\115\070\114\097\109\101\092\085\073-\079\112\116\105\111\110\115\070\114\097\109\101-\073\110\065\099\116\105\118\101\084\097\098")a.Right:SetSize(20,24)a.Right:SetPoint("\076\069\070\084",a.Middle,"\082\073\071\072\084")a.Right:SetTexCoord(.84375,1.0,0,1.0)a.Text=a:CreateFontString(t.."\084\101\120\116")a:SetFontString(a.Text)a:SetNormalFontObject(GameFontNormalSmall)a:SetHighlightFontObject(GameFontHighlightSmall)a:SetDisabledFontObject(GameFontHighlightSmall)a:SetHighlightTexture("\073\110\116\101\114\102\097\099\101\092\080\097\112\101\114\068\111\108\108\073\110\102\111\070\114\097\109\101\092\085\073-\067\104\097\114\097\099\116\101\114-\084\097\098-\072\105\103\104\108\105\103\104\116","\065\068\068")a.HighlightTexture=a:GetHighlightTexture()a.HighlightTexture:ClearAllPoints()a.HighlightTexture:SetPoint("\076\069\070\084",a,"\076\069\070\084",10,-4)a.HighlightTexture:SetPoint("\082\073\071\072\084",a,"\082\073\071\072\084",-10,-4)D[t.."\072\105\103\104\108\105\103\104\116\084\101\120\116\117\114\101"]=a.HighlightTexture a.obj=h a.id=m a.text=a.Text a.text:ClearAllPoints()a.text:SetPoint("\076\069\070\084",14,-3)a.text:SetPoint("\082\073\071\072\084",-12,-3)a:SetScript("\079\110\067\108\105\099\107",q)a:SetScript("\079\110\069\110\116\101\114",T)a:SetScript("\079\110\076\101\097\118\101",x)a:SetScript("\079\110\083\104\111\119",b)a._SetText=a.SetText a.SetText=W a.SetSelected=P a.SetDisabled=R return a end;SetTitle=function(h,m)h.titletext:SetText(m or"")if m and m~=""then h.alignoffset=25 else h.alignoffset=18 end h:BuildTabs()end;SetStatusTable=function(h,m)z(s(m)=="\116\097\098\108\101")h.status=m end;SelectTab=function(h,m)local t=h.status or h.localstatus local a for h,t in N(h.tabs)do if t.value==m then t:SetSelected(true)a=true else t:SetSelected(false)end end t.selected=m if a then h:Fire("\079\110\071\114\111\117\112\083\101\108\101\099\116\101\100",m)end end;SetTabs=function(h,m)h.tablist=m h:BuildTabs()end,BuildTabs=function(h)local m=h.titletext:GetText()and h.titletext:GetText()~=""local t=h.tablist local a=h.tabs if not t then return end local z=h.frame.width or h.frame:GetWidth()or 0 S(U)S(E)S(Q)for m,t in N(t)do local N=a[m]if not N then N=h:CreateTab(m)a[m]=N end N:Show()N:SetText(t.text)N:SetDisabled(t.disabled)N.value=t.value U[m]=N:GetWidth()-6 end for h=#t+1,#a,1 do a[h]:Hide()end local s=#t local g=1 local i=0 for h=1,#t,1 do if i~=0 and(z-i)-U[h]<0 then E[g]=i+10 Q[g]=h-1 g=g+1 i=0 end i=i+U[h]end E[g]=i+10 Q[g]=#t if g>1 then if Q[g-1]==s-1 then if g==2 and Q[g-1]>2 or Q[g]-Q[g-1]>2 then if E[g]+U[s-1]<=z then Q[g-1]=Q[g-1]-1 E[g]=E[g]+U[s-1]E[g-1]=E[g-1]-U[s-1]end end end end local j=1 for t,N in N(Q)do local s=true for N=j,N,1 do local z=a[N]z:ClearAllPoints()if s then z:SetPoint("\084\079\080\076\069\070\084",h.frame,"\084\079\080\076\069\070\084",0,-(m and 14 or 7)-(t-1)*20)s=false else z:SetPoint("\076\069\070\084",a[N-1],"\082\073\071\072\084",-10,0)end end local S=0 if not(g==1 and E[1]<z*.75-18)then S=(z-E[t])/((N-j)+1)end for h=j,N,1 do L(a[h],S+4,nil,nil,z,(a[h]:GetFontString()):GetStringWidth())end j=N+1 end h.borderoffset=(m and 17 or 10)+g*20 h.border:SetPoint("\084\079\080\076\069\070\084",1,-h.borderoffset)end;OnWidthSet=function(h,m)local t=h.content local a=m-60 if a<0 then a=0 end t:SetWidth(a)t.width=a h:BuildTabs(h)h.frame:SetScript("\079\110\085\112\100\097\116\101",v)end,OnHeightSet=function(h,m)local t=h.content local a=m-(h.borderoffset+23)if a<0 then a=0 end t:SetHeight(a)t.height=a end,LayoutFinished=function(h,m,t)if h.noAutoHeight then return end h:SetHeight((t or 0)+(h.borderoffset+23))end}local d={bgFile="\073\110\116\101\114\102\097\099\101\092\067\104\097\116\070\114\097\109\101\092\067\104\097\116\070\114\097\109\101\066\097\099\107\103\114\111\117\110\100";edgeFile="\073\110\116\101\114\102\097\099\101\092\084\111\111\108\116\105\112\115\092\085\073-\084\111\111\108\116\105\112-\066\111\114\100\101\114";tile=true,tileSize=16,edgeSize=16,insets={left=3,right=3;top=5;bottom=3}}local function G()local m=t:GetNextWidgetNum(h)local N=i("\070\114\097\109\101",nil,j)N:SetHeight(100)N:SetWidth(100)N:SetFrameStrata("\070\085\076\076\083\067\082\069\069\078\095\068\073\065\076\079\071")local z=N:CreateFontString(nil,"\079\086\069\082\076\065\089","\071\097\109\101\070\111\110\116\078\111\114\109\097\108")z:SetPoint("\084\079\080\076\069\070\084",14,0)z:SetPoint("\084\079\080\082\073\071\072\084",-14,0)z:SetJustifyH("\076\069\070\084")z:SetHeight(18)z:SetText("")local s=i("\070\114\097\109\101",nil,N,"\066\097\099\107\100\114\111\112\084\101\109\112\108\097\116\101")s:SetPoint("\084\079\080\076\069\070\084",1,-27)s:SetPoint("\066\079\084\084\079\077\082\073\071\072\084",-1,3)s:SetBackdrop(d)s:SetBackdropColor(.1,.1,.1,.5)s:SetBackdropBorderColor(.4,.4,.4)local S=i("\070\114\097\109\101",nil,s)S:SetPoint("\084\079\080\076\069\070\084",10,-7)S:SetPoint("\066\079\084\084\079\077\082\073\071\072\084",-10,7)local g={num=m,frame=N,localstatus={};alignoffset=18;titletext=z,border=s;borderoffset=27;tabs={},content=S;type=h}for h,m in a(u)do g[h]=m end return t:RegisterAsContainer(g)end t:RegisterWidgetType(h,G,m)
--[[-----------------------------------------------------------------------------
TabGroup Container
Container that uses tabs on top to switch between groups.
-------------------------------------------------------------------------------]]
local Type, Version = "TabGroup", 38
local AceGUI = LibStub and LibStub("AceGUI-3.0", true)
if not AceGUI or (AceGUI:GetWidgetVersion(Type) or 0) >= Version then return end

-- Lua APIs
local pairs, ipairs, assert, type, wipe = pairs, ipairs, assert, type, table.wipe

-- WoW APIs
local PlaySound = PlaySound
local CreateFrame, UIParent = CreateFrame, UIParent
local _G = _G

-- local upvalue storage used by BuildTabs
local widths = {}
local rowwidths = {}
local rowends = {}

--[[-----------------------------------------------------------------------------
Support functions
-------------------------------------------------------------------------------]]

local function PanelTemplates_TabResize(tab, padding, absoluteSize, minWidth, maxWidth, absoluteTextSize)
	local tabName = tab:GetName();

	local buttonMiddle = tab.Middle or tab.middleTexture or _G[tabName.."Middle"];
	local buttonMiddleDisabled = tab.MiddleDisabled or (tabName and _G[tabName.."MiddleDisabled"]);
	local left = tab.Left or tab.leftTexture or _G[tabName.."Left"];
	local sideWidths = 2 * left:GetWidth();
	local tabText = tab.Text or _G[tab:GetName().."Text"];
	local highlightTexture = tab.HighlightTexture or (tabName and _G[tabName.."HighlightTexture"]);

	local width, tabWidth;
	local textWidth;
	if ( absoluteTextSize ) then
		textWidth = absoluteTextSize;
	else
		tabText:SetWidth(0);
		textWidth = tabText:GetWidth();
	end
	-- If there's an absolute size specified then use it
	if ( absoluteSize ) then
		if ( absoluteSize < sideWidths) then
			width = 1;
			tabWidth = sideWidths
		else
			width = absoluteSize - sideWidths;
			tabWidth = absoluteSize
		end
		tabText:SetWidth(width);
	else
		-- Otherwise try to use padding
		if ( padding ) then
			width = textWidth + padding;
		else
			width = textWidth + 24;
		end
		-- If greater than the maxWidth then cap it
		if ( maxWidth and width > maxWidth ) then
			if ( padding ) then
				width = maxWidth + padding;
			else
				width = maxWidth + 24;
			end
			tabText:SetWidth(width);
		else
			tabText:SetWidth(0);
		end
		if (minWidth and width < minWidth) then
			width = minWidth;
		end
		tabWidth = width + sideWidths;
	end

	if ( buttonMiddle ) then
		buttonMiddle:SetWidth(width);
	end
	if ( buttonMiddleDisabled ) then
		buttonMiddleDisabled:SetWidth(width);
	end

	tab:SetWidth(tabWidth);

	if ( highlightTexture ) then
		highlightTexture:SetWidth(tabWidth);
	end
end

local function PanelTemplates_DeselectTab(tab)
	local name = tab:GetName();

	local left = tab.Left or _G[name.."Left"];
	local middle = tab.Middle or _G[name.."Middle"];
	local right = tab.Right or _G[name.."Right"];
	left:Show();
	middle:Show();
	right:Show();
	--tab:UnlockHighlight();
	tab:Enable();
	local text = tab.Text or _G[name.."Text"];
	text:SetPoint("CENTER", tab, "CENTER", (tab.deselectedTextX or 0), (tab.deselectedTextY or 2));

	local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
	local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
	local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
	leftDisabled:Hide();
	middleDisabled:Hide();
	rightDisabled:Hide();
end

local function PanelTemplates_SelectTab(tab)
	local name = tab:GetName();

	local left = tab.Left or _G[name.."Left"];
	local middle = tab.Middle or _G[name.."Middle"];
	local right = tab.Right or _G[name.."Right"];
	left:Hide();
	middle:Hide();
	right:Hide();
	--tab:LockHighlight();
	tab:Disable();
	tab:SetDisabledFontObject(GameFontHighlightSmall);
	local text = tab.Text or _G[name.."Text"];
	text:SetPoint("CENTER", tab, "CENTER", (tab.selectedTextX or 0), (tab.selectedTextY or -3));

	local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
	local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
	local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
	leftDisabled:Show();
	middleDisabled:Show();
	rightDisabled:Show();

	if GameTooltip:IsOwned(tab) then
		GameTooltip:Hide();
	end
end

local function PanelTemplates_SetDisabledTabState(tab)
	local name = tab:GetName();
	local left = tab.Left or _G[name.."Left"];
	local middle = tab.Middle or _G[name.."Middle"];
	local right = tab.Right or _G[name.."Right"];
	left:Show();
	middle:Show();
	right:Show();
	--tab:UnlockHighlight();
	tab:Disable();
	tab.text = tab:GetText();
	-- Gray out text
	tab:SetDisabledFontObject(GameFontDisableSmall);
	local leftDisabled = tab.LeftDisabled or _G[name.."LeftDisabled"];
	local middleDisabled = tab.MiddleDisabled or _G[name.."MiddleDisabled"];
	local rightDisabled = tab.RightDisabled or _G[name.."RightDisabled"];
	leftDisabled:Hide();
	middleDisabled:Hide();
	rightDisabled:Hide();
end

local function UpdateTabLook(frame)
	if frame.disabled then
		PanelTemplates_SetDisabledTabState(frame)
	elseif frame.selected then
		PanelTemplates_SelectTab(frame)
	else
		PanelTemplates_DeselectTab(frame)
	end
end

local function Tab_SetText(frame, text)
	frame:_SetText(text)
	local width = frame.obj.frame.width or frame.obj.frame:GetWidth() or 0
	PanelTemplates_TabResize(frame, 0, nil, nil, width, frame:GetFontString():GetStringWidth())
end

local function Tab_SetSelected(frame, selected)
	frame.selected = selected
	UpdateTabLook(frame)
end

local function Tab_SetDisabled(frame, disabled)
	frame.disabled = disabled
	UpdateTabLook(frame)
end

local function BuildTabsOnUpdate(frame)
	local self = frame.obj
	self:BuildTabs()
	frame:SetScript("OnUpdate", nil)
end

--[[-----------------------------------------------------------------------------
Scripts
-------------------------------------------------------------------------------]]
local function Tab_OnClick(frame)
	if not (frame.selected or frame.disabled) then
		PlaySound(841) -- SOUNDKIT.IG_CHARACTER_INFO_TAB
		frame.obj:SelectTab(frame.value)
	end
end

local function Tab_OnEnter(frame)
	local self = frame.obj
	self:Fire("OnTabEnter", self.tabs[frame.id].value, frame)
end

local function Tab_OnLeave(frame)
	local self = frame.obj
	self:Fire("OnTabLeave", self.tabs[frame.id].value, frame)
end

local function Tab_OnShow(frame)
	_G[frame:GetName().."HighlightTexture"]:SetWidth(frame:GetTextWidth() + 30)
end

--[[-----------------------------------------------------------------------------
Methods
-------------------------------------------------------------------------------]]
local methods = {
	["OnAcquire"] = function(self)
		self:SetTitle()
	end,

	["OnRelease"] = function(self)
		self.status = nil
		for k in pairs(self.localstatus) do
			self.localstatus[k] = nil
		end
		self.tablist = nil
		for _, tab in pairs(self.tabs) do
			tab:Hide()
		end
	end,

	["CreateTab"] = function(self, id)
		local tabname = ("AceGUITabGroup%dTab%d"):format(self.num, id)
		local tab = CreateFrame("Button", tabname, self.border)
		tab:SetSize(115, 24)
		tab.deselectedTextY = -3
		tab.selectedTextY = -2

		tab.LeftDisabled = tab:CreateTexture(tabname .. "LeftDisabled", "BORDER")
		tab.LeftDisabled:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
		tab.LeftDisabled:SetSize(20, 24)
		tab.LeftDisabled:SetPoint("BOTTOMLEFT", 0, -3)
		tab.LeftDisabled:SetTexCoord(0, 0.15625, 0, 1.0)

		tab.MiddleDisabled = tab:CreateTexture(tabname .. "MiddleDisabled", "BORDER")
		tab.MiddleDisabled:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
		tab.MiddleDisabled:SetSize(88, 24)
		tab.MiddleDisabled:SetPoint("LEFT", tab.LeftDisabled, "RIGHT")
		tab.MiddleDisabled:SetTexCoord(0.15625, 0.84375, 0, 1.0)

		tab.RightDisabled = tab:CreateTexture(tabname .. "RightDisabled", "BORDER")
		tab.RightDisabled:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-ActiveTab")
		tab.RightDisabled:SetSize(20, 24)
		tab.RightDisabled:SetPoint("LEFT", tab.MiddleDisabled, "RIGHT")
		tab.RightDisabled:SetTexCoord(0.84375, 1.0, 0, 1.0)

		tab.Left = tab:CreateTexture(tabname .. "Left", "BORDER")
		tab.Left:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
		tab.Left:SetSize(20, 24)
		tab.Left:SetPoint("TOPLEFT")
		tab.Left:SetTexCoord(0, 0.15625, 0, 1.0)

		tab.Middle = tab:CreateTexture(tabname .. "Middle", "BORDER")
		tab.Middle:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
		tab.Middle:SetSize(88, 24)
		tab.Middle:SetPoint("LEFT", tab.Left, "RIGHT")
		tab.Middle:SetTexCoord(0.15625, 0.84375, 0, 1.0)

		tab.Right = tab:CreateTexture(tabname .. "Right", "BORDER")
		tab.Right:SetTexture("Interface\\OptionsFrame\\UI-OptionsFrame-InActiveTab")
		tab.Right:SetSize(20, 24)
		tab.Right:SetPoint("LEFT", tab.Middle, "RIGHT")
		tab.Right:SetTexCoord(0.84375, 1.0, 0, 1.0)

		tab.Text = tab:CreateFontString(tabname .. "Text")
		tab:SetFontString(tab.Text)

		tab:SetNormalFontObject(GameFontNormalSmall)
		tab:SetHighlightFontObject(GameFontHighlightSmall)
		tab:SetDisabledFontObject(GameFontHighlightSmall)
		tab:SetHighlightTexture("Interface\\PaperDollInfoFrame\\UI-Character-Tab-Highlight", "ADD")
		tab.HighlightTexture = tab:GetHighlightTexture()
		tab.HighlightTexture:ClearAllPoints()
		tab.HighlightTexture:SetPoint("LEFT", tab, "LEFT", 10, -4)
		tab.HighlightTexture:SetPoint("RIGHT", tab, "RIGHT", -10, -4)
		_G[tabname .. "HighlightTexture"] = tab.HighlightTexture

		tab.obj = self
		tab.id = id

		tab.text = tab.Text -- compat
		tab.text:ClearAllPoints()
		tab.text:SetPoint("LEFT", 14, -3)
		tab.text:SetPoint("RIGHT", -12, -3)

		tab:SetScript("OnClick", Tab_OnClick)
		tab:SetScript("OnEnter", Tab_OnEnter)
		tab:SetScript("OnLeave", Tab_OnLeave)
		tab:SetScript("OnShow", Tab_OnShow)

		tab._SetText = tab.SetText
		tab.SetText = Tab_SetText
		tab.SetSelected = Tab_SetSelected
		tab.SetDisabled = Tab_SetDisabled

		return tab
	end,

	["SetTitle"] = function(self, text)
		self.titletext:SetText(text or "")
		if text and text ~= "" then
			self.alignoffset = 25
		else
			self.alignoffset = 18
		end
		self:BuildTabs()
	end,

	["SetStatusTable"] = function(self, status)
		assert(type(status) == "table")
		self.status = status
	end,

	["SelectTab"] = function(self, value)
		local status = self.status or self.localstatus
		local found
		for i, v in ipairs(self.tabs) do
			if v.value == value then
				v:SetSelected(true)
				found = true
			else
				v:SetSelected(false)
			end
		end
		status.selected = value
		if found then
			self:Fire("OnGroupSelected",value)
		end
	end,

	["SetTabs"] = function(self, tabs)
		self.tablist = tabs
		self:BuildTabs()
	end,


	["BuildTabs"] = function(self)
		local hastitle = (self.titletext:GetText() and self.titletext:GetText() ~= "")
		local tablist = self.tablist
		local tabs = self.tabs

		if not tablist then return end

		local width = self.frame.width or self.frame:GetWidth() or 0

		wipe(widths)
		wipe(rowwidths)
		wipe(rowends)

		--Place Text into tabs and get thier initial width
		for i, v in ipairs(tablist) do
			local tab = tabs[i]
			if not tab then
				tab = self:CreateTab(i)
				tabs[i] = tab
			end

			tab:Show()
			tab:SetText(v.text)
			tab:SetDisabled(v.disabled)
			tab.value = v.value

			widths[i] = tab:GetWidth() - 6 --tabs are anchored 10 pixels from the right side of the previous one to reduce spacing, but add a fixed 4px padding for the text
		end

		for i = (#tablist)+1, #tabs, 1 do
			tabs[i]:Hide()
		end

		--First pass, find the minimum number of rows needed to hold all tabs and the initial tab layout
		local numtabs = #tablist
		local numrows = 1
		local usedwidth = 0

		for i = 1, #tablist do
			--If this is not the first tab of a row and there isn't room for it
			if usedwidth ~= 0 and (width - usedwidth - widths[i]) < 0 then
				rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
				rowends[numrows] = i - 1
				numrows = numrows + 1
				usedwidth = 0
			end
			usedwidth = usedwidth + widths[i]
		end
		rowwidths[numrows] = usedwidth + 10 --first tab in each row takes up an extra 10px
		rowends[numrows] = #tablist

		--Fix for single tabs being left on the last row, move a tab from the row above if applicable
		if numrows > 1 then
			--if the last row has only one tab
			if rowends[numrows-1] == numtabs-1 then
				--if there are more than 2 tabs in the 2nd last row
				if (numrows == 2 and rowends[numrows-1] > 2) or (rowends[numrows] - rowends[numrows-1] > 2) then
					--move 1 tab from the second last row to the last, if there is enough space
					if (rowwidths[numrows] + widths[numtabs-1]) <= width then
						rowends[numrows-1] = rowends[numrows-1] - 1
						rowwidths[numrows] = rowwidths[numrows] + widths[numtabs-1]
						rowwidths[numrows-1] = rowwidths[numrows-1] - widths[numtabs-1]
					end
				end
			end
		end

		--anchor the rows as defined and resize tabs to fill thier row
		local starttab = 1
		for row, endtab in ipairs(rowends) do
			local first = true
			for tabno = starttab, endtab do
				local tab = tabs[tabno]
				tab:ClearAllPoints()
				if first then
					tab:SetPoint("TOPLEFT", self.frame, "TOPLEFT", 0, -(hastitle and 14 or 7)-(row-1)*20 )
					first = false
				else
					tab:SetPoint("LEFT", tabs[tabno-1], "RIGHT", -10, 0)
				end
			end

			-- equal padding for each tab to fill the available width,
			-- if the used space is above 75% already
			-- the 18 pixel is the typical width of a scrollbar, so we can have a tab group inside a scrolling frame,
			-- and not have the tabs jump around funny when switching between tabs that need scrolling and those that don't
			local padding = 0
			if not (numrows == 1 and rowwidths[1] < width*0.75 - 18) then
				padding = (width - rowwidths[row]) / (endtab - starttab+1)
			end

			for i = starttab, endtab do
				PanelTemplates_TabResize(tabs[i], padding + 4, nil, nil, width, tabs[i]:GetFontString():GetStringWidth())
			end
			starttab = endtab + 1
		end

		self.borderoffset = (hastitle and 17 or 10)+((numrows)*20)
		self.border:SetPoint("TOPLEFT", 1, -self.borderoffset)
	end,

	["OnWidthSet"] = function(self, width)
		local content = self.content
		local contentwidth = width - 60
		if contentwidth < 0 then
			contentwidth = 0
		end
		content:SetWidth(contentwidth)
		content.width = contentwidth
		self:BuildTabs(self)
		self.frame:SetScript("OnUpdate", BuildTabsOnUpdate)
	end,

	["OnHeightSet"] = function(self, height)
		local content = self.content
		local contentheight = height - (self.borderoffset + 23)
		if contentheight < 0 then
			contentheight = 0
		end
		content:SetHeight(contentheight)
		content.height = contentheight
	end,

	["LayoutFinished"] = function(self, width, height)
		if self.noAutoHeight then return end
		self:SetHeight((height or 0) + (self.borderoffset + 23))
	end
}

--[[-----------------------------------------------------------------------------
Constructor
-------------------------------------------------------------------------------]]
local PaneBackdrop  = {
	bgFile = "Interface\\ChatFrame\\ChatFrameBackground",
	edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
	tile = true, tileSize = 16, edgeSize = 16,
	insets = { left = 3, right = 3, top = 5, bottom = 3 }
}

local function Constructor()
	local num = AceGUI:GetNextWidgetNum(Type)
	local frame = CreateFrame("Frame",nil,UIParent)
	frame:SetHeight(100)
	frame:SetWidth(100)
	frame:SetFrameStrata("FULLSCREEN_DIALOG")

	local titletext = frame:CreateFontString(nil,"OVERLAY","GameFontNormal")
	titletext:SetPoint("TOPLEFT", 14, 0)
	titletext:SetPoint("TOPRIGHT", -14, 0)
	titletext:SetJustifyH("LEFT")
	titletext:SetHeight(18)
	titletext:SetText("")

	local border = CreateFrame("Frame", nil, frame, "BackdropTemplate")
	border:SetPoint("TOPLEFT", 1, -27)
	border:SetPoint("BOTTOMRIGHT", -1, 3)
	border:SetBackdrop(PaneBackdrop)
	border:SetBackdropColor(0.1, 0.1, 0.1, 0.5)
	border:SetBackdropBorderColor(0.4, 0.4, 0.4)

	local content = CreateFrame("Frame", nil, border)
	content:SetPoint("TOPLEFT", 10, -7)
	content:SetPoint("BOTTOMRIGHT", -10, 7)

	local widget = {
		num          = num,
		frame        = frame,
		localstatus  = {},
		alignoffset  = 18,
		titletext    = titletext,
		border       = border,
		borderoffset = 27,
		tabs         = {},
		content      = content,
		type         = Type
	}
	for method, func in pairs(methods) do
		widget[method] = func
	end

	return AceGUI:RegisterAsContainer(widget)
end

AceGUI:RegisterWidgetType(Type, Constructor, Version)
