local use_font = system.IsWindows() and "Tahoma" or "Verdana"
surface.CreateFont("MG_Theme_Close", {font = use_font, size = 13, weight = 1000})

surface.CreateFont("MG_Theme_ScrollbarButtons", {font = "Arial", size = 8, weight = 500})

MG_Theme = MG_Theme or {}

MG_Theme.Theme = {
	Frame = {},
	Button = {},
	ListView = {},
	DMenu = {},
	TextEntry = {},
	ComboBox = {},
	ScrollBar = {},
	MenuBar = {},
	ColorPatterns = {},
	CustomColorPattern = false,
}

local Theme = MG_Theme.Theme

Theme.PrimaryColor = {50, 150, 50}
Theme.DangerColor = {255, 60, 60}
Theme.WarningColor = {235, 235, 35}
Theme.SuccessColor = {40, 190, 85}
Theme.AdminColor = {255, 60, 60}
Theme.UserColor = {45, 175, 230}

function Theme:CreateColorPattern(name, tbl) -- Add custom color patterns, needs to be tables, not colors (It does override the above specified colors)
	Theme.ColorPatterns[name] = tbl

	--[[Example:
	MG_Theme.Theme.CreateColorPattern("example", {
		PrimaryColor = {255, 255, 255},
		DangerColor = {255, 0, 0},
	})
	]]
end

function Theme:ApplyColorPattern(name, menu) -- Applys a color pattern, until the specific menu element is removed
	Theme.CustomColorPattern = name

	if menu then
		local oldRemove = menu.OnRemove
		menu.OnRemove = function(self)
			if oldRemove then
				oldRemove(self)
			end

			Theme.CustomColorPattern = false
		end
	end
end

function Theme:GetCustomColor(self, typ, alpha)
	typ = typ.."Color"

	if Theme.CustomColorPattern and Theme.ColorPatterns[Theme.CustomColorPattern] and Theme.ColorPatterns[Theme.CustomColorPattern][typ] then
		return Theme:GetColor(Theme.ColorPatterns[Theme.CustomColorPattern][typ], alpha)
	end
end

function Theme:GetColor(color, alpha)
	return Color(color[1], color[2], color[3], alpha or color[4] or 255)
end

function Theme:GetPrimaryColor(alpha, self)
	return Theme:GetCustomColor(self, "Primary", alpha) or Theme:GetColor(Theme.PrimaryColor, alpha)
end

function Theme:GetDangerColor(alpha, self)
	return Theme:GetCustomColor(self, "Danger", alpha) or Theme:GetColor(Theme.DangerColor, alpha)
end

function Theme:GetWarningColor(alpha, self)
	return Theme:GetCustomColor(self, "Warning", alpha) or Theme:GetColor(Theme.WarningColor, alpha)
end

function Theme:GetSuccessColor(alpha, self)
	return Theme:GetCustomColor(self, "Success", alpha) or Theme:GetColor(Theme.SuccessColor, alpha)
end

function Theme:GetAdminColor(alpha, self)
	return Theme:GetCustomColor(self, "Admin", alpha) or Theme:GetColor(Theme.AdminColor, alpha)
end

function Theme:GetUserColor(alpha, self)
	return Theme:GetCustomColor(self, "User", alpha) or Theme:GetColor(Theme.UserColor, alpha)
end

function Theme:GetStatusColor(status)
	local tStatus = {
		Theme:GetSuccessColor(),
		Theme:GetWarningColor(),
		Theme:GetDangerColor()
	}

	if tStatus[status] then
		return tStatus[status]
	end

	return Theme:GetPrimaryColor()
end

timer.Simple(0, function()
	function DListView_Line:SetColumnColor(icol, ccol)
		self.ColumnColors = self.ColumnColors or {}
		self.ColumnColors[icol] = ccol
	end
end)

Theme.Frame.Paint = function(s, w, h)
	draw.RoundedBox(0, 0, 0, w, 24, Color(30, 30, 30, 255))
	draw.RoundedBox(0, 0, 23, w, 1, Theme:GetPrimaryColor(nil, self))
	draw.RoundedBox(0, 0, 24, w, h - 24, Color(50, 50, 50, 240))
end

Theme.Frame.PaintNoBG = function(s, w, h)
	draw.RoundedBox(0, 0, 0, w, 24, Color(30, 30, 30, 255))
	draw.RoundedBox(0, 0, 23, w, 1, Theme:GetPrimaryColor(nil, self))
	draw.RoundedBox(0, 0, 24, w, h - 24, Color(50, 50, 50, 255))
end

Theme.Frame.PaintOver = function(s, w, h)
	local w2, h2 = 35, 23
	local x2, y2  = s:GetPos()
	local mx, my = gui.MouseX() - x2, gui.MouseY() - y2
	local color = Color(150, 150, 150)
	draw.RoundedBox(0, w - 100, 0, 100, 23, Color(30, 30, 30, 255))
	if s:HasFocus() and ((mx > w - w2 - 1 and mx < w) and (my > -1 and my < 24)) then
		color = color_white
		draw.RoundedBox(0, w - w2 + 1, 1, w2 - 2, h2 - 2, s.DangerColor or Theme:GetDangerColor())
	end
	draw.SimpleText("r", "Marlett", w - (w2 / 2), h2 / 2, color, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
end

Theme.Frame.Setup = function(frame, noBG)
	frame.Paint = noBG and Theme.Frame.PaintNoBG or Theme.Frame.Paint
	frame.PaintOver = Theme.Frame.PaintOver
end
Theme.Frame.SetupTheme = Theme.Frame.Setup

Theme.ListView.Paint = function(s,w,h)
	draw.RoundedBox(0, 0, 0, w, h, Color(0, 0, 0, 150))
end

Theme.ListView.Setup = function(list)
	list.Paint = Theme.ListView.Paint
	list:SetHeaderHeight(25)
	list:SetDataHeight(25)
	for _, v in pairs(list.Lines) do
		for i, c in pairs(v.Columns) do
			function c:UpdateColours()
				local parent = self:GetParent()
				if (parent.ColumnColors and parent.ColumnColors[i]) then
					return self:SetColor(parent.ColumnColors[i])
				end
				if parent:IsSelected() then
					self:SetColor(color_white)
				else
					self:SetColor(Color(200, 200, 200))
				end
			end
			c:SetContentAlignment(5)
		end

	    function v:Paint(w, h)
	    	if self:IsSelected() then
	    		return draw.RoundedBox(0, 0, 0, w, list:GetDataHeight(), Theme:GetPrimaryColor(100, self))
			end
	    	if self.BackgroundColor then
	    		return draw.RoundedBox(0, 0, 0, w, list:GetDataHeight(), self.BackgroundColor)
	    	end
	    	if self:IsHovered() then
	    		return draw.RoundedBox(0, 0, 0, w, list:GetDataHeight(), Color(100, 100, 100, 200))
	    	end
		    draw.RoundedBox(0, 0, 0, w, list:GetDataHeight(), Color(45, 45, 45))
		    draw.RoundedBox(0, 0, 0, w, 1, Color(35, 35, 35))
	    end
	end
	for _, v in pairs(list.Columns) do
	    function v.Header:Paint(w, h)
	    	if self:IsHovered() then
	    		self:SetTextColor(Theme:GetPrimaryColor(nil, self))
	    		return draw.RoundedBox(0, 0, 0, w, h, Color(20, 20, 20, 255))
	    	end
	    	self:SetTextColor(Color(150, 150, 150))
	        draw.RoundedBox(0, 0, 0, w, h, Color(25, 25, 25, 255))
	    end
	end
	Theme.ScrollBar.Setup(list.VBar)
end
Theme.ListView.SetupTheme = Theme.ListView.Setup

Theme.DMenu.Setup = function(menu)
	menu.Paint = Theme.DMenu.Paint
	menu.fAddOption = menu.AddOption
	menu.fAddSubMenu = menu.AddSubMenu

	function menu:AddOption(...)
		local opt = menu:fAddOption(...)
		opt.Paint = Theme.DMenu.OptionPaint
		return opt
	end

	function menu:AddSubMenu(...)
		local submenu, parent = menu:fAddSubMenu(...)
		parent.Paint = Theme.DMenu.OptionPaint
		return submenu, parent
	end
end
Theme.DMenu.SetupTheme = Theme.DMenu.Setup

Theme.DMenu.Paint = function(s, w, h)
	draw.RoundedBox(0, 0, 0, w, h, Color(25, 25, 25))
	draw.RoundedBox(0, 2, 2, w - 4, h - 4, Color(30, 30, 30))
end

Theme.DMenu.AddOption = function(menu, ...)
	local option = menu:AddOption(...)
	option.Paint = Theme.DMenu.OptionPaint
	return option
end

Theme.DMenu.AddSubMenu = function(menu, ...)
	local submenu, parent = menu:AddSubMenu(...)
	parent.Paint = Theme.DMenu.OptionPaint
	return submenu, parent
end

Theme.DMenu.OptionPaint = function(s, w, h)
	if s:IsHovered() then
		draw.RoundedBox(0, 0, 0, w, h, Color(255, 255, 255, 1))
		draw.RoundedBox(0, 2, 2, w - 4, h- 4, Color(255, 255, 255, 1))
		s:SetTextColor(Theme:GetPrimaryColor(nil, self))
	else
		s:SetTextColor(Color(100, 100, 100))
	end
end

Theme.Button.Paint = function(s, w, h)
	if !s.OldColor and !s:IsHovered() then
		s.OldColor = s:GetTextColor()
	end

	local drawColor1 = Color(60, 60, 60)
	local drawColor2 = Color(35, 35, 35)

	local disabled = s:GetDisabled()
	if disabled then
		drawColor1.r = drawColor1.r + 15
		drawColor2.r = drawColor2.r + 15
	end

	draw.RoundedBox(0, 0, 0, w, h, drawColor1)
	draw.RoundedBox(0, 2, 2, w - 4, h - 4, drawColor2)

	if disabled then return end

	if s:IsHovered() then
		draw.RoundedBox(0, 0, 0, w, h, Color(150, 150, 150, 5))
		if !s.AddHovered then
			s:SetTextColor(color_white)
			s.AddHovered = true
		end
	else
		if s.OldColor then
			s:SetTextColor(s.OldColor)
		end
		s.AddHovered = false
	end
end 

Theme.Button.Setup = function(button) 
	button.Paint = Theme.Button.Paint
	button:SetTextColor(Color(150, 150, 150))
end
Theme.Button.SetupTheme = Theme.Button.Setup

Theme.TextEntry.Setup = function(text)
	text.Paint = Theme.TextEntry.Paint
end
Theme.TextEntry.SetupTheme = Theme.TextEntry.Setup

Theme.TextEntry.Paint = function(s, w, h)
	draw.RoundedBox(0, 0, 0, w, h, Color(45, 45, 45, 230))
	draw.RoundedBox(0, 2, 2, w - 4, h - 4, Color(35, 35, 35, 230))

	if s.GetPlaceholderText and s.GetPlaceholderColor and s:GetPlaceholderText() and s:GetPlaceholderText():Trim() != "" and s:GetPlaceholderColor() and (!s:GetText() or s:GetText() == "" ) then
		local oldText = s:GetText()
		local str = s:GetPlaceholderText()

		s:SetText(str)
		s:DrawTextEntryText(s:GetPlaceholderColor(), color_black, color_white)
		s:SetText(oldText)
		return
	end

	s:DrawTextEntryText(Color(255, 255, 255, 100), Color(0, 0, 0, 0), color_white)
end

Theme.ComboBox.Setup = function(combo)
	combo.Paint = Theme.ComboBox.Paint

	function combo:DoClick()
		if self:IsMenuOpen() then
			return self:CloseMenu()
		end
		self:OpenMenu()
		if IsValid(self.Menu) then
			self.Menu.Paint = Theme.DMenu.Paint
			local options = self.Menu:GetCanvas():GetChildren()
			for _, opt in ipairs(options) do
				opt.Paint = Theme.DMenu.OptionPaint
			end
		end
	end
end
Theme.ComboBox.SetupTheme = Theme.ComboBox.Setup

Theme.ComboBox.Paint = function(s, w, h)
	draw.RoundedBox(0, 0, 0, w, h, Color(45, 45, 45, 230))
	draw.RoundedBox(0, 2, 2, w - 4, h - 4, Color(35, 35, 35, 230))
	s:DrawTextEntryText(Color(255, 255, 255, 200), color_black, color_white)
end

Theme.ScrollBar.Setup = function(scroll)
	function scroll:Paint(w, h)
		draw.RoundedBox(0, 0, 0, w, h, Color(35, 35, 35))
	end

	function scroll.btnUp:Paint(w, h)
		draw.RoundedBox(0, 0, 0, w, h, Color(25, 25, 25))
		draw.RoundedBox(0, 0, h - 1, w, 1, Color(50, 50, 50))

		draw.DrawText("▲", "MG_Theme_ScrollbarButtons", w / 2 - 4, h / 2 - 5, color_white)
	end

	function scroll.btnDown:Paint(w,h)
		draw.RoundedBox(0, 0, 0, w, h, Color(25, 25, 25))
		draw.RoundedBox(0, 0, 0, w, 1, Color(50, 50, 50))

		draw.DrawText("▼", "MG_Theme_ScrollbarButtons", w / 2 - 4, h / 2 - 5, color_white)
	end

	function scroll.btnGrip:Paint(w, h)
		draw.RoundedBox(0, 0, 0, w, h, Color(25, 25, 25))
	end
end
Theme.ScrollBar.SetupTheme = Theme.ScrollBar.Setup

Theme.MenuBar.Paint = function(s, w, h)
	draw.RoundedBox(0, 0, 0, w, h, Color(30, 30, 30))
	draw.RoundedBox(0, 0, h - 1, w, 1, Color(80, 80, 80))
end

Theme.MenuBar.Setup = function(bar)
	bar.Paint = Theme.MenuBar.Paint
	for _, menu in pairs(bar.Menus) do
		menu.Paint = Theme.DMenu.Paint
	end
end
Theme.MenuBar.SetupTheme = Theme.MenuBar.Setup