timer.Simple(1, function()
	MG_CarDealer.LoadTuner()
end)

function MG_CarDealer.InitTuneData(tunedata)
	tunedata.Color = tunedata.Color or Color(255, 255, 255, 255)
end

local function DuplicateElements(ent, id)
	local motherdata = ent.TuneData.Elements[id]
	if !motherdata then return end
	for _, v in pairs(MG_CarDealer_Tuners or {}) do
		if v.Type == motherdata.Type then
			v.Func(ent, nil, table.Copy(motherdata))
			return
		end
	end
end

local function IsValidElement(typ)
	for _, b in pairs(MG_CarDealer_Tuners or {}) do
		if b.LuaName == typ then
			return b
		end
	end
end

local function AddUpgradeButton(self, name, id, data, cost, desc, sellprice)
	local ply = LocalPlayer()
	local Button = vgui.Create("CarDealer_DSWButton")
	Button:SetTooltip(name.."\n"..desc.."\n\nKosten: $"..string.Comma(cost).."\nKauf möglich: "..(ply:canAfford(cost) and "Ja" or "Nein"))
	Button:SetTall(20)
	Button:SetTexts(name)
	Button.BoarderCol = Color(0, 0, 0, 0)
	Button.Think = function(slf)
		if tonumber(data[id]) == 2 then
			slf.TextCol = Color(255, 255, 0, 255)
		elseif data[id] and data[id] != "NULL" then
			slf.TextCol = Color(0, 255, 0, 255)
		elseif ply:canAfford(cost) then
			slf.TextCol = Color(255, 100, 0, 255)
		else
			slf.TextCol = Color(255, 0, 0, 255)
		end
	end
	Button.DoClick = function(slf)
		surface.PlaySound("ui/buttonclick.wav")
		local menu = DermaMenu(slf)
		menu:SetSkin("CarDealer_ButtonMenu")
		if !data[id] or data[id] == "NULL" then
			menu:AddOption("Kaufen ($"..string.Comma(cost)..")", function()
				surface.PlaySound("ui/buttonclick.wav")
				if ply:canAfford(cost) then
					MG_CarDealer.ShowAsker("Bist du dir sicher, dass du "..name.." für $"..string.Comma(cost).." kaufen möchtest?", function()
						MG_CarDealer.BuyUpgrade(data["id"], id)
						data[id] = true
					end)
				else
					MG_CarDealer.ShowNotice("Du hast nicht genug Geld für diese Verbesserung!")
				end
			end):SetIcon(ply:canAfford(cost) and "icon16/basket_go.png" or "icon16/basket_error.png")
		else
			if tonumber(data[id]) == 2 then
				menu:AddOption("Aktivieren", function()
					surface.PlaySound("ui/buttonclick.wav")
					MG_CarDealer.ChangeUpgrade(data["id"], id, true)
					data[id] = 1
				end):SetIcon("icon16/tick.png")
			else
				local activate = menu:AddOption("Deaktivieren", function()
					surface.PlaySound("ui/buttonclick.wav")
					MG_CarDealer.ChangeUpgrade(data["id"], id, false)
					data[id] = 2
				end):SetIcon("icon16/cross.png")
			end
			menu:AddOption("Verkaufen ($"..string.Comma(sellprice)..")", function()
				surface.PlaySound("ui/buttonclick.wav")
				MG_CarDealer.ShowAsker("Bist du dir sicher, dass du "..name.." für $"..string.Comma(sellprice).." verkaufen möchtest?", function()
					MG_CarDealer.SellUpgrade(data["id"], id)
					data[id] = nil
				end)
			end):SetIcon("icon16/money_dollar.png")
		end
		menu:Open()
	end
	self.UpgradeList:AddItem(Button)
	return Button
end

function MG_CarDealer.LoadTuner()
	function MG_CarDealerPanel_Tuner:DuplicateElement(id)
		local motherdata = self.TuneData.Elements[id]
		if !motherdata then return end
		for _,v in pairs(MG_CarDealer_Tuners or {}) do
			if v.LuaName == motherdata.Type then
				local cur = 0
				for _,a in pairs(self.TuneData.Elements or {}) do
					if a.Type == v.LuaName then
						cur = cur + 1
					end
				end
				if cur >= v.Max then
					MG_CarDealer.ShowNotice("Du hast das maximale Limit an Elementen dieser Art erreicht!")
					return
				end
				v:AddOnTunerPanel(self.TuneData, self, nil, nil, true, motherdata.Vars)
				return
			end
		end
	end

	function MG_CarDealerPanel_Tuner:ApplyTuneData2Preview(tunedata)
		self.BGBackGroundPanel:SetTuneData(tunedata or self.TuneData)
	end

	function MG_CarDealerPanel_Tuner:AddElement()
		local tunedata = self.TuneData
		local car = self.BGBackGroundPanel:GetCarEntity()
		local BG = vgui.Create("CarDealer_DSWButton")
		BG:SetTall(20)
		BG:SetTexts("Haupt")
		BG.BoarderCol = Color(0, 0, 0, 0)
		BG.PaintBackGround = function(slf)
			if self.SelectedButton == slf then
				surface.SetDrawColor(Color(0, 50, 150, 100))
				surface.DrawRect(0, 0, slf:GetWide(), slf:GetTall())
			end
		end
		self.ElementList:AddItem(BG)
		BG.Click = function(slf)
			self.SelectedButton = BG
			local List = self.ToolList
			List:Clear()
			List:AddText("Farbe auswählen:")
			local color = vgui.Create("DColorMixer")
			color:SetSize(List:GetWide(), 200)
			color:SetColor(color_white)
			color.ValueChanged = function(slf,color)
				tunedata.Color = color
				self:ApplyTuneData2Preview()
			end
			color:SetColor(tunedata.Color or color_white)
			List:AddItem(color)
			if IsValid(car) then
				local skin_count = car:SkinCount() - 1
				if !self.SelectedCarData.NoSkin and math.max(0, skin_count) != 0 then
					List:AddSubTitle("Aussehen")
					local Slider = List:CreateSlider("Möglichkeit", 0, skin_count, 0)
					Slider:SetValue(tunedata.SkinNumber or 0)
					Slider.OnValueChanged = function(slf,val)
						tunedata.SkinNumber = val
						car:SetSkin(val)
					end
				end
				local cnt = 0
				for i=0, car:GetNumBodyGroups() -1 do
					if (car:GetBodygroupCount(i) <= 1) then continue end
					cnt = cnt + 1
				end
				if !self.SelectedCarData.NoBodygroup and cnt > 0 then
					List:AddSubTitle("Körpergruppen")
					tunedata.BodyGroups = tunedata.BodyGroups or {}
					for i=0, car:GetNumBodyGroups() -1 do
						if (car:GetBodygroupCount(i) <= 1) then continue end
						if (self.SelectedCarData.BodygroupBlacklist and self.SelectedCarData.BodygroupBlacklist[car:GetBodygroupName(i)]) then continue end
						local Slider = List:CreateSlider(car:GetBodygroupName(i), 0, car:GetBodygroupCount(i) - 1, 0)
						Slider:SetValue(tunedata.BodyGroups[i] or 0)
						Slider.OnValueChanged = function(slf, val)
							tunedata.BodyGroups[car:FindBodygroupByName(car:GetBodygroupName(i))] = val
							car:SetBodygroup(car:FindBodygroupByName(car:GetBodygroupName(i)), val)
						end
					end
				end
			end
		end
	end

	function MG_CarDealerPanel_Tuner:BuildTuner(num, data, tunedata, selectedcardata, olddata)
		local ply = LocalPlayer()
		MG_CarDealer.InitTuneData(tunedata)
		self.TuneData = tunedata
		self.BuilderBGPanel = self:ReBuildCanvas()
		self.BuilderBGPanel.Name = "Konfiguration"
		self.BuilderBGPanel.CantSpin = true
		self.SelectedCarData = selectedcardata
		self.BuilderBGPanel.Paint = function(slf)
			draw.SimpleText("Du hast $"..string.Comma(ply:getDarkRPVar("money"))..".", "MG_CarDealer_TrebOut_S25", 60, self:GetTall() - 80, color_white)
		end
		local AcceptButton = vgui.Create("CarDealer_DSWButton", self.BuilderBGPanel)
		AcceptButton:SetSize(200, 50)
		AcceptButton:SetPos(self.BuilderBGPanel:GetWide() / 2 - AcceptButton:GetWide() / 2 - 150, self.BuilderBGPanel:GetTall() - AcceptButton:GetTall())
		AcceptButton:SetTexts("Änderungen übernehmen")
		AcceptButton.Click = function(slf)
			MG_CarDealer.UpdateTuneData(data.id, self.TuneData)
			self.ActiveWindow = "inv"
			self:BuildInventory(num, data)
		end
		local DeclineButton = vgui.Create("CarDealer_DSWButton", self.BuilderBGPanel)
		DeclineButton:SetSize(200, 50)
		DeclineButton:SetPos(self.BuilderBGPanel:GetWide() / 2 - DeclineButton:GetWide() / 2 + 150, self.BuilderBGPanel:GetTall() - DeclineButton:GetTall())
		DeclineButton:SetTexts("Änderungen verwerfen")
		DeclineButton.Click = function(slf)
			self.ActiveWindow = "inv"
			self:BuildInventory(num, data)
			for k in pairs(tunedata) do
				tunedata[k] = nil
			end
			for k, v in pairs(olddata.tunedata or {}) do
				tunedata[k] = v
			end
			self:ApplyTuneData2Preview()
		end
		local UpgradeListBG = vgui.Create("DPanel", self.BuilderBGPanel)
		UpgradeListBG:SetPos(self.BuilderBGPanel:GetWide() - 220, self.BuilderBGPanel:GetTall() - 370)
		UpgradeListBG:SetSize(220, 160)
		UpgradeListBG.Paint = function(slf)
			surface.SetDrawColor(Color(20, 20, 20, 253))
			surface.DrawRect(0, 0, slf:GetWide(), slf:GetTall())
			surface.SetDrawColor(Color(40, 40, 40, 255))
			surface.DrawRect(0, 0, slf:GetWide(), 20)
			draw.SimpleText("Verfügbare Verbesserungen", "MG_CarDealer_TrebOut_S20", 10, 1, color_white)
		end
		self.UpgradeList = vgui.Create("DPanelList", UpgradeListBG)
		self.UpgradeList:SetPos(5, 25)
		self.UpgradeList:SetSize(UpgradeListBG:GetWide() - 10, UpgradeListBG:GetTall() - 30)
		self.UpgradeList:EnableHorizontal(false)
		self.UpgradeList:EnableVerticalScrollbar(true)
		self.UpgradeList:MG_CarDealer_PaintListBarC()
		self.UpgradeList.Paint = function(slf)
		end
		if !selectedcardata.UnlimitedHealth then
			AddUpgradeButton(self, "Autoversicherung", "insurance", data, math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.InsuranceCost), "Repariert dein Auto automatisch bei Einlieferung in die Garage, sofern die Gesundheit nicht unter "..math.floor(MG_CarDealerConfig.InsurancePercentage * 100).."% gefallen ist.\nSollte die Gesundheit des Autos unter "..math.floor(MG_CarDealerConfig.InsurancePercentage * 100).."% gefallen sein, muss es erst wieder vollständig repariert werden, bevor die Autoversicherung wieder aktiv wird.", math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.InsuranceCost * MG_CarDealerConfig.UpgradeSellWorth))
			AddUpgradeButton(self, "Autopanzerung", "armored", data, math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.ArmorUpgradeCost), "Erhöht Autopanzerung um "..math.floor((1 - MG_CarDealerConfig.ArmorUpgradePercentage) * 100).."%.", math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.ArmorUpgradeCost * MG_CarDealerConfig.UpgradeSellWorth))
		end
		if !selectedcardata.UnlimitedFuel then
			AddUpgradeButton(self, "Vergrößerter Tank", "extrafuel", data, math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.FuelUpgradeCost), "Erhöht Tankvolumen um "..math.floor((1 - MG_CarDealerConfig.FuelUpgradePercentage) * 100).."%.", math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.FuelUpgradeCost * MG_CarDealerConfig.UpgradeSellWorth))
		end
		if !selectedcardata.NoWheels then
			AddUpgradeButton(self, "Schusssichere Reifen", "bulletproof", data, math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.BulletProofCost), "Macht deine Reifen gegen jeglichen Schaden immun.", math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.BulletProofCost * MG_CarDealerConfig.UpgradeSellWorth))
		end
		AddUpgradeButton(self, "Verbessertes Schloss", "lock", data, math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.LockCost), "Verlängert die benötigte Zeit, um das Autoschloss zu knacken um 30 Sekunden.", math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.LockCost * MG_CarDealerConfig.UpgradeSellWorth))
		AddUpgradeButton(self, "Autoalarmanlage", "vehiclealarm", data, math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.AlarmCost), "Bei Aufknacken des Autoschlosses, aktiviert sich die intere Alarmanlage.", math.ceil(selectedcardata.CarPrice * MG_CarDealerConfig.AlarmCost * MG_CarDealerConfig.UpgradeSellWorth))
		local ElementListBG = vgui.Create("DPanel", self.BuilderBGPanel)
		ElementListBG:SetPos(self.BuilderBGPanel:GetWide() - 220, self.BuilderBGPanel:GetTall() - 220)
		ElementListBG:SetSize(220, 220)
		ElementListBG.Paint = function(slf)
			surface.SetDrawColor(Color(20, 20, 20, 253))
			surface.DrawRect(0, 0, slf:GetWide(), slf:GetTall())
			surface.SetDrawColor(Color(40, 40, 40, 255))
			surface.DrawRect(0, 0, slf:GetWide(), 20)
			draw.SimpleText("Installierte Elemente", "MG_CarDealer_TrebOut_S20", 10, 1, color_white)
		end
		self.ElementList = vgui.Create("DPanelList", ElementListBG)
		self.ElementList:SetPos(5, 25)
		self.ElementList:SetSize(ElementListBG:GetWide() - 10, ElementListBG:GetTall() - 30)
		self.ElementList:EnableHorizontal(false)
		self.ElementList:EnableVerticalScrollbar(true)
		self.ElementList:MG_CarDealer_PaintListBarC()
		self.ElementList.Paint = function(slf)
		end
		local AddElementBG = vgui.Create("DPanel", self.BuilderBGPanel)
		AddElementBG:SetPos(0, 0)
		AddElementBG:SetSize(50, self.BuilderBGPanel:GetTall())
		AddElementBG.Paint = function(slf)
			surface.SetDrawColor(Color(20, 20, 20, 253))
			surface.DrawRect(0, 0, slf:GetWide(), slf:GetTall())
			surface.SetDrawColor(Color(40, 40, 40, 255))
			surface.DrawRect(0, 0, slf:GetWide(), 20)
			draw.SimpleText("Element", "MG_CarDealer_TrebOut_S18", 25, 1, color_white, TEXT_ALIGN_CENTER)
		end
		self.AddElementList = vgui.Create("DPanelList", AddElementBG)
		self.AddElementList:SetPos(5, 25)
		self.AddElementList:SetSize(40, AddElementBG:GetTall()-30)
		self.AddElementList:EnableHorizontal(false)
		self.AddElementList:EnableVerticalScrollbar(true)
		self.AddElementList:SetSpacing(5)
		self.AddElementList:MG_CarDealer_PaintListBarC()
		self.AddElementList.Paint = function(slf)
			surface.SetDrawColor(Color(0, 0, 0, 50))
			surface.DrawRect(0, 0, slf:GetWide(), slf:GetTall())
		end
		for _,v in pairs(MG_CarDealer_Tuners or {}) do
			local Add = vgui.Create("DButton")
			Add:SetSize(40, 40)
			Add:SetText("")
			Add.DoClick = function(slf)
				surface.PlaySound("ui/buttonclick.wav")
				local cur = 0
				for _,a in pairs(tunedata.Elements or {}) do
					if a.Type == v.LuaName then
						cur = cur + 1
					end
				end
				if cur >= v.Max then
					MG_CarDealer.ShowNotice("Du hast das maximale Limit an Elementen dieser Art erreicht!")
					return
				end
				local allowed, reason = v:CanPlace(ply, selectedcardata.CarClass)
				if !allowed then MG_CarDealer.ShowNotice(reason or "") return end
				v:AddOnTunerPanel(tunedata, self, nil, nil, true)
			end
			local MAT
			if v.Icon then
				MAT = Material("icon16/"..v.Icon..".png")
			end
			Add.Paint = function(slf)
				if slf:IsHovered() then
					surface.SetDrawColor(60, 60, 60, 200)
				else
					surface.SetDrawColor(60, 60, 60, 100)
				end
				surface.DrawRect(0, 0, slf:GetWide(), slf:GetTall())
				if MAT then
					surface.SetMaterial(MAT)
					surface.SetDrawColor(255, 255, 255, 255)
					surface.DrawTexturedRect(12, 12, 16, 16)
				end
			end
			Add:SetTooltip(v.PrintName)
			self.AddElementList:AddItem(Add)
		end
		local ToolListBG = vgui.Create("DPanel", self.BuilderBGPanel)
		ToolListBG:SetPos(self.BuilderBGPanel:GetWide() - 220, 0)
		ToolListBG:SetSize(220, self.BuilderBGPanel:GetTall() - 370)
		ToolListBG.Paint = function(slf)
			surface.SetDrawColor(Color(20, 20, 20, 253))
			surface.DrawRect(0, 0, slf:GetWide(), slf:GetTall())
			surface.SetDrawColor(Color(40, 40, 40, 255))
			surface.DrawRect(0, 0, slf:GetWide(), 20)
			draw.SimpleText("Elementoptionen", "MG_CarDealer_TrebOut_S20", 10, 1, color_white)
		end
		self.ToolList = vgui.Create("DPanelList", ToolListBG)
		self.ToolList:SetPos(5, 25)
		self.ToolList:SetSize(ToolListBG:GetWide() - 10, ToolListBG:GetTall() - 30)
		self.ToolList:EnableHorizontal(false)
		self.ToolList:EnableVerticalScrollbar(true)
		self.ToolList:SetSpacing(2)
		self.ToolList:MG_CarDealer_PaintListBarC()
		self.ToolList.Paint = function(slf)
			surface.SetDrawColor(Color(0, 0, 0, 50))
			surface.DrawRect(0, 0, slf:GetWide(), slf:GetTall())
		end

		function self.ToolList:AddSubTitle(text)
			text = "※ "..text
			local wrap = MG_CarDealer.String_Wrap(text, self:GetWide() - 20, "MG_CarDealer_TrebOut_S20")
			local Labels = vgui.Create("DPanel")
			Labels:SetSize(self:GetWide() - 20, #wrap * 25)
			Labels.Paint = function(slf)
				surface.SetDrawColor(40, 40, 40, 255)
				surface.DrawRect(0, 0, slf:GetWide(), slf:GetTall())
				for k, v in pairs(wrap) do
					draw.SimpleText(v, "MG_CarDealer_Treb_S25", 2, 1 + 25 * (k - 1), Color(180, 255, 180, 255))
				end
			end
			self:AddItem(Labels)
			return Labels
		end

		function self.ToolList:AddText(text)
			local wrap = MG_CarDealer.String_Wrap(text, self:GetWide() - 20, "MG_CarDealer_TrebOut_S18")
			local Labels = vgui.Create("DPanel")
			Labels:SetSize(self:GetWide() - 20, #wrap * 20)
			Labels.Paint = function(slf)
				for k,v in pairs(wrap) do
					draw.SimpleText(v, "MG_CarDealer_Treb_S20", 10, -12 + 20 * k, Color(200, 200, 200, 255), TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
				end
			end
			self:AddItem(Labels)
			return Labels
		end

		function self.ToolList:CreateSlider(text, min, max, demical)
			local BG = vgui.Create("DPanel")
			BG:SetSize(self:GetWide(), 45)
			BG.Paint = function(slf)
			end
			local Slider = vgui.Create("MG_CarDealer_Sliders", BG)
			Slider.Mother = BG
			Slider:SetSize(self:GetWide(), 45)
			Slider:SetMax(max)
			Slider:SetMin(min)
			Slider.Last = min
			Slider:SetName(text)
			Slider:SetUp()
			Slider:SetValue(min)
			Slider:SetDemical(demical)
			self:AddItem(BG)
			return Slider
		end

		self.CamControler = vgui.Create("DPanel", self.BuilderBGPanel)
		self.CamControler:SetPos(1, 1)
		self.CamControler:SetSize(1, 1)
		self.CamControler.Paint = function(slf)
		end
		self.CamControler.Think = function(slf)
			self.BGBackGroundPanel.CamAngle.r = 0
			local speed = 1
			if input.IsKeyDown(KEY_LSHIFT) then
				speed = speed * 2
			end
			if input.IsKeyDown(KEY_W) then
				self.BGBackGroundPanel.CamPos = self.BGBackGroundPanel.CamPos + self.BGBackGroundPanel.CamAngle:Forward() * speed
			end
			if input.IsKeyDown(KEY_S) then
				self.BGBackGroundPanel.CamPos = self.BGBackGroundPanel.CamPos - self.BGBackGroundPanel.CamAngle:Forward() * speed
			end
			if input.IsKeyDown(KEY_A) then
				self.BGBackGroundPanel.CamPos = self.BGBackGroundPanel.CamPos - self.BGBackGroundPanel.CamAngle:Right() * speed
			end
			if input.IsKeyDown(KEY_D) then
				self.BGBackGroundPanel.CamPos = self.BGBackGroundPanel.CamPos + self.BGBackGroundPanel.CamAngle:Right() * speed
			end
			if input.IsKeyDown(KEY_SPACE) then
				self.BGBackGroundPanel.CamPos = self.BGBackGroundPanel.CamPos + self.BGBackGroundPanel.CamAngle:Up() * speed
			end
			if input.IsMouseDown(MOUSE_RIGHT) then
				if !slf.LM then
					slf.LM = true
					local MX, MY = gui.MousePos()
					self.LastMousePos_X = MX
					self.LastMousePos_Y = MY
				else
					local CX, CY = gui.MousePos()
					local DX, DY = self.LastMousePos_X-CX, self.LastMousePos_Y-CY
					self.BGBackGroundPanel.CamAngle.p = self.BGBackGroundPanel.CamAngle.p - DY/3
					if self.BGBackGroundPanel.CamAngle.p > 90 then
						self.BGBackGroundPanel.CamAngle.p = 90
					end
					if self.BGBackGroundPanel.CamAngle.p < -90 then
						self.BGBackGroundPanel.CamAngle.p = -90
					end
					self.BGBackGroundPanel.CamAngle.y = self.BGBackGroundPanel.CamAngle.y + DX/6
					self.LastMousePos_X = CX
					self.LastMousePos_Y = CY
				end
			else
				if slf.LM then
					slf.LM = false
				end
			end
			self.BGBackGroundPanel.CamPos.x = math.min(self.BGBackGroundPanel.CamPos.x, 350 + (self.BGBackGroundPanel.CargoSize) * 500)
			self.BGBackGroundPanel.CamPos.x = math.max(self.BGBackGroundPanel.CamPos.x, -300)
			self.BGBackGroundPanel.CamPos.y = math.min(self.BGBackGroundPanel.CamPos.y, 350)
			self.BGBackGroundPanel.CamPos.y = math.max(self.BGBackGroundPanel.CamPos.y, -350)
			self.BGBackGroundPanel.CamPos.z = math.min(self.BGBackGroundPanel.CamPos.z, 240)
			self.BGBackGroundPanel.CamPos.z = math.max(self.BGBackGroundPanel.CamPos.z, 10)
		end
		self:AddElement()
		for _,v in pairs(tunedata.Elements or {}) do
			local element = IsValidElement(v.Type)
			if element then
				element:AddOnTunerPanel(tunedata, self, v.ID, v.Vars)
			end
		end
	end
end