if not ur then
	ur = {}
end
if SERVER then
	ur.loadouts = {}
	ur.config = {}
	ur.loadouts["default"] = { ["loadout"] = { "weapon_physgun", "weapon_physcannon", "gmod_camera", "gmod_tool" }, ["groups"] = {}}
	ur.loadouts["excluded"] = {}
	ur.tools = { ["dynamite"] = {}}
	ur.tools["list"] = {}
	ur.tools["excluded"] = {}
	ur.limit = { ["props"] = {}, ["npcs"] = {}, ["vehicles"] = {}, ["ragdolls"] = {}, ['sents'] = {} }
	ur.spawn = {  ["prop"] = {}, ["npc"] = {}, ["vehicle"] = {}, ["ragdoll"] = {}, ['sent'] = {} }
	ur.config["loadouts"] = true
	ur.config["tools"] = true
	ur.config["admin_exclude"] = { ["loadouts"] = "false", ["tools"] = "false" }
	
	function ur.updateTables()
		file.Write("URestrict/loadouts.txt", ULib.makeKeyValues(ur.loadouts))
		file.Write("URestrict/config.txt", ULib.makeKeyValues(ur.config))
		file.Write("URestrict/tools.txt", ULib.makeKeyValues(ur.tools))
		file.Write("URestrict/spawn_limits.txt", ULib.makeKeyValues(ur.limit))
	end
	
	if file.Exists("URestrict/loadouts.txt") then
		ur.loadouts = ULib.parseKeyValues(file.Read("URestrict/loadouts.txt"))
	else
		file.Write("URestrict/loadouts.txt", ULib.makeKeyValues(ur.loadouts))
	end
	
	if file.Exists("URestrict/props.txt") then
		file.Delete("URestrict/props.txt")
	end
	
	if file.Exists("URestrict/spawn_limits.txt") then
		ur.limit = ULib.parseKeyValues(file.Read("URestrict/spawn_limits.txt"))
		for k,v in pairs({ "props", "sents", "ragdolls", "vehicles", "npcs"}) do
			if !ur.limit[v] then
				ur.limit[v] = {}
				ur.updateTables()
			end
		end
	else
		file.Write("URestrict/spawn_limits.txt", ULib.makeKeyValues(ur.limit))
	end

	if file.Exists("URestrict/tools.txt") then
		ur.tools = ULib.parseKeyValues(file.Read("URestrict/tools.txt"))
	else
		file.Write("URestrict/tools.txt", ULib.makeKeyValues(ur.tools))
	end

	if file.Exists("URestrict/config.txt") then
		ur.config = ULib.parseKeyValues(file.Read("URestrict/config.txt"))
		ur.config.tools = tostring(ur.config.tools)
		ur.config.loadouts = tostring(ur.config.loadouts)
		ur.config.admin_exclude.tools = tostring(ur.config.admin_exclude.tools)
		ur.config.admin_exclude.loadouts = tostring(ur.config.admin_exclude.loadouts)
	else
		file.Write("URestrict/config.txt", ULib.makeKeyValues(ur.config))
	end
	
	function ur.checkToolList( tool )
		if table.HasValue( ur.tools.list, tool ) then
			return true
		end
	end

	function ur.getToolList()
		for k, v in pairs( file.FindInLua( "weapons/gmod_tool/stools/*.lua" ) ) do 
			local newtool = string.gsub(v, ".lua", "")
			if not( ur.checkToolList( newtool ) ) then
				table.insert( ur.tools.list, newtool )	
			end
		end
	end
	
	function ur.syncClient( )
		ur.getToolList()
		local admins = {}
		for k,ply in pairs(player.GetAll()) do
			if ply:IsAdmin() then
				if table.HasValue(ULib.getAllLoadedPlayers(), ply) then
					table.insert(admins, ply)
				end
			end
		end
		if admins then
			local groups = {}
			local loadouts = {}
			local configs = {}
			for k,v in pairs(ULib.ucl.groups) do
				if not(table.HasValue(groups, k)) then
					table.insert(groups, k)
				end
			end
			for k,v in pairs(ur.loadouts) do
				if not(table.HasValue(loadouts, k)) then
					table.insert(loadouts, k)
				end
			end
			ULib.clientRPC(	admins, "ur.getBase", groups, loadouts)
			for k,v in pairs(ur.loadouts) do
				if k ~= "excluded" then
					ULib.clientRPC(admins, "ur.getGroups", k, ur.loadouts[k]["groups"])
				else
					ULib.clientRPC(admins, "ur.getGroups", k, ur.loadouts[k])
				end
			end
			for k,v in pairs(ur.loadouts) do
				if k ~= "excluded" then
					ULib.clientRPC(admins, "ur.getLoadout", k, ur.loadouts[k]["loadout"])
				end
			end
			ULib.clientRPC(admins, "ur.getConfig", ur.config.loadouts, ur.config.tools, ur.config.admin_exclude.loadouts, ur.config.admin_exclude.tools)	
			ULib.clientRPC(admins, "ur.getTools", ur.tools, ur.tools.excluded)
			ULib.clientRPC(admins, "ur.getToolList", ur.tools.list )
			ULib.clientRPC(admins, "ur.getProps", ur.limit.props )
		end
		hook.Add(ULib.HOOK_UCLCHANGED, "ur.syncClient_UCL", ur.syncClient)
	end
	hook.Add("ULibPlayerULibLoaded", "ur.syncClient",ur.syncClient )

	function ur.main( ply )
		if ply:IsValid() then
			if ply:IsAdmin() then
				umsg.Start("URestrict", ply)
				umsg.End()
			else
				ULib.tsay(ply, "You Don't Have Access To This Command")
			end
		else
			print("Not Available In The Server Console")
		end
	end
--	ULib.begin_subconcommand( "urestrict", ur.main, "ur.commands", ULib.ACCESS_ALL )
--	ULib.ucl.registerAccess( "urestrict")
	
	function ur.excludeAdmins(ply, command, args )
		if ply:IsAdmin() then
			if args[1] == "loadouts" then
				if tostring(ur.config.admin_exclude.loadouts) == "false" then
					ur.config.admin_exclude.loadouts = "true"
					ULib.tsay(ply, "Admins Have Been Excluded From Loadout Restrictions")
				else
					ur.config.admin_exclude.loadouts = "false"
					ULib.tsay(ply, "Default Exclusion Of Admins From Loadout Restrictions Have Been Removed.")
				end
			else
				if args[1] == "tools" then
					if tostring(ur.config.admin_exclude.tools) == "false" then
						ur.config.admin_exclude.tools = "true"
						ULib.tsay(ply, "Admins Have Been Excluded From Tool Restrictions")
					else
						ur.config.admin_exclude.tools = "false"
						ULib.tsay(ply, "Default Exclusion Of Admins From Tool Restrictions Have Been Removed.")
					end
				end
			end
			ur.updateTables()
			ur.syncClient()
		else
			ULib.tsay(ply, "You Don't Have Access To This Command")
		end
	end
--	ULib.add_subconcommand(	"urestrict", "adminexclude", ur.excludeAdmins )
	function ur.toggle(ply, commands, args)
		if ply:IsAdmin() then
			if args[1] == "loadouts" then
				if tostring(ur.config.loadouts) == "false" then
					ur.config.loadouts = "true"
					ULib.tsay(ply, "Loadout Restrictions Have Been Enabled")
				else
					ur.config.loadouts = "false"
					ULib.tsay(ply, "Loadout Restrictions Have Been Disabled")
				end
			else
				if args[1] == "tools" then
					if ur.config.tools == "false" then
						ur.config.tools = "true"
						ULib.tsay(ply, "Tool Restrictions Have Been Enabled")
					else
						ur.config.tools = "false"
						ULib.tsay(ply, "Tool Restrictions Have Been Disabled")
					end
				end
			end
			ur.updateTables()
			ur.syncClient()
		else
			ULib.tsay(ply, "You Don't Have Access To This Command")
		end
	end
--	ULib.add_subconcommand(	"urestrict", "toggle", ur.toggle )
	function ur.getGroupLoadout(group)
		for loadout, _ in pairs( ur.loadouts ) do
			if loadout ~= "excluded" then
				for _, lgroup in pairs( ur.loadouts[loadout]["groups"] ) do
					if lgroup == group then
						return loadout
					end
				end
			else
				for k,v in pairs(ur.loadouts.excluded) do
					if group == v then
						return "excluded"
					end
				end
				
			end
		end
		return "none"
	end
	for k,v in pairs(ULib.ucl.groups) do
		if ur.getGroupLoadout(k) == "none" then
			table.insert( ur.loadouts.default["groups"], k )
		end
	end
	if SERVER then
		Msg( "///////////////////////////////\n" )
		Msg( "//         URestrict         //\n" )
		Msg( "///////////////////////////////\n" )
		Msg( "//Loading...                 //\n" )
		local file = "init.lua"
		Msg( "//  MODULE: " .. file .. string.rep( " ", 17 - file:len() ) .. "//\n" )
		include( "ULib/modules/base/" .. file )
	end
	ur.restricted = {}
	function ur.initClient(ply)	
		ur.restricted[ply] = {}
		if ur.loadouts[ur.getLoadout( ply )] then
			if ur.getLoadout( ply ) ~= "excluded" then
				ULib.tsay(ply, "Certain Weapon Restrictions May Apply To Your User Group.")
				ur.restricted[ply] = { ["loadout"] = true }
			end
		end
		for k,v in pairs(ur.tools) do
			if (not(k == "list") and not(k == "excluded")) then
				if not(table.HasValue(ur.tools[k], ply:GetUserGroup())) then
					if not(table.HasValue(ur.tools.excluded, ply:GetUserGroup())) then
						ULib.tsay(ply, "Certain Tool Restrictions May Apply To Your User Group.")
						ur.restricted[ply] = { ["tools"] = true }
					end
				end
			end
		end
		if ur.restricted[ply]["loadout"] == true or ur.restricted[ply]["tools"] == true then
			ULib.tsay(ply, "Any Questions Or Concerns About What Restrictions Are In Place, Please Contact An Administrator")
		end
		ur.restricted[ply] = nil
	end
	hook.Add("ULibPlayerULibLoaded", "ur.initClient",ur.initClient )
end
ULib.cmds.addCommand( "urestrict", ur.main, nil )
ULib.cmds.addCommand( "urestrict toolexclude", ur.groupExclude, nil )
ULib.cmds.addCommand( "urestrict deny", ur.toolDeny, nil )
ULib.cmds.addCommand( "urestrict allow", ur.toolAllow, nil)
ULib.cmds.addCommand( "urestrict tool", ur.modifyTool, nil)
ULib.cmds.addCommand( "urestrict excluded", ur.excludeGroup, nil)
ULib.cmds.addCommand( "urestrict apply", ur.applyLoadout, nil)
ULib.cmds.addCommand( "urestrict remove", ur.removeLoadout, nil)
ULib.cmds.addCommand( "urestrict make", ur.makeLoadout, nil)
ULib.cmds.addCommand( "urestrict modify", ur.modifyLoadout, nil)
ULib.cmds.addCommand( "urestrict adminexclude", ur.excludeAdmins, nil)
ULib.cmds.addCommand( "urestrict toggle", ur.toggle, nil )

local props = ULib.cmds.TranslateCommand("urestrict props", ur.prop)
props:addParam{ type=ULib.cmds.StringArg, completes=ulx.group_names, hint="group", error="invalid group \"%s\" specified", ULib.cmds.restrictToCompletes }
props:addParam{ type=ULib.cmds.NumArg, min=-1, default=0, hint="max props", ULib.cmds.round }
props:defaultAccess( ULib.ACCESS_ADMIN )

local npcs = ULib.cmds.TranslateCommand("urestrict npcs", ur.npc)
npcs:addParam{ type=ULib.cmds.StringArg, completes=ulx.group_names, hint="group", error="invalid group \"%s\" specified", ULib.cmds.restrictToCompletes }
npcs:addParam{ type=ULib.cmds.NumArg, min=-1, default=0, hint="max npcs", ULib.cmds.round }
npcs:defaultAccess( ULib.ACCESS_ADMIN )

local vehicles = ULib.cmds.TranslateCommand("urestrict vehicles", ur.vehicle)
vehicles:addParam{ type=ULib.cmds.StringArg, completes=ulx.group_names, hint="group", error="invalid group \"%s\" specified", ULib.cmds.restrictToCompletes }
vehicles:addParam{ type=ULib.cmds.NumArg, min=-1, default=0, hint="max vehicles", ULib.cmds.round }
vehicles:defaultAccess( ULib.ACCESS_ADMIN )

local ragdolls = ULib.cmds.TranslateCommand("urestrict ragdolls", ur.ragdoll)
ragdolls:addParam{ type=ULib.cmds.StringArg, completes=ulx.group_names, hint="group", error="invalid group \"%s\" specified", ULib.cmds.restrictToCompletes }
ragdolls:addParam{ type=ULib.cmds.NumArg, min=-1, default=0, hint="max ragdolls", ULib.cmds.round }
ragdolls:defaultAccess( ULib.ACCESS_ADMIN )

local sents = ULib.cmds.TranslateCommand("urestrict sents", ur.sent)
sents:addParam{ type=ULib.cmds.StringArg, completes=ulx.group_names, hint="group", error="invalid group \"%s\" specified", ULib.cmds.restrictToCompletes }
sents:addParam{ type=ULib.cmds.NumArg, min=-1, default=0, hint="max sents", ULib.cmds.round }
sents:defaultAccess( ULib.ACCESS_ADMIN )





