surface.CreateFont('PS_Heading', { font = 'coolvetica', size = 64 })
surface.CreateFont('PS_Heading2', { font = 'coolvetica', size = 24 })
surface.CreateFont('PS_Heading3', { font = 'coolvetica', size = 19 })

local ALL_ITEMS = 1
local OWNED_ITEMS = 2
local UNOWNED_ITEMS = 3

ICON_COLORS = {}
ICON_COLORS["Crimson"] = Color( 162, 0, 37, 255 )
ICON_COLORS["Emerald"] = Color( 0, 138, 0, 255 )
ICON_COLORS["Green"] = Color( 96, 169, 23, 255 )
ICON_COLORS["Indigo"] = Color( 106, 0, 255, 255 )
ICON_COLORS["Cyan"] = Color( 27, 161, 226, 255 )
ICON_COLORS["Olive"] = Color( 109, 135, 100, 255 )
ICON_COLORS["Teal"] = Color( 0, 171, 169, 255 )

local function BuildItemMenu(menu, ply, itemstype, callback)
	local plyitems = ply:PS_GetItems()
	
	for category_id, CATEGORY in pairs(PS.Categories) do
		
		local catmenu = menu:AddSubMenu(CATEGORY.Name)
		
		table.SortByMember(PS.Items, "Name", function(a, b) return a > b end)
		
		for item_id, ITEM in pairs(PS.Items) do
			if ITEM.Category == CATEGORY.Name then
				if itemstype == ALL_ITEMS or (itemstype == OWNED_ITEMS and plyitems[item_id]) or (itemstype == UNOWNED_ITEMS and not plyitems[item_id]) then
					catmenu:AddOption(ITEM.Name, function() callback(item_id) end)
				end
			end
		end
	end
end

local PANEL = {}

function PANEL:Init()

	surface.PlaySound( "ambient/levels/canals/windchime2.wav" )

	self:SetSize( math.Clamp( 1200, 0, ScrW() ), math.Clamp( 768, 0, ScrH() ) )
	self:SetPos((ScrW() / 2) - (self:GetWide() / 2), (ScrH() / 2) - (self:GetTall() / 2))
	
	// TOP MENU
	local topMenu = vgui.Create( 'DPanel', self )
	topMenu:Dock( TOP )
	topMenu:SetSize( 300, 72 )
	topMenu.Paint = function()
		surface.SetDrawColor( 0, 0, 0, 100 )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
	end
	
	// PLAYER INFO
	local plyInfo = vgui.Create( 'DPSPlayerInfo', self )
	plyInfo:SetSize( 300, 72 )
	
	-- close button
	local closeButton = vgui.Create('DButton', topMenu )
	closeButton:SetFont('marlett')
	closeButton:SetText('r')
	closeButton:SetColor(Color(255, 255, 255))
	closeButton:SetSize(15, 15)
	closeButton:SetDrawBackground(false)
	closeButton:Dock( RIGHT )
	closeButton:DockMargin( 6, 10, 6, 50 )
	closeButton.DoClick = function()
		PS:ToggleMenu()
	end
	
	local infoLbl = vgui.Create( 'DLabel', topMenu )
	infoLbl:Dock( TOP )
	infoLbl:SetSize( 500, 72 )
	infoLbl:DockMargin( 50, 0, 20, 0 )
	infoLbl:SetFont( "DermaLarge" )
	infoLbl:SetText( "PointShop by _Undefined, skin design by [G-S] Gizmoandsmudge" )
	infoLbl:SetTextColor( Color( 255, 255, 255, 255 ) )
	infoLbl:SetContentAlignment( 6 )
	
	// LEFT MENU
	local leftMenu = vgui.Create( 'DPanelList', self )
	leftMenu:Dock( LEFT )
	leftMenu:SetSize( 300, self:GetTall() )
	leftMenu:SetPadding( 4 )
	leftMenu:SetSpacing( 4 )
	leftMenu:EnableVerticalScrollbar( true )
	leftMenu.Paint = function()
		surface.SetDrawColor( 0, 0, 0, 100 )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
	end
	
	for _, category in pairs( PS.Categories ) do
	
		local catPanel = vgui.Create( "DPSCategory" )
		catPanel:SetSize( 300, 64 )
		catPanel:SetPanelText( category.Name, category.Desc or "" )
		catPanel.BackColor = category.BackgroundColor or ICON_COLORS["Teal"]
		if ( category.Icon ) then
			catPanel:SetIcon( category.Icon )
		end
		catPanel.Items = {}
		
		for _, item in pairs(PS.Items) do
			if item.Category == category.Name then
				table.insert( catPanel.Items, item )
			end
		end
	
		leftMenu:AddItem( catPanel )
	end
	
	local scrollPanel = vgui.Create( "DScrollPanel", self )
	scrollPanel:Dock( LEFT )
	scrollPanel:SetSize( self:GetWide() - 600, 500 )
	scrollPanel:DockMargin( 0, 0, 300, 0 )
	scrollPanel.Paint = function()
		surface.SetDrawColor( 255, 255, 255, 0 )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
	end
	
	PS_ItemPanel = vgui.Create( "DIconLayout", scrollPanel )
	PS_ItemPanel:SetSize( scrollPanel:GetWide() - 20, scrollPanel:GetTall() - 20 )
	PS_ItemPanel:SetPos( 10, 10 )
	PS_ItemPanel:SetSpaceX( 10 )
	PS_ItemPanel:SetSpaceY( 10 )
	PS_ItemPanel.Paint = function()
		surface.SetDrawColor( 255, 255, 255, 0 )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
	end

	/*
	local tabs = vgui.Create('DPropertySheet', self)
	
	if PS.Config.DisplayPreviewInMenu then
		tabs:DockMargin(10, 80, 410, 10)
	else
		tabs:DockMargin(10, 80, 10, 10)
	end
	tabs:Dock(FILL)
	
	tabs:SetSize(self:GetWide() - 60, self:GetTall() - 150)
	tabs:SetPos((self:GetWide() / 2) - (tabs:GetWide() / 2), 120)
	
	-- sorting
	local categories = {}
	
	for _, i in pairs(PS.Categories) do
		table.insert(categories, i)
	end
	
	table.sort(categories, function(a, b) 
		if a.Order == b.Order then 
			return a.Name < b.Name
		else
			return a.Order < b.Order
		end
	end)
	
	local items = {}
	
	for _, i in pairs(PS.Items) do
		table.insert(items, i)
	end
	
	table.SortByMember(items, "Name", function(a, b) return a > b end)
	
	-- items
	for _, CATEGORY in pairs(categories) do
		if CATEGORY.AllowedUserGroups and #CATEGORY.AllowedUserGroups > 0 then
			if not table.HasValue(CATEGORY.AllowedUserGroups, LocalPlayer():PS_GetUsergroup()) then
				continue
			end
		end
		
		if CATEGORY.CanPlayerSee then
			if not CATEGORY:CanPlayerSee(LocalPlayer()) then
				continue
			end
		end
		
		local ShopCategoryTab = vgui.Create('DPanel')
		
		local DScrollPanel = vgui.Create('DScrollPanel', ShopCategoryTab)
		DScrollPanel:Dock(FILL)
		
		local ShopCategoryTabLayout = vgui.Create('DIconLayout', DScrollPanel)
		ShopCategoryTabLayout:Dock(FILL)
		ShopCategoryTabLayout:SetBorder(10)
		ShopCategoryTabLayout:SetSpaceX(10)
		ShopCategoryTabLayout:SetSpaceY(10)
		
		DScrollPanel:AddItem(ShopCategoryTabLayout)
		
		for _, ITEM in pairs(items) do
			if ITEM.Category == CATEGORY.Name then
				local model = vgui.Create('DPointShopItem')
				model:SetData(ITEM)
				model:SetSize(126, 126)
				
				ShopCategoryTabLayout:Add(model)
			end
		end
		
		tabs:AddSheet(CATEGORY.Name, ShopCategoryTab, 'icon16/' .. CATEGORY.Icon .. '.png', false, false, '')
	end
	*/
	
	if (PS.Config.AdminCanAccessAdminTab and LocalPlayer():IsAdmin()) or (PS.Config.SuperAdminCanAccessAdminTab and LocalPlayer():IsSuperAdmin()) then
	
		local adminButton = vgui.Create( "DButton", topMenu )
		adminButton:SetPos( 304, 4 )
		adminButton:SetSize( 64, 64 )
		adminButton:SetText( "Admin" )
		adminButton:SetTextColor( Color( 255, 255, 255, 255 ) )
		adminButton:SetFont( "Trebuchet24" )
		adminButton.Paint = function()
			surface.SetDrawColor( ICON_COLORS["Cyan"] )	
			surface.DrawRect( 0, 0, adminButton:GetWide(), adminButton:GetTall() )
			
			if adminButton.Hover then
				surface.SetDrawColor( 255, 255, 255, 50 )
				surface.DrawRect( 0, 0, adminButton:GetWide(), adminButton:GetTall() )
			end
		end
		adminButton.OnCursorEntered = function() adminButton.Hover = true end
		adminButton.OnCursorExited = function() adminButton.Hover = false end
		adminButton.DoClick = function()
			
			if IsValid( self.AdminTab ) then
				return
			end
			
			self.AdminTab = vgui.Create('DPanel')
			self.AdminTab:SetSize( 500, 700 )
			self.AdminTab:Center()
			self.AdminTab.Paint = function()
				Derma_DrawBackgroundBlur( self.AdminTab )
				surface.SetDrawColor( 30, 30, 30, 200 )
				surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
			end
			
			local CloseAdmin = vgui.Create( 'DButton', self.AdminTab )
			CloseAdmin:Dock( BOTTOM )
			CloseAdmin:SetSize( 200, 32 )
			CloseAdmin:DockMargin( 10, 10, 10, 10 )
			CloseAdmin:SetText( "Close Administration" )
			CloseAdmin:SetFont( "HudHintTextLarge" )
			CloseAdmin:SetTextColor( Color( 255, 255, 255, 255 ) )
			CloseAdmin.DoClick = function()
				if ( self.AdminTab ) then
					self.AdminTab:Remove()
				end
			end
			CloseAdmin.Paint = function()
				surface.SetDrawColor( ICON_COLORS["Cyan"] )	
				surface.DrawRect( 0, 0, CloseAdmin:GetWide(), CloseAdmin:GetTall() )
				
				if CloseAdmin.Hover then
					surface.SetDrawColor( 255, 255, 255, 50 )
					surface.DrawRect( 0, 0, CloseAdmin:GetWide(), CloseAdmin:GetTall() )
				end
			end
			CloseAdmin.OnCursorEntered = function() CloseAdmin.Hover = true end
			CloseAdmin.OnCursorExited = function() CloseAdmin.Hover = false end
			
			
			local ClientsList = vgui.Create('DListView', self.AdminTab)
			ClientsList:DockMargin(10, 10, 10, 0)
			ClientsList:Dock(FILL)
			ClientsList.Paint = function()
				
				surface.SetDrawColor( 240, 240, 240, 255 )
				surface.DrawRect( 0, 0, ClientsList:GetWide(), ClientsList:GetTall() )
			
			end
			
			ClientsList:SetMultiSelect(false)
			ClientsList:AddColumn('Name')
			ClientsList:AddColumn('Points'):SetFixedWidth(60)
			ClientsList:AddColumn('Items'):SetFixedWidth(60)
			
			ClientsList.OnClickLine = function(parent, line, selected)
				local ply = line.Player
				
				local menu = DermaMenu()
				
				menu:AddOption('Set Points...', function()
					Derma_StringRequest(
						"Set Points for " .. ply:GetName(),
						"Set points to...",
						"",
						function(str)
							if not str or not tonumber(str) then return end
							
							net.Start('PS_SetPoints')
								net.WriteEntity(ply)
								net.WriteInt(tonumber(str), 32)
							net.SendToServer()
						end
					)
				end)
				
				menu:AddOption('Give Points...', function()
					Derma_StringRequest(
						"Give Points to " .. ply:GetName(),
						"Give points...",
						"",
						function(str)
							if not str or not tonumber(str) then return end
							
							net.Start('PS_GivePoints')
								net.WriteEntity(ply)
								net.WriteInt(tonumber(str), 32)
							net.SendToServer()
						end
					)
				end)
				
				menu:AddOption('Take Points...', function()
					Derma_StringRequest(
						"Take Points from " .. ply:GetName(),
						"Take points...",
						"",
						function(str)
							if not str or not tonumber(str) then return end
							
							net.Start('PS_TakePoints')
								net.WriteEntity(ply)
								net.WriteInt(tonumber(str), 32)
							net.SendToServer()
						end
					)
				end)
				
				menu:AddSpacer()
				
				BuildItemMenu(menu:AddSubMenu('Give Item'), ply, UNOWNED_ITEMS, function(item_id)
					net.Start('PS_GiveItem')
						net.WriteEntity(ply)
						net.WriteString(item_id)
					net.SendToServer()
				end)
				
				BuildItemMenu(menu:AddSubMenu('Take Item'), ply, OWNED_ITEMS, function(item_id)
					net.Start('PS_TakeItem')
						net.WriteEntity(ply)
						net.WriteString(item_id)
					net.SendToServer()
				end)
				
				menu:Open()
			end
			
			self.ClientsList = ClientsList
		
		end
	
	end
	
	-- preview panel

	local preview
	if PS.Config.DisplayPreviewInMenu then

		preview = vgui.Create('DPanel', self)
		preview:Dock( RIGHT )
		preview:SetSize( 300, self:GetTall() )
		preview.Paint = function()
			surface.SetDrawColor( 0, 0, 0, 50 )
			surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
		end
		
		local previewpanel = vgui.Create('DPointShopPreview', preview)
		previewpanel:Dock(FILL)
	end
	
	-- give points button
	
	if PS.Config.CanPlayersGivePoints then
		local givebutton = vgui.Create('DButton', preview or self)
		givebutton:SetText("Give Points")
		givebutton:SetTextColor( Color( 255, 255, 255, 255 ) )
		if PS.Config.DisplayPreviewInMenu then
			givebutton:DockMargin(8, 8, 8, 8)
		else
			givebutton:DockMargin(8, 0, 8, 8)
		end
		givebutton:SetFont( "HudHintTextLarge" )
		givebutton:Dock(BOTTOM)
		givebutton.DoClick = function()
			vgui.Create('DPointShopGivePoints')
		end
		givebutton.Paint = function()
			surface.SetDrawColor( ICON_COLORS["Cyan"] )	
			surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
			
			if self.Hover then
				surface.SetDrawColor( 255, 255, 255, 50 )
				surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
			end
		end
		givebutton.OnCursorEntered = function() self.Hover = true end
		givebutton.OnCursorExited = function() self.Hover = false end
	end
end

function PANEL:Think()
	if IsValid( self.AdminTab ) and self.ClientsList then
		local lines = self.ClientsList:GetLines()
		
		for _, ply in pairs(player.GetAll()) do
			local found = false
			
			for _, line in pairs(lines) do
				if line.Player == ply then
					found = true
				end
			end
			
			if not found then
				self.ClientsList:AddLine(ply:GetName(), ply:PS_GetPoints(), table.Count(ply:PS_GetItems())).Player = ply
			end
		end
		
		for i, line in pairs(lines) do
			if IsValid(line.Player) then
				local ply = line.Player
				
				line:SetValue(1, ply:GetName())
				line:SetValue(2, ply:PS_GetPoints())
				line:SetValue(3, table.Count(ply:PS_GetItems()))
			else
				self.ClientsList:RemoveLine(i)
			end
		end
	end
end

function PANEL:Paint()
	Derma_DrawBackgroundBlur(self)
	
	if ( SelectedCategory ) && ( SelectedCategory.BackColor ) then
		surface.SetDrawColor( Color( SelectedCategory.BackColor.r, SelectedCategory.BackColor.g, SelectedCategory.BackColor.b, 40 ))
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
	end
	
	surface.SetDrawColor( Color( 30, 30, 30, 180 ))
	surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
end

vgui.Register('DPointShopMenu', PANEL)

// Player Information Panel

local PANEL = {}

function PANEL:Init()

	self.Avatar = vgui.Create( "AvatarImage", self )
	self.Avatar:SetSize( 64, 64 )
	self.Avatar:Dock( LEFT )
	self.Avatar:DockMargin( 4, 4, 0, 4 )
	self.Avatar:SetPlayer( LocalPlayer(), 64 )
	
	self.NameLbl = vgui.Create( "DLabel", self )
	self.NameLbl:SetFont( "Trebuchet24" )
	self.NameLbl:Dock( TOP )
	self.NameLbl:SetSize( 40, 26 )
	self.NameLbl:DockMargin( 0, 6, 6, 3 )
	self.NameLbl:SetText( "  " .. string.upper( LocalPlayer():Name() ) )
	self.NameLbl:SetTextColor( Color( 255, 255, 255, 255 ) )
	self.NameLbl.Paint = function()
		surface.SetDrawColor( 0, 0, 0, 150 )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
	end
	
	self.PointsLbl = vgui.Create( "DLabel", self )
	self.PointsLbl:SetFont( "Trebuchet24" )
	self.PointsLbl:Dock( TOP )
	self.PointsLbl:SetSize( 40, 26 )
	self.PointsLbl:DockMargin( 0, 3, 6, 6 )
	self.PointsLbl:SetText( "  PTs: " .. LocalPlayer():PS_GetPoints() )
	self.PointsLbl:SetTextColor( Color( 255, 255, 255, 255 ) )
	self.PointsLbl.Paint = function()
		surface.SetDrawColor( 0, 0, 0, 150 )
		surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
	end

end

function PANEL:Paint()

	surface.SetDrawColor( 0, 0, 0, 50 )
	surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )

end

function PANEL:Think()
	
	self.PointsLbl:SetText( "  PTs: " .. LocalPlayer():PS_GetPoints() )
	
end

vgui.Register( 'DPSPlayerInfo', PANEL )

local PANEL = {}

function PANEL:Init()
	
	self.BackColor = Color( 200, 50, 50, 200 )
	self.mult = 0;
	self:SetText( "" )
	
	self.NameLbl = vgui.Create( "DLabel", self )
	self.NameLbl:SetFont( "DermaLarge" )
	self.NameLbl:Dock( TOP )
	self.NameLbl:DockMargin( 6, 6, 6, 6 )
	self.NameLbl:SetText( "Main Text" )
	self.NameLbl:SizeToContents()
	self.NameLbl:SetTextColor( Color( 255, 255, 255, 255 ) )
	
	self.DescLbl = vgui.Create( "DLabel", self )
	self.DescLbl:SetFont( "HudHintTextLarge" )
	self.DescLbl:Dock( BOTTOM )
	self.DescLbl:DockMargin( 6, 0, 6, 6 )
	self.DescLbl:SetText( "Description Text" )
	self.NameLbl:SetTextColor( Color( 255, 255, 255, 255 ) )

end

function PANEL:SetPanelText( mainText, descText )

	self.NameLbl:SetText( mainText )
	self.DescLbl:SetText( descText )

end

function PANEL:SetIcon( icon )

	self.icon = Material( 'icon16/' .. icon .. '.png' )

end

function PANEL:OnCursorEntered()

	surface.PlaySound( "UI/buttonrollover.wav" )
	self.Hover = true;

end

function PANEL:OnCursorExited()

	self.Hover = false;

end

function PANEL:OnMousePressed()

	SelectedCategory = self;

	surface.PlaySound( "UI/buttonclick.wav" )
	if ( self.Items ) and ( PS_ItemPanel ) then
	
		PS_ItemPanel:Clear()
		
		for _, item in pairs( self.Items ) do
		
			local itemPanel = vgui.Create( 'DPointShopItem' )
			itemPanel:SetData( item )
			itemPanel:SetSize( 136, 136 )
			
			PS_ItemPanel:Add( itemPanel )
		end
	end

end

function PANEL:Paint()

	if ( self.Hover ) then
		self.mult = math.Approach( self.mult, 0.2, FrameTime() / 1.5 )
	else
		if not ( SelectedCategory == self ) then
			self.mult = math.Approach( self.mult, 0, FrameTime() / 1.5 )
		end
	end
	
	surface.SetDrawColor( self.BackColor )
	surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
	
	if ( self.icon ) then
		surface.SetMaterial( self.icon )
		surface.SetDrawColor( 0, 0, 0, 70 )
		surface.DrawTexturedRect( self:GetWide() - 20, 4, 16, 16 )
	end
	
	surface.SetDrawColor( Color( 255, 255, 255, 255 * self.mult ) )
	surface.DrawRect( 0, 0, self:GetWide(), self:GetTall() )
	
	draw.TexturedQuad
	{
		texture = surface.GetTextureID "gui/gradient",
		color = Color( 0, 0, 0, 60 ),
		x = 1,
		y = 1,
		w = self:GetWide() - 2,
		h = self:GetTall() - 2
	}
	
end

vgui.Register( 'DPSCategory', PANEL, "DButton" )
