include("shared.lua")

local use_font = system.IsWindows() and "Tahoma" or "Verdana"
surface.CreateFont("mg_methcombinermenu", {font = use_font, size = 15, weight = 800, blursize = 0, antialias = true, shadow = false})
surface.CreateFont("mg_methcombinermenu2", {font = use_font, size = 32, weight = 600, blursize = 0, antialias = true, shadow = false})

surface.CreateFont("mg_entfont", {font = use_font, size = 35, weight = 1000, blursize = 0, antialias = true, shadow = false})

local localply, jobclr
local labcolors = {
	Color(47, 54, 64), -- Main background
	Color(27, 156, 252), -- On
	Color(87, 96, 111), -- Off
	Color(53, 59, 72), -- Help background & progress background
	Color(0, 151, 230), -- Progress fill
	Color(251, 197, 49), -- Danger filter
	Color(65, 65, 65),
	Color(231, 76, 60),
	Color(45, 45, 45),
	Color(35, 35, 35),
	Color(192, 57, 43),
}
local draw_RoundedBox, draw_SimpleText, draw_DrawText, math_Clamp, cam_Start3D2D, cam_End3D2D, draw_SimpleTextOutlined  = draw.RoundedBox, draw.SimpleText, draw.DrawText, math.Clamp, cam.Start3D2D, cam.End3D2D, draw.SimpleTextOutlined
local wrkingsteps = {
	[2] = true,
	[4] = true,
	[6] = true,
}
local pausesteps = {
	[1] = true,
	[3] = true,
	[7] = true,
	[8] = true,
}

function ENT:Initialize()

	self.LastStage = 1
	self.HasFilter = false
	self.HasTray = false
	self.GasLevel = 0
	self.DirtLevel = 0

	self.LastMethSludge = 0

	self.stageinfo = {
		[1] = zmlab.language.combiner_step01,
		[2] = zmlab.language.combiner_step02,
		[3] = zmlab.language.combiner_step03,
		[4] = zmlab.language.combiner_step04,
		[5] = zmlab.language.combiner_step05,
		[6] = zmlab.language.combiner_step06,
		[7] = zmlab.language.combiner_step07,
		[8] = zmlab.language.combiner_step08
	}
	jobclr = team.GetColor(zmlab.config.cookjob) or color_white
end

local ask
local function askdialogue(text, ent, callback)
	ask = vgui.Create("DFrame")
	ask:SetSize(400, 100)
	ask:Center()
	ask:SetTitle("")
	ask:MakePopup()
	ask:ShowCloseButton(false)
	ask:SetDraggable(false)
	ask:ParentToHUD()
	ask.Paint = function(self, w, h)
		draw.RoundedBox(0, 0, 0, w, h, labcolors[7])
		draw.SimpleText("Bestätigung", "mg_methcombinermenu", 5, 5, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
		draw.SimpleText(text, "mg_methcombinermenu", w / 2, 25, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP)
	end
	local ply = LocalPlayer()
	local pressed_E = true
	ask.Think = function()
		if !input.IsKeyDown(KEY_E) then
			pressed_E = false
		elseif !pressed_E then
			ask:Remove()
		end
		if !IsValid(ent) or ent:GetNoDraw() or ent:GetIsBusy() or !ply:Alive() or ply:EyePos():DistToSqr(ent:GetPos()) > 36000 then
			ask:Remove()
		end
	end

	local closebttn = vgui.Create("DButton", ask)
	closebttn:SetText("")
	closebttn:SetPos(ask:GetWide() - 50, 0)
	closebttn:SetSize(50, 20)
	closebttn.Paint = function(self, w, h)
		if self:IsHovered() then
			draw.RoundedBox(0, 0, 0, w, h, labcolors[11])
		else
			draw.RoundedBox(0, 0, 0, w, h, labcolors[8])
		end
		draw.SimpleText("X", "mg_methcombinermenu", w / 2, h / 2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	end
	closebttn.DoClick = function()
		surface.PlaySound("ui/buttonclick.wav")
		ask:Remove()
	end

	local bttn2 = vgui.Create("DButton", ask)
	bttn2:Dock(BOTTOM)
	bttn2:SetText("")
	bttn2.Paint = function(self, w, h)
		if self:IsHovered() then
			draw.RoundedBox(0, 0, 0, w, h, labcolors[10])
		else
			draw.RoundedBox(0, 0, 0, w, h, labcolors[9])
		end
		draw.SimpleText("Zurück", "mg_methcombinermenu", w / 2, h / 2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	end
	bttn2.DoClick = function()
		surface.PlaySound("ui/buttonclick.wav")
		ask:Close()
	end

	local bttn1 = vgui.Create("DButton", ask)
	bttn1:DockMargin(0, 5, 0, 5)
	bttn1:Dock(BOTTOM)
	bttn1:SetText("")
	bttn1.Paint = function(self, w, h)
		if self:IsHovered() then
			draw.RoundedBox(0, 0, 0, w, h, labcolors[10])
		else
			draw.RoundedBox(0, 0, 0, w, h, labcolors[9])
		end
		draw.SimpleText("Fortfahren", "mg_methcombinermenu", w / 2, h / 2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	end
	bttn1.DoClick = function()
		surface.PlaySound("ui/buttonclick.wav")
		ask:Remove()
		callback()
	end
end

local base
local function combinermenu()
	local ent = net.ReadEntity()
	if !IsValid(ent) or IsValid(base) then return end
	base = vgui.Create("DFrame")
	base:SetSize(200, 115)
	base:Center()
	base:SetTitle("")
	base:MakePopup()
	base:ShowCloseButton(false)
	base:SetDraggable(false)
	base:ParentToHUD()
	base.Paint = function(self, w, h)
		draw.RoundedBox(0, 0, 0, w, h, labcolors[7])
		draw.SimpleText("Methlabor", "mg_methcombinermenu", 5, 5, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_TOP)
	end
	local ply = LocalPlayer()
	local pressed_E = true
	base.Think = function()
		if !input.IsKeyDown(KEY_E) then
			pressed_E = false
		elseif !pressed_E then
			base:Remove()
		end
		if !IsValid(ent) or ent:GetNoDraw() or ent:GetIsBusy() or !ply:Alive() or ply:EyePos():DistToSqr(ent:GetPos()) > 36000 then
			base:Remove()
		end
	end

	local closebttn = vgui.Create("DButton", base)
	closebttn:SetText("")
	closebttn:SetPos(150, 0)
	closebttn:SetSize(50, 20)
	closebttn.Paint = function(self, w, h)
		if self:IsHovered() then
			draw.RoundedBox(0, 0, 0, w, h, labcolors[11])
		else
			draw.RoundedBox(0, 0, 0, w, h, labcolors[8])
		end
		draw.SimpleText("X", "mg_methcombinermenu", w / 2, h / 2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	end
	closebttn.DoClick = function()
		surface.PlaySound("ui/buttonclick.wav")
		base:Remove()
	end

	local bttn1 = vgui.Create("DButton", base)
	bttn1:Dock(TOP)
	bttn1:SetHeight(36)
	bttn1:SetText("")
	bttn1.Paint = function(self, w, h)
		if self:IsHovered() then
			draw.RoundedBox(0, 0, 0, w, h, labcolors[10])
		else
			draw.RoundedBox(0, 0, 0, w, h, labcolors[9])
		end
		if ent:GetIsBeeingScraped() then
			draw.SimpleText("Abbrechen (".. string.ToMinutesSeconds(ent:GetScrapedIn() - CurTime())..")", "mg_methcombinermenu", w / 2, h / 2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
		else
			draw.SimpleText("Verschrotten ("..string.ToMinutesSeconds(zmlab.config.scraptime)..")", "mg_methcombinermenu", w / 2, h / 2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
		end
	end
	bttn1.DoClick = function()
		base:Remove()
		surface.PlaySound("ui/buttonclick.wav")
		if !IsValid(ent) then return end
		if ent:GetIsBeeingScraped() then
			askdialogue("Möchtest du die Verschrottung wirklich abbrechen?", ent, function()
				if !IsValid(ent) then return end
				net.Start("mg_meth_net_stopscrap")
					net.WriteEntity(ent)
				net.SendToServer()
			end)
		else
			askdialogue("Möchtest du dies wirklich verschrotten?", ent, function()
				net.Start("mg_meth_net_startscrap")
					net.WriteEntity(ent)
				net.SendToServer()
			end)
		end
	end

	local bttn2 = vgui.Create("DButton", base)
	bttn2:Dock(TOP)
	bttn2:DockMargin(0, 5, 0, 0)
	bttn2:SetHeight(36)
	bttn2:SetText("")
	bttn2.Paint = function(self, w, h)
		if self:IsHovered() then
			draw.RoundedBox(0, 0, 0, w, h, labcolors[10])
		else
			draw.RoundedBox(0, 0, 0, w, h, labcolors[9])
		end
		draw.SimpleText("Methlabor fixieren/lösen", "mg_methcombinermenu", w / 2, h / 2, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
	end
	bttn2.DoClick = function()
		base:Remove()
		surface.PlaySound("ui/buttonclick.wav")
		if !IsValid(ent) then return end
		net.Start("mg_meth_net_freeze")
			net.WriteEntity(ent)
		net.SendToServer()
	end
end

net.Receive("mg_meth_net_opencombinermenu", combinermenu)

function ENT:Draw()
	self:DrawModel()
	localply = localply or LocalPlayer()
	if localply:GetPos():DistToSqr(self:GetPos()) > 160000 or self:GetIsScraped() then return end
	self:DrawInfo()
end

local vector_1 = Vector(0, 0, 1)
function ENT:DrawTranslucent()
	localply = localply or LocalPlayer()
	if self:GetIsScraped() then
		if localply:GetPos():DistToSqr(self:GetPos()) > 360000 then return end
		local ang = self:GetAngles()	
		local pos = self:GetPos() + (vector_1 * (self:OBBMaxs().z + 5 + math.sin(SysTime() * 2) * 2))
		ang:RotateAroundAxis(ang:Forward(), 90)
		ang:RotateAroundAxis(ang:Right(), -90)
		ang:RotateAroundAxis(ang:Up(), 0)
		cam_Start3D2D(pos, Angle(0, EyeAngles().y - 90, 90), 0.1)
			draw_SimpleTextOutlined("Verschrottetes Methlabor", "mg_entfont", 0, -100, jobclr, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER, 1, color_black)
		cam_End3D2D()
	else
		local time = self:GetScrapedIn()
		if time > 0 then
			cam_Start3D2D(self:LocalToWorld(Vector(0, 64.1, 59.2)), self:LocalToWorldAngles(Angle(180, 0, -75)), 0.05)
				draw_SimpleText("Wird verschrottet in:", "zmlab_combinertitle", 0, -20, Color(255, 50, 50), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
				draw_SimpleText(string.ToMinutesSeconds(time - CurTime()).." min.", "zmlab_combinertitle", 0, 20, Color(255, 50, 50), TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
			cam_End3D2D()
		end
	end
end

function ENT:DrawInfo()
	local owner = zmlab.f.GetOwner(self)
	local pname = owner and owner:Nick() or "Niemand"
	cam_Start3D2D(self:LocalToWorld(Vector(0, 64.1, 59.2)), self:LocalToWorldAngles(Angle(180, 0, -75)), 0.05)
		draw_RoundedBox(0, -375, -200, 750, 400, labcolors[1])
		--draw.RoundedBox(number cornerRadius, number x, number y, number width, number height, table color)
		if wrkingsteps[self.LastStage] or self:GetIsBusy() then
			draw_RoundedBox(0, -375, -200, 750, 80, labcolors[2])
		elseif self.LastStage == 5 then
			draw_RoundedBox(0, -375, -200, 750, 80, self.HasFilter and labcolors[2] or labcolors[6])
		else
			draw_RoundedBox(0, -375, -200, 750, 80, labcolors[3])
		end
		draw_SimpleText("Methlabor", "zmlab_combinertitle", 0, -165, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)
		draw_SimpleText(pname, "zmlab_combinerbody", 0, -135, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_CENTER)

		local time = self:GetScrapedIn()
		if time <= 0 then
			draw_SimpleText("Status", "zmlab_combinerbody", -340, -104, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
			draw_RoundedBox(0, -340, -90, 680, 40, labcolors[4])

			if !pausesteps[self.LastStage] then
				local MaxTime = self:GetMaxProcessingTime()
				local StartTime = self:GetStartProcessingTime()
				local EndTime = (StartTime + MaxTime) - CurTime()
				EndTime = MaxTime - EndTime
				draw_RoundedBox(0, -338, -88, math_Clamp((676 / MaxTime) * EndTime, 0, 676), 36, labcolors[5])
			end

			draw_SimpleText("Verschmutzung", "zmlab_combinerbody", -340, -26, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
			draw_RoundedBox(0, -340, -12.5, 680, 20, labcolors[4])
			self.DirtLevel = Lerp(FrameTime() * 8, self.DirtLevel, (676 / zmlab.config.Combiner.DirtAmount) * self:GetCleaningProgress())
			draw_RoundedBox(0, -338, -10.5, self.DirtLevel, 16, labcolors[5])

			draw_SimpleText("Gasentwicklung", "zmlab_combinerbody", -340, 20, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
			draw_RoundedBox(0, -340, 33.5, 680, 20, labcolors[4])

			if self.LastStage == 5 and !self.HasFilter then
				self.GasLevel = Lerp(FrameTime() * 6, self.GasLevel, 676)
				draw_RoundedBox(0, -338, 35.5, self.GasLevel, 16, labcolors[5])
			elseif self.LastStage == 6 then
				self.GasLevel = Lerp(FrameTime() * 2, self.GasLevel, 0)
				draw_RoundedBox(0, -338, 35.5, self.GasLevel, 16, labcolors[5])
			end

			draw_RoundedBox(0, -375, 80, 750, 120, labcolors[4])
			draw_SimpleText("Nächster Schritt:", "zmlab_combinertitle2", -340, 94, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
			if self.LastStage == 1 then
				local need = self:GetNeedMethylamin() - self:GetMethylamin()
				draw_DrawText(self.stageinfo[self.LastStage].."\nNoch "..need.." "..(need == 1 and "Fass" or "Fässer").." benötigt.", "zmlab_combinerbody", -340, 110, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
			elseif self.LastStage == 3 then
				local need = self:GetNeedAluminium() - self:GetAluminium()
				draw_DrawText(self.stageinfo[self.LastStage].."\nNoch "..need.." "..(need == 1 and "Box" or "Boxen").." benötigt.", "zmlab_combinerbody", -340, 110, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
			elseif self.stageinfo[self.LastStage] then
				draw_DrawText(self.stageinfo[self.LastStage], "zmlab_combinerbody", -340, 110, color_white, TEXT_ALIGN_LEFT, TEXT_ALIGN_CENTER)
			end
		end
	cam_End3D2D()
end

local particleEffects = GetConVar("zmlab_cl_vfx_particleeffects")
function ENT:CreateFilterEffects()
	self:StopParticles()

	if self:GetIsScraped() then return end

	if !particleEffects:GetBool() then return end

	if self.LastStage == 5 then
		if self.HasFilter then
			ParticleEffectAttach("zmlab_cleand_gas", PATTACH_POINT_FOLLOW, self, 7)
		else
			ParticleEffectAttach("zmlab_poison_gas", PATTACH_POINT_FOLLOW, self, 7)
		end
	else
		self:StopParticles()
	end
end

local localPly
function ENT:Think()
	local tb = self:GetTable()
	if !tb then return end
	local dt = tb.dt
	if !dt then return end

	if dt.IsScraped then
		self:CleanUp()
		return
	end

	localPly = localPly or LocalPlayer()

	if zmlab.f.InDistance(localPly:EyePos(), self:GetPos(), 600) and !self:GetNoDraw() then

		zmlab.f.LoopedSound(self, "Combiner_poision", tb.LastStage == 5 and tb.HasFilter == false)
		zmlab.f.LoopedSound(self, "Combiner_filtering", tb.LastStage == 5 and tb.HasFilter == true)
		zmlab.f.LoopedSound(self, "progress_cooking", tb.LastStage == 2 or tb.LastStage == 4 or tb.LastStage == 6)

		// PumpSound and Effects
		self:OutputVFX()

		if tb.ClientProps then

			local methsludge = tb.ClientProps["MethSludge"]
			if !IsValid(methsludge) then
				self:SpawnClientModel_MethSludge()
			else
				self:Parent_MethSludges()
				local hasFilter = dt.HasFilter
				local hasTray = dt.HasTray
				local currentStage = dt.Stage

				if tb.LastStage ~= currentStage or hasFilter ~= tb.HasFilter or hasTray ~= tb.HasTray then

					tb.LastStage = currentStage
					tb.HasFilter = hasFilter
					tb.HasTray = hasTray

					self:CreateFilterEffects()

					methsludge:SetNoDraw(false)

					if tb.LastStage == 1 then

						methsludge:SetNoDraw(true)
						zmlab.f.ClientAnim(methsludge, "idle", 1)
						zmlab.f.ClientAnim(self, "mode_idle", 1)

					elseif tb.LastStage == 2 then

						zmlab.f.ClientAnim(methsludge, "half", 1)
						zmlab.f.ClientAnim(self, "mode_mix", 1)

					elseif tb.LastStage == 3 then

						zmlab.f.ClientAnim(self, "mode_idle", 1)
						self:EmitSound("progress_done")

					elseif tb.LastStage == 4 then

						zmlab.f.ClientAnim(methsludge, "full", 1)
						zmlab.f.ClientAnim(self, "mode_mix", 1)

					elseif tb.LastStage == 5 then

						zmlab.f.ClientAnim(self, "mode_mix", 1)
						zmlab.f.ClientAnim(methsludge, "full", 1)

					elseif tb.LastStage == 6 then

						zmlab.f.ClientAnim(self, "mode_mix", 1)
						zmlab.f.ClientAnim(methsludge, "full", 1)

					elseif tb.LastStage == 7 then

						if tb.HasTray then
							zmlab.f.ClientAnim(self, "mode_pump", 1)
						else
							zmlab.f.ClientAnim(self, "mode_idle", 1)
						end

						zmlab.f.ClientAnim(methsludge, "full", 1)

					elseif tb.LastStage == 8 then

						zmlab.f.ClientAnim(self, "mode_idle", 1)
						methsludge:SetNoDraw(true)
						zmlab.f.ClientAnim(methsludge, "idle", 1)
					end
				end
			end
		else
			tb.ClientProps = {}
		end
	else
		tb.LastStage = -1
		tb.HasFilter = -1
		tb.HasTray = -1

		self:StopSound("progress_cooking")
		self:StopSound("progress_done")
		self:StopSound("Combiner_poision")
		self:StopSound("Combiner_filtering")

		self:RemoveClientModels()

		self:StopParticles()
	end

	self:SetNextClientThink(CurTime())

	return true
end


function ENT:OutputVFX()
	if self:GetIsScraped() then return end

	local currentMeth = self:GetMethSludge()

	if self.LastMethSludge ~= currentMeth and self.HasTray then

		self:EmitSound("MethylaminSludge_pump")

		local attach = self:LookupAttachment("effect0" .. math.random(1, 5))
		if attach then
			local attachData = self:GetAttachment(attach)
			if attachData then
				if particleEffects:GetBool() then
					ParticleEffect("zmlab_methsludge_fill", attachData.Pos, attachData.Ang, self)
				end
				self.LastMethSludge = currentMeth
			end
		end
	end
end

// Client Model
function ENT:SpawnClientModel_MethSludge()
	local ent = ents.CreateClientProp()
	if !IsValid(ent) then return end
	ent:SetPos(self:GetPos() + self:GetUp() * 20)
	ent:SetAngles(self:GetAngles())
	ent:SetModel("models/zerochain/zmlab/zmlab_sludge.mdl")
	ent:Spawn()
	ent:Activate()
	ent:SetParent(self)
	ent:SetNoDraw(true)
	self.ClientProps["MethSludge"] = ent
end

function ENT:Parent_MethSludges()
	if (self.ClientProps) then
		for k, v in pairs(self.ClientProps) do
			if IsValid(v) and !IsValid(v:GetParent()) then
				v:SetPos(self:GetPos() + self:GetUp() * 20)
				v:SetAngles(self:GetAngles())
				v:SetParent(self)
			end
		end
	end
end

function ENT:RemoveClientModels()
	if (self.ClientProps) then
		for k, v in pairs(self.ClientProps) do
			if IsValid(v) then
				v:Remove()
			end
		end
	end

	self.ClientProps = {}
	self.RollCount = 0
end

function ENT:CleanUp()
	self:StopSound("progress_cooking")
	self:StopSound("progress_done")
	self:StopSound("Combiner_poision")
	self:StopSound("Combiner_filtering")

	self:RemoveClientModels()


	for k, v in pairs(self.Sounds or {}) do
		if v:IsPlaying() then
			v:Stop()
		end
		self.Sounds[k] = nil
	end
end

function ENT:OnRemove()
	self:CleanUp()
end
