
-- Used on server only
local table 			= table
local pairs 			= pairs
local concommand 		= concommand
local SERVER 			= SERVER
local CLIENT 			= CLIENT
local saverestore 		= saverestore
local hook				= hook

-- Used on client only
local GetControlPanel = GetControlPanel

module( "cleanup" )

local cleanup_types = {}

local function IsType( type )

	for key, val in pairs( cleanup_types ) do
	
		if ( val == type ) then return true end
		
	end
	
	return false
	
end

function Register( type )

	if ( type == "all" ) then return end
	
	for key, val in pairs( cleanup_types ) do
	
		if val == type then return end
		
	end
	
	table.insert( cleanup_types, type )
	
	if ( CLIENT ) then UpdateUI() end
	
end

if ( SERVER ) then

	local cleanup_list = {}
	

	local function Save( save )
	
		saverestore.WriteTable( cleanup_list, save )
		
	end
	
	local function Restore( restore )
	
		cleanup_list = saverestore.ReadTable( restore )
		
	end
	
	saverestore.AddSaveHook( "CleanupTable", Save )
	saverestore.AddRestoreHook( "CleanupTable", Restore )
	
	function Add( pl, type, ent )
	
		if ( !ent ) then return end
		
		if ( !IsType( type ) ) then return end
		
		local id = pl:UniqueID()
		
		cleanup_list[ id ] = cleanup_list[ id ] or {}
		cleanup_list[ id ][ type ] = cleanup_list[ id ][ type ] or {}
		
		if ( !ent:IsValid() ) then return end
		
		table.insert( cleanup_list[ id ][ type ], ent )
		
	end

	function ReplaceEntity( from, to )
	
		local ActionTaken = false
	
		for _, PlayerTable in pairs(cleanup_list) do
			for _, TypeTable in pairs(PlayerTable) do
				for key, ent in pairs(TypeTable) do
				
						if ( ent == from ) then
							TypeTable[ key ] = to
							ActionTaken = true
						end
											
				end
			end	
		end
		
		return ActionTaken
		
	end
	
	function CC_Cleanup( pl, command, args )
	
		local id = pl:UniqueID()
		
		if ( !cleanup_list[id] ) then return end
		
		if ( !args[1] ) then
		
			local count = 0
		
			for key, val in pairs( cleanup_list[id] ) do
			
				for key, ent in pairs( val ) do
				
					if ( ent:IsValid() ) then ent:Remove() end
					count = count + 1
					
				end
				
			end
			
			// Send tooltip command to client
			if (count > 0 ) then
				pl:SendLua( "GAMEMODE:OnCleanup( 'all' )" )
			end
			
			return
			
		end
		
		if ( !IsType( args[1] ) ) then return end
		if ( !cleanup_list[id][args[1]] ) then return end
		
		for key, ent in pairs( cleanup_list[id][args[1]] ) do
		
			if ( ent:IsValid() ) then ent:Remove() end
			
		end
		
		// Send tooltip command to client
		pl:SendLua( "GAMEMODE:OnCleanup( '"..args[1].."' )" )
		
	end
	
	function CC_AdminCleanup( pl, command, args )
	
		if ( pl && pl:IsValid() && !pl:IsAdmin() ) then return end
		
		if ( !args[1] ) then
		
			for key, player in pairs( cleanup_list ) do
			
				for key, type in pairs( player ) do
				
					for key, ent in pairs( type ) do
					
						if ( ent:IsValid() ) then ent:Remove() end
						
					end
					
				end
				
			end
			
			// Send tooltip command to client
			pl:SendLua( "GAMEMODE:OnCleanup( 'all' )" )
			
			return
			
		end
		
		if ( !IsType( args[1] ) ) then return end
		
		for key, player in pairs( cleanup_list ) do
		
			if ( player[args[1]] != nil ) then
			
				for key, ent in pairs( player[args[1]] ) do
				
					if ( ent:IsValid() ) then ent:Remove() end
					
				end
				
			end
			
		end
		
		// Send tooltip command to client
		pl:SendLua( "GAMEMODE:OnCleanup( '"..args[1].."' )" )
		
	end
	
	concommand.Add( "gmod_cleanup",		CC_Cleanup )
	concommand.Add( "gmod_admin_cleanup",	CC_AdminCleanup )
	
else

	function UpdateUI()
	
		local Panel = GetControlPanel( "User_Cleanup" )
		if (!Panel) then return end
		
		Panel:ClearControls()
		Panel:AddControl( "Header", { Text = "#CleanUp" }  )
		
		local params = {}
		params.Text = "#CleanupAll"
		params.Command = "gmod_cleanup"
		
		Panel:AddControl( "Button", params )
		
		table.sort( cleanup_types )
		
		for key, val in pairs( cleanup_types ) do
		
			local params = {}
			params.Label = "#Cleanup_"..val
			params.Text = "Remove All"
			params.Command = "gmod_cleanup "..val
			
			Panel:AddControl( "Button", params )
			
		end
		
		local Panel = GetControlPanel( "Admin_Cleanup" )
		if (!Panel) then return end
		
		Panel:ClearControls()
		Panel:AddControl( "Header", { Text = "#CleanUp" }  )
		
		local params = {}
		params.Text = "#CleanupAll"
		params.Command = "gmod_admin_cleanup"
		
		Panel:AddControl( "Button", params )
		
		table.sort( cleanup_types )
		
		for key, val in pairs( cleanup_types ) do
		
			local params = {}
			params.Label = "#Cleanup_"..val
			params.Text = "Remove All"
			params.Command = "gmod_admin_cleanup "..val
			
			Panel:AddControl( "Button", params )
			
		end
		
	end
	
	hook.Add( "PostReloadToolsMenu", "BuildCleanupUI", UpdateUI )
	
end
