-- Function to set a players flag.
local function SetFlag( ply, cmd, args )
	if ( ply:IsAdmin() or ply:HasFlag( "p" ) ) then --or tonumber( UserRanks[ ply.fizzminrank ][ "Level" ] ) > 98 ) ) then
		if ( #args < 1 ) then
			ply:SendNotify( "Use: /setflag <player name> <flag>" );
			return;
		end;
		
		local Target = epsilonScript.FindPlayer( args[ 1 ] );
		local Flag = string.lower( args[ 2 ] );
		
		if ( Target ) then
			if ( !Target:HasFlag( Flag ) ) then
				table.insert( Target:GetCharInfo( "Flags" ), Flag );
				epsilonScript:SavePlayer( Target );
				
				Target:SendNotify( ply:Name() .. " has given you the flag '" .. Flag .. "'." );
				Target:UpdateFlags();
				
				ply:SendNotify( "You gave '" .. Target:Name() .. "' the flag '" .. Flag .. "'." );
			else
				ply:SendNotify( Target:Name() .. " already has the flag '" .. Flag .. "'" );
				return;
			end;
		else
			ply:SendNotify( "Player '" .. args[ 1 ] .. "' was not found!" );
		end;
	end;
end;
concommand.Add( "eps_setflag", SetFlag );
epsilonScript.AddChatCmd( "setflag", "eps_setflag" );

-- Function to select a flag.
local function Flag( ply, cmd, args )
	for k, v in pairs( epsilonScript.Classes.Stored ) do
		if ( v.Flag == args[ 1 ] ) then
			if ( ply:HasFlag( args[ 1 ] ) or v.Public ) then
				ply:SetTeam( k );
				ply:KillSilent();
				ply:Spawn();
			else
				ply:SendNotify( "Use the menu idiot!" );
				return;
			end;
		end;
	end;
end;
concommand.Add( "eps_flag", Flag );

-- Core function to create a new character.
function epsilonScript.CreateNewCharacter( ply, cmd, args )
	ply.Ready = false;
	
	if ( !ply.Ready ) then
		ply.epsilonScriptData[ #ply.epsilonScriptData + 1 ] = 
		{
			Name = args[ 1 ],
			Model = args[ 2 ],
			Title = args[ 3 ],
			Money = epsilonScript.Config:Get( "DefaultMoney" ),
			Inventory = { [ "Items" ] = {}, [ "Weight" ] = 0, [ "MaxWeight" ] = 10 },
			Flags = {},
			KnownPlayers = {}
		};
		
		ply.CharID = #ply.epsilonScriptData;
		ply:SetNWString( "RPName", ply:GetCharInfo( "Name" ) );
		ply:SetNWString( "Title", ply:GetCharInfo( "Title" ) );
		ply:UpdateMoney();
		ply:UpdateFlags();
		ply.Ready = true;
		ply:Freeze( false );
		ply:SetTeam( 1 );
		ply:Spawn();
	end;
	
	for k, v in pairs( epsilonScript.Config:Get( "DefaultInventoryItems" ) ) do
		if ( !ply:HasItem( v ) ) then
			ply:GiveItem( v, 1 );
		end;
	end;
	
	epsilonScript.SavePlayer( ply );
	ply:SendSavedInventory();
end;
concommand.Add( "eps_createnewchar", epsilonScript.CreateNewCharacter );

-- Core function to start the character selection.
function epsilonScript.StartCharSelect( ply, cmd, args )
	ply.epsilonScriptData = table.CleanUpKeys( ply.epsilonScriptData );
	ply.Ready = false;
	
	umsg.Start( "ResetInventory", ply );
	umsg.End();
	
	for k, v in pairs( ply.epsilonScriptData ) do
		umsg.Start( "RecieveCharacters", ply );
			umsg.Short( k );
			umsg.String( v.Name );
			umsg.String( v.Model );
		umsg.End();
	end;
	
	ply:ConCommand( "eps_CharSelectMenu" );
end
concommand.Add( "eps_startselectchar", epsilonScript.StartCharSelect );

-- Function to choose a character.
function epsilonScript.ChooseCharacter( ply, cmd, args )
	if ( ply.Ready ) then
		return;
	end;
	
	local ID = tonumber( args[ 1 ] );

	ply.CharID = ID;
	ply:SetNWString( "RPName", ply:GetCharInfo( "Name" ) );
	ply:SetNWString( "Title", ply:GetCharInfo( "Title" ) );
	ply:UpdateMoney();
	ply:UpdateFlags();
	ply.Ready = true;
	ply:Freeze( false );
	ply:SetTeam( 1 );
	ply:Spawn();
	
	for k, v in pairs( epsilonScript.Config:Get( "DefaultInventoryItems" ) ) do
		if ( !ply:HasItem( v ) ) then
			ply:GiveItem( v, 1 );
		end;
	end;
	
	ply:SendSavedInventory();
end;
concommand.Add( "eps_selectcharacter", epsilonScript.ChooseCharacter );

-- Function to remove a character.
function epsilonScript.RemoveCharacter( ply, cmd, args )
	local ID = tonumber( args[ 1 ] );

	if ( ply.epsilonScriptData[ ID ] ) then
		ply.epsilonScriptData[ ID ] = nil;
	end;

	epsilonScript.StartCharSelect( ply, cmd, args );
end;
concommand.Add( "eps_removecharacter", epsilonScript.RemoveCharacter );

-- Function to use a item.
function epsilonScript.UseItem( ply, cmd, args )
	if ( !ply:Alive() ) then return end;

	local Item = args[ 1 ];
	
	if ( epsilonScript.Items.Stored[ Item ] and ply:HasItem( Item ) ) then
		if ( epsilonScript.Items.GetItem( Item ).RemoveOnUse ) then 
			ply:RemoveItem( Item, 1 ) 
		end;
		
		epsilonScript.Items.GetItem( Item ):OnUse( ply );
	end;
end;
concommand.Add( "eps_useitem", epsilonScript.UseItem );

-- Function to drop a item.
function epsilonScript.DropItem( ply, cmd, args )
	if ( !ply:Alive() ) then return end;
	
	local Item = args[ 1 ];

	if ( epsilonScript.Items.Stored[ Item ] and ply:HasItem( Item ) ) then
		ply:SpawnItem( Item );
		ply:RemoveItem( Item, 1 );
		epsilonScript.Items.GetItem( Item ):OnDrop( ply );
		ply:EmitSound( "items/ammocrate_close.wav" );
	end;
end;
concommand.Add( "eps_dropitem", epsilonScript.DropItem );

-- Function to buy a item.
function epsilonScript.BuyItem( ply, cmd, args )
	local Item = args[ 1 ];
	local Price = epsilonScript.Items.GetItem( Item ).Cost
	local Currency = epsilonScript.Config:Get( "Currency" );
	
	if ( !epsilonScript.Items.Stored[ Item ] ) then
		return;
	elseif ( !ply:CanAfford( Price ) ) then 
		ply:SendNotify( "You need another " .. ( Price - ply:GetMoney() ) .. Currency );
		return;
	elseif ( !ply:HasInventorySpace( Item ) ) then
		ply:SendNotify( "Your inventory is full!" );
		return;
	end;
	
	ply:GiveItem( Item, 1 );
	ply:SetCharInfo( "Money", ply:GetMoney() - Price );
	ply:UpdateMoney();
	ply:SendNotify( "Item Purchased!" );
	epsilonScript.Items.GetItem( Item ):OnPickup( ply );
end;
concommand.Add( "eps_buyitem", epsilonScript.BuyItem );

-- Function to sell a item.
function epsilonScript.SellItem( ply, cmd, args )
	local Item = args[ 1 ];
	
	if ( epsilonScript.Items.Stored[ Item ] and ply:HasItem( Item ) ) then
		ply:RemoveItem( Item, 1 );
		ply:SetCharInfo( "Money", ply:GetMoney() + epsilonScript.Items.GetItem( Item ).Cost );
		ply:UpdateMoney();
		epsilonScript.Items.GetItem( Item ):OnDrop( ply );
	end;
end;
concommand.Add( "eps_sellitem", epsilonScript.SellItem );

-- Function to drop your weapon.
function epsilonScript.DropWeapon( ply, cmd, args )
	local weapon = ply:GetActiveWeapon();
	
	if ( weapon:IsValid() ) then
		local weaponClass = weapon:GetClass();
		
		if ( epsilonScript.Items.Stored[ weaponClass ] ) then
			ply:SpawnItem( weaponClass );
			ply:StripWeapon( weaponClass );
			ply:EmitSound( "items/ammocrate_close.wav" );
		end;
	end;
end;
concommand.Add( "eps_dropweapon", epsilonScript.DropWeapon );
epsilonScript.AddChatCmd( "dropweapon", "eps_dropweapon" );

-- Function to put the weapon in your inventory.
function epsilonScript.PutWeaponIntoInventory( ply, cmd, args )
	local weapon = ply:GetActiveWeapon();

	if ( weapon:IsValid() ) then
		local weaponClass = weapon:GetClass();
		
		if ( epsilonScript.Items.Stored[ weaponClass ] ) then
			ply:GiveItem( weaponClass, 1 );
			ply:StripWeapon( weaponClass );
			ply:EmitSound( "items/ammocrate_open.wav" );
		end;
	end;
end;
concommand.Add( "eps_weaponintoinventory", epsilonScript.PutWeaponIntoInventory );
epsilonScript.AddChatCmd( "holster", "eps_weaponintoinventory" );

-- Function to give a player money.
local function GiveMoney( ply, cmd, args )
	local Ent = ply:TracePlayer( 80 )
	local Currency = epsilonScript.Config:Get( "Currency" );
	local Amount = tonumber( args[ 1 ] );
	
	-- Not enough args?
	if ( #args < 1 ) then 
		ply:SendNotify( "Use: Face a player and type /givemoney < amount >"  );
		return;
	end;
	
	if ( Ent:IsValid() ) then
		-- Don't have the given amount?
		if ( !ply:CanAfford( Amount ) ) then
			ply:SendNotify( "You need another " .. ( Amount - ply:GetMoney() ) .. Currency );
			return;
		end;
		
		-- Modify the givers money.
		ply:SetCharInfo( "Money", ply:GetMoney() - Amount );
		ply:UpdateMoney();
		ply:SendNotify( "You gave '" .. Ent:Name() .. "' " .. Amount .. Currency );
		
		-- Modify the takers money.
		Ent:SetCharInfo( "Money", Ent:GetMoney() + Amount );
		Ent:UpdateMoney()
		Ent:SendNotify( "You recieved " .. Amount .. Currency .. " from '" .. ply:Name() );
	end;
end;
concommand.Add( "eps_givemoney", GiveMoney );
epsilonScript.AddChatCmd( "givemoney", "eps_givemoney" );

-- Function to change your roleplay name.
local function ChangeRPName( ply, cmd, args )
	local Output = table.concat( args, " " );
	
	if ( Output != "" ) then
		ply:SetCharInfo( "Name", Output );
		ply:SetNWString( "RPName", Output );
	end;
end;
concommand.Add( "eps_changerpname", ChangeRPName );
epsilonScript.AddChatCmd( "setrpname", "eps_changerpname" );