-- Clientside menu, available to admins
-- make their command running easier

local ItemList = nil;

local CommandList = {
"admin_kick",
"admin_ban",
"admin_setmoney",
"admin_setflags",
"admin_addflag",
"admin_tooltrust",
"admin_findowner",
"admin_unowndoor",
"admin_getTT",
"admin_addmoney",
"admin_setplayermodel",
"admin_setdefaultmodel",
"admin_goto",
"admin_bring",
"admin_noclip",
"admin_slay",
"admin_slap",
"admin_settitle",
"admin_observe",
"admin_restartmap",
"admin_playtoall",
"admin_stopsounds",
"admin_resumeMusic",
"admin_clear_songs",
"admin_seeall",
"admin_ooc",
"admin_ooc_enable",
};

-- used to copy the item table over to the client side, should only occur once per connection
-- if they are an admin and try /admin and the table is not set
local function receiveAdminItem( data )

	local tableName = data:ReadString();
	local itemName = data:ReadString();
	local modelName = data:ReadString();
	local className = data:ReadString();
	local Description = data:ReadString();
	
	local ITEM = {};
	ITEM.Name = itemName;
	ITEM.Class = className;
	ITEM.Description = Description;
	ITEM.Model = modelName;
	
	ItemList[ITEM.Class] = ITEM;

end
usermessage.Hook("AddAdminItem", receiveAdminItem);

local SongTable = {};
local playingSong = "";
local AllSongs = nil;

-- tells us what song is being played
local function receivePlayingSong( data )
	playingSong = data:ReadString();
end
usermessage.Hook("AddPlayingItem", receivePlayingSong);

-- used to copy the server's song queue to the client's side. Will occur every time the menu is opened.
local function receiveQueueSong( data )

--Msg("received a queue entry\n");
	table.insert( SongTable, data:ReadString() );

end
usermessage.Hook("AddQueueSong", receiveQueueSong);

-- copy of all the songs known by the server
local function receiveMusicList( data )

	table.insert( AllSongs, data:ReadString() );

end
usermessage.Hook("AddMusicItem", receiveMusicList);


local function openAdminMenu()

	if( adminFrame != nil ) then
	
		adminFrame:Remove();
		adminFrame = nil;
	
	end
	
	if( ItemList == nil ) then
		ItemList = {};
		RunConsoleCommand("admin_getItems");
		return;
	end
	
	if( AllSongs == nil ) then
		AllSongs = {};
		RunConsoleCommand("admin_get_all_songs");
		return;
	end
	
	-- reset their song list and get the current queue
	SongTable = {};
	RunConsoleCommand("admin_get_song_list");
	
	-- used for running the con cmd
	local playerName = "invalid";
	local selectedCommand = "invalid";
	
	local adminFrame = vgui.Create( "DFrame" );
	adminFrame:SetPos( ScrW()/5, ScrH()/5 );
	adminFrame:SetSize( ScrW()*2/3, ScrH()*2/3 );
	adminFrame:SetTitle( "The admin panel!" );
	adminFrame:SetVisible( true );
	adminFrame:SetDraggable( true );
	adminFrame:ShowCloseButton( true );
	adminFrame:MakePopup();
	adminFrame:SetDeleteOnClose(false); -- can cause problems when closed while its refreshing
	
	local adminProperty = vgui.Create("DPropertySheet", adminFrame);
	adminProperty:SetPos( 10, 30 );
	local parentX, parentY = adminFrame:GetSize();
	adminProperty:SetSize( parentX - 20, parentY - 40 );
	adminProperty:SetPadding( 10 );
	
	-- this panel will hold all players, and all admin concmds
	local cmdPanel = vgui.Create( "DPanel" );
	parentX, parentY = adminProperty:GetSize();
	cmdPanel:SetSize( parentX - 10, parentY - 10 );
	
	-- overwrite the paint function to make it a better color
	cmdPanel.Paint = function()
		surface.SetDrawColor( 50, 50, 50, 255 );
		surface.DrawRect( 0, 0, cmdPanel:GetWide(), cmdPanel:GetTall() );
	end 
	
	-- button that will list an option for each connected player
	local playerButton = vgui.Create("DButton", cmdPanel);
	parentX, parentY = cmdPanel:GetSize();
	playerButton:SetSize( parentX / 4, parentY / 10 );
	playerButton:SetPos( parentX/5, parentY / 5 );
	playerButton:SetText( "Select a player" );
	playerButton.DoClick = function ( btn )
		local MenuButtonOptions = DermaMenu();
		for k, v in pairs(player.GetAll()) do
		
			MenuButtonOptions:AddOption( v:Name(), function()
			
														
														playerButton:SetText( v:Nick() );
														playerName = v:Nick();
														
														/* I can be silly sometimes
														-- this will get their first name, then break
														for _, name in pairs(string.Explode(" ", v:Nick() )) do
															playerButton:SetText( name );
															playerName = name;
															break;
														end
														*/
												   end);
		
		end
		MenuButtonOptions:Open();
	end
	
	-- button that will list each command in the command table at the top of this file.
	local commandButton = vgui.Create("DButton", cmdPanel);
	commandButton:SetSize( parentX / 4, parentY / 10 );
	commandButton:SetPos( parentX*3/5, parentY / 5 );
	commandButton:SetText( "Select a command" );
	commandButton.DoClick = function ( btn )
		local MenuButtonOptions = DermaMenu();
		for k, v in pairs( CommandList ) do
		
			MenuButtonOptions:AddOption( v, function()
														commandButton:SetText( v );
														selectedCommand = v;
												   end );
		end
		MenuButtonOptions:Open();
	end
	
	-- a label to go above the text entry
	commandLabel = vgui.Create( "DLabel", cmdPanel );
	commandLabel:SetFont( "ChatFont" );
	commandLabel:SetText( "Put additional info here." );
	commandLabel:SetPos( parentX/5, parentY*2/5 );
	commandLabel:SetTextColor( Color(255,255,255) );
	commandLabel:SizeToContents();
	
	-- a text entry field for entering extra values if needed.
	commandText = vgui.Create( "DTextEntry", cmdPanel );
	commandText:SetPos( parentX/5, parentY*2/5 + 30 );
	commandText:SetSize( parentX/4, 15 );
	commandText:SetVisible( true );
	commandText:SetEnabled( true );
	commandText:SetKeyboardInputEnabled( true );
	commandText:SetMouseInputEnabled( true );
	
	local doCommand = vgui.Create("DButton", cmdPanel);
	doCommand:SetSize( parentX/4, parentY/10 );
	doCommand:SetPos( parentX*3/5, parentY*2/5 );
	doCommand:SetText("Run the command.");
	doCommand.DoClick = function ( btn )
		Msg( "Running command: " .. selectedCommand .. " " .. playerName .. " " .. commandText:GetValue() .. "\n" );
		-- the code used to find name automatically puts a space at the end
		RunConsoleCommand( selectedCommand, playerName, commandText:GetValue() );
	end
	
	
	-- this panel will help make item creation easier
	-- I modified inventory code, was gonna rewrite it but it woulda been pretty much the same
	
	local itemPanel = vgui.Create( "DPanelList" )
	itemPanel:SetPadding(20);
	itemPanel:SetSpacing(20);
	itemPanel:EnableHorizontal(true);
	itemPanel:EnableVerticalScrollbar(true);
	
	for k, v in pairs( ItemList ) do

		local spawnicon = vgui.Create( "DModelPanel" )
		spawnicon:SetSize( 128, 128 );
		spawnicon:SetModel( v.Model )
		spawnicon:SetAnimSpeed( 0.0 )
		spawnicon:SetAnimated( false )
		spawnicon:SetAmbientLight( Color( 50, 50, 50 ) )
		spawnicon:SetDirectionalLight( BOX_TOP, Color( 255, 255, 255 ) )
		spawnicon:SetDirectionalLight( BOX_FRONT, Color( 255, 255, 255 ) )
		spawnicon:SetCamPos( Vector( 0, 0, 40 ) )
		spawnicon:SetLookAt( Vector( 0, 0, 40 ) )
		spawnicon:SetFOV( 70 )
		spawnicon:SetToolTip( v.Description )
		
		local function DeleteMyself()
			spawnicon:Remove()
		end
		
		spawnicon.DoClick = function ( btn )
		
			RunConsoleCommand( "admin_createitem", v.Class );
			
		end
		
		spawnicon.PaintOver = function()
			surface.SetTextColor(Color(255,255,255,255));
			surface.SetFont("DefaultSmall");
			surface.SetTextPos(64 - surface.GetTextSize(v.Name) / 2, 5);
			surface.DrawText(v.Name)
		end
		
		spawnicon.PaintOverHovered = function()
			surface.SetTextColor(Color(255,255,255,255));
			surface.SetFont("DefaultSmall");
			surface.SetTextPos(64 - surface.GetTextSize(v.Name) / 2, 5);
			surface.DrawText(v.Name)
		end
		
		spawnicon.LayoutEntity = function( self, ent )
		
			ent:SetAngles( Angle( 0, 90, 100 ) );
		
		end

		itemPanel:AddItem(spawnicon);
	end
	
	
	local musicPanel = vgui.Create( "DPanel" );
	parentX, parentY = adminProperty:GetSize();
	musicPanel:SetSize( parentX - 10, parentY - 10 );
	-- overwrite the paint function to make it a better color
	musicPanel.Paint = function()
		surface.SetDrawColor( 50, 50, 50, 255 );
		surface.DrawRect( 0, 0, cmdPanel:GetWide(), cmdPanel:GetTall() );
	end 
	
	parentX, parentY = musicPanel:GetSize();
	
	-- holds the list of songs in server's queue
	local songQueue = vgui.Create( "DComboBox", musicPanel );
	songQueue:SetSize( (parentX / 3) - 20, (parentY * 3 / 4 ) - 20 );
	songQueue:SetPos( parentX * 2 / 3, 20 );
	songQueue:EnableVerticalScrollbar( true );
	songQueue:SetMultiple( false );
	
	local count = 0;
	for k, v in pairs( SongTable ) do
		
		songQueue:AddItem( count .. " " .. v );
		count = count + 1;
	
	end
	
	-- button below queue, will clear the queue
	local clearQueue = vgui.Create( "DButton", musicPanel );
	clearQueue:SetSize( (parentX / 3) - 20, (parentY / 4 ) - 60 );
	clearQueue:SetPos( parentX * 2 / 3, parentY * 3 / 4 + 10 );
	clearQueue:SetText("Clear the server queue.");
	clearQueue.DoClick = function ( btn )
		Msg( "Running command: admin_clear_songs\n" );
		RunConsoleCommand( "admin_clear_songs" );
		songQueue:Clear();
		SongTable = {};
	end
	
	-- refresh the list of songs, due to umsgs taking time, will always be 1 refresh behind.
	-- refresh the song list after populating the list.
	local refreshButton = vgui.Create( "DButton", musicPanel );
	refreshButton:SetSize( 60, 30 );
	refreshButton:SetPos( parentX * 2 / 3 - 70, 20 );
	refreshButton:SetText("Refresh");
	refreshButton.DoClick = function ( btn )
	
		count = 0;
		songQueue:Clear();
		for k, v in pairs( SongTable ) do
		
			songQueue:AddItem( count .. " " .. v );
			count = count + 1;
	
		end
		
		SongTable = {};
		RunConsoleCommand( "admin_get_song_list" );
	
	end
	
	-- Stops all sounds
	local stopButton = vgui.Create( "DButton", musicPanel );
	stopButton:SetSize( 60, 30 );
	stopButton:SetPos( parentX * 2 / 3 - 70, 60 );
	stopButton:SetText("Stop music");
	stopButton.DoClick = function ( btn )
	
		RunConsoleCommand( "admin_stopsounds" );
	
	end
	
	-- Will resume sounds if possible
	local playButton = vgui.Create( "DButton", musicPanel );
	playButton:SetSize( 60, 30 );
	playButton:SetPos( parentX * 2 / 3 - 70, 100 );
	playButton:SetText("Start music");
	playButton.DoClick = function ( btn )
	
		RunConsoleCommand( "admin_resumeMusic" );
	
	end
	
	local option = "";
	-- select a song they wish to add
	local chooseSongButton = vgui.Create("DButton", musicPanel);
	chooseSongButton:SetSize( parentX / 6, parentY / 10 );
	chooseSongButton:SetPos( parentX / 6 - 100, parentY * 1 / 5 );
	chooseSongButton:SetText( "Select a Song" );
	chooseSongButton.DoClick = function ( btn )
		local MenuButtonOptions = DermaMenu();
		for k, v in pairs( AllSongs ) do
		
			MenuButtonOptions:AddOption( v, function()
														option = v;
														chooseSongButton:SetText( v );
												   end );
		end
		MenuButtonOptions:Open();
	end
	
	-- will submit their selected song to the server's queue
	local addSongButton = vgui.Create("DButton", musicPanel);
	addSongButton:SetSize( parentX / 6, parentY / 10 );
	addSongButton:SetPos( parentX / 6 - 100, parentY * 2 / 5 );
	addSongButton:SetText( "Add song to queue." );
	addSongButton.DoClick = function ( btn )
	
		if( string.len(option) != 0 ) then
			RunConsoleCommand( "admin_playtoall", option );
			option = "";
			chooseSongButton:SetText( "Choose another song?" );
			
			-- refresh their list for them
			SongTable = {};
			RunConsoleCommand( "admin_get_song_list" );
			
			-- give the umsgs 3 seconds, then refresh their list
			-- make it appear they're seeing this in real time (lawl)
			timer.Simple( 3, function()
								count = 0;
								songQueue:Clear();
								for k, v in pairs( SongTable ) do
		
									songQueue:AddItem( count .. " " .. v );
									count = count + 1;
	
								end
		
								SongTable = {};
								RunConsoleCommand( "admin_get_song_list" );
							end );
		end
	end
	
	-- vars I have to use
	--local SongTable = {};
	--local playingSong = "";
	--local AllSongs = nil;
	                                                 -- icon   horiz  vert   tooltip
	adminProperty:AddSheet( "   Commands   ", cmdPanel, false, false, false, false );
	adminProperty:AddSheet( "    Items    ", itemPanel, false, false, false, false );
	adminProperty:AddSheet( "    Music    ", musicPanel, false, false, false, false );
end
usermessage.Hook("openAdminMenu", openAdminMenu);


