--[[   _                                

	( )                               

   _| |   __   _ __   ___ ___     _ _ 

 /'_` | /'__`\( '__)/' _ ` _ `\ /'_` )

( (_| |(  ___/| |   | ( ) ( ) |( (_| |

`\__,_)`\____)(_)   (_) (_) (_)`\__,_) 



--]]



local table 			= table

local vgui				= vgui

local concommand		= concommand

local Msg				= Msg

local setmetatable		= setmetatable

local _G				= _G

local hook 				= hook

local gamemode			= gamemode

local debug				= debug

local pairs				= pairs

local ispanel			= ispanel

local isfunction		= isfunction

local istable			= istable

local PrintTable		= PrintTable



module( "derma" )



Controls = {}

SkinList = {}



local derma_skin_name = nil

local DefaultSkin = {}

local SkinMetaTable = {}

local iSkinChangeIndex = 1



SkinMetaTable.__index = function ( self, key ) 

							return DefaultSkin[key]

						end



local function FindPanelsByClass( SeekingClass )



	local outtbl = {}



	--

	-- Going through the registry is a hacky way to do this.

	-- We're only doing it this way because it doesn't matter if it's a

	-- bit slow - because this function is only used when reloading.

	--

	local tbl = debug.getregistry()

	for k, v in pairs( tbl ) do



		if ( ispanel( v ) && v.ClassName && v.ClassName == SeekingClass ) then



			table.insert( outtbl, v )



		end



	end



	return outtbl



end



--

-- Find all the panels that use this class and

-- if allowed replace the functions with the new ones.

--

local function ReloadClass( classname )



	local ctrl = vgui.GetControlTable( classname )

	if ( !ctrl ) then return end



	local tbl = FindPanelsByClass( classname )



	for k, v in pairs ( tbl ) do



		if ( !v.AllowAutoRefresh ) then continue end



		if ( v.PreAutoRefresh ) then

			v:PreAutoRefresh()

		end



		for name, func in pairs( ctrl ) do



			if ( !isfunction( func ) ) then continue end



			v[ name ] = func;



		end



		if ( v.PostAutoRefresh ) then

			v:PostAutoRefresh()

		end



	end



end

						

--[[---------------------------------------------------------

   GetControlList

-----------------------------------------------------------]]

function GetControlList()



	return Controls

	

end



--[[---------------------------------------------------------

   DefineControl

-----------------------------------------------------------]]

function DefineControl( strName, strDescription, strTable, strBase )



	local bReloading = Controls[ strName ] != nil



	-- Add Derma table to PANEL table.

	strTable.Derma = {	ClassName 	= strName, 

						Description = strDescription, 

						BaseClass 	= strBase }



	-- Register control with VGUI

	vgui.Register( strName, strTable, strBase )

	

	-- Store control

	Controls[ strName ] = strTable.Derma

	

	-- Store as a global so controls can 'baseclass' easier

	-- TODO: STOP THIS

	_G[ strName ] = strTable



	if ( bReloading ) then

		Msg( "Reloaded Control: ", strName, "\n" )

		ReloadClass( strName )

	end

	

	return strTable

	

end







--[[---------------------------------------------------------

   DefineSkin

-----------------------------------------------------------]]

function DefineSkin( strName, strDescription, strTable )



	strTable.Name = strName

	strTable.Description = strDescription

	strTable.Base = strBase or "Default"

	

	if ( strName != "Default" ) then

		setmetatable( strTable, SkinMetaTable )

	else

		DefaultSkin = strTable

	end



	SkinList[ strName ] = strTable

	

end



--[[---------------------------------------------------------

   GetSkin - Returns current skin for panel

-----------------------------------------------------------]]

function GetSkinTable()



	return table.Copy( SkinList )



end



--[[---------------------------------------------------------

   Returns 'Default' Skin

-----------------------------------------------------------]]

function GetDefaultSkin()



	local skin = nil

	

	-- Check gamemode skin preference

	if ( gamemode ) then

		local skinname = gamemode.Call( "ForceDermaSkin" )

		if ( skinname ) then skin = GetNamedSkin( skinname ) end

	end



	-- default

	if (!skin) then skin = DefaultSkin end

	

	return skin

end



--[[---------------------------------------------------------

   Returns 'Named' Skin

-----------------------------------------------------------]]

function GetNamedSkin( name )

	return SkinList[ name ]

end



--[[---------------------------------------------------------

   SkinHook( strType, strName, panel )

-----------------------------------------------------------]]

function SkinHook( strType, strName, panel, w, h )



	local Skin = panel:GetSkin()



	if ( !Skin ) then return end

	local func = Skin[ strType .. strName ]

	if ( !func ) then return end

	

	return func( Skin, panel, w, h )

	

end





--[[---------------------------------------------------------

   SkinTexture( strName, panel, default )

-----------------------------------------------------------]]

function SkinTexture( strName, panel, default )



	local Skin = panel:GetSkin()



	if ( !Skin ) then return default end

	

	local Textures = Skin.tex



	if ( !Textures ) then return default end

	

	return Textures[ strName ] or default

	

end



--[[---------------------------------------------------------

   Color( strName, panel, default )

-----------------------------------------------------------]]

function Color( strName, panel, default )



	local Skin = panel:GetSkin()



	if ( !Skin ) then return default end



	return Skin[ strName ] or default

	

end



--[[---------------------------------------------------------

   SkinChangeIndex

-----------------------------------------------------------]]

function SkinChangeIndex()

	return iSkinChangeIndex

end



--[[---------------------------------------------------------

   RefreshSkins - clears all cache'd panels (so they will reassess which skin they should be using)

-----------------------------------------------------------]]

function RefreshSkins()

	iSkinChangeIndex = iSkinChangeIndex + 1

end

