if SERVER then
	AddCSLuaFile()
end

SWEP.PrintName = "Hacke"
SWEP.Purpose = "Wird zum Errichten von Beeten benutzt."
SWEP.Instructions = "Linksklick zum Errichten eines Beets.\nRechtsklick zum Abreißen eines Beets.\nNachladen zum Nachschauen deiner Pflanzensamen."

SWEP.Slot = 0
SWEP.SlotPos = 10

SWEP.Spawnable = true

SWEP.ViewModel = Model("models/weapons/eryk/farmingmod/v_hoe.mdl")
SWEP.WorldModel = Model("models/weapons/eryk/farmingmod/w_hoe.mdl")
SWEP.ViewModelFOV = 90
SWEP.UseHands = false
SWEP.HoldType = "melee2"

SWEP.Primary.ClipSize = -1
SWEP.Primary.DefaultClip = -1
SWEP.Primary.Automatic = false
SWEP.Primary.Ammo = "none"

SWEP.Secondary.ClipSize = -1
SWEP.Secondary.DefaultClip = -1
SWEP.Secondary.Automatic = true
SWEP.Secondary.Ammo = "none"

SWEP.BuildCost = 100
SWEP.Seeds = {}

SWEP.DrawAmmo = false

function SWEP:SetupDataTables()
	self:NetworkVar("Bool", 0, "CanBuild")
end

function SWEP:DrawHUD()
	local scrw, scrh = ScrW() / 2, ScrH() - 110
	draw.SimpleTextOutlined("Linksklick zum Errichten eines Beets für $"..string.Comma(self.BuildCost)..".", "mg_instructions", scrw, scrh, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP, 1, color_black)
	draw.SimpleTextOutlined("Rechtsklick zum Abreißen eines Beets und Nachladen zum Nachschauen deiner Pflanzensamen.", "mg_instructions2", scrw, scrh + 25, color_white, TEXT_ALIGN_CENTER, TEXT_ALIGN_TOP, 1, color_black)
end

function SWEP:Initialize()
	self:SetDeploySpeed(1)
	self:SetHoldType(self.HoldType)
end

function SWEP:CalcViewModelView(vm, oldPos, oldAng, pos, ang)
	local oldPos = vm:GetPos()
	local oldAng = vm:GetAngles()
	local newPos = pos + ang:Up() * 5 + ang:Forward() * -12
	return newPos, ang
end

if CLIENT then
	net.Receive("Farming_SendSeeds", function(l, ply)
		local wep = net.ReadEntity()
		if !IsValid(wep) or !wep.Seeds then return end
		wep.Seeds = net.ReadTable()
	end)
end

local tbl = {
	cmd = "plant_plot",
	max = FarmingCFG.MaxPlots
}

SWEP.MaxRange = 120 * 120
function SWEP:PrimaryAttack(right)
	self:SetNextPrimaryFire(CurTime() + 0.1)
	self:SetNextSecondaryFire(CurTime() + 0.1)
	if CLIENT and self:GetCanBuild() or SERVER then
		if SERVER then
			local allowed, tr, parent = self:IsFree()
			if allowed then
				local plot = ents.Create("plant_plot")
				if !IsValid(plot) then return end
				plot:SetPos(tr.HitPos + Vector(0, 0, 2))
				plot:SetAngles(Angle(0, self.Owner:EyeAngles().y, 0))
				plot:Spawn()
				plot:Activate()
				plot.DarkRPItem = tbl
				plot.SID = self.Owner.SID
				plot:Setowning_ent(self.Owner)
				self.Owner:addCustomEntity(tbl)
				if !self.Owner.GardenerPlots then
					self.Owner.GardenerPlots = {}
				end
				self.Owner.GardenerPlots[plot] = true
				if IsValid(parent) then
					plot.Parent = parent
					plot.ParentPos = parent:GetPos()
				end
				self.Owner:addMoney(-self.BuildCost)
				DarkRP.notify(self.Owner, 0, 4, "Du hast ein leeres Beet für $"..self.BuildCost.." errichtet.")
			else
				return false
			end
		end
		self:SendWeaponAnim(ACT_VM_HITCENTER)
		self.Owner:SetAnimation(PLAYER_ATTACK1)
		self:EmitSound("physics/wood/wood_plank_impact_hard"..math.random(1, 4)..".wav")
		self:SetNextPrimaryFire(CurTime() + 1)
		self:SetNextSecondaryFire(CurTime() + 1)
	end
end

function SWEP:SecondaryAttack()
	self:SetNextPrimaryFire(CurTime() + 0.1)
	self:SetNextSecondaryFire(CurTime() + 0.1)
	local tr = self.Owner:GetEyeTrace()
	local ent = tr.Entity
	if IsValid(ent) and ent:GetClass() == "plant_plot" and ent:Getowning_ent() == self.Owner then
		if SERVER then
			ent:Explode()
		end
		self:SendWeaponAnim(ACT_VM_HITCENTER)
		self.Owner:SetAnimation(PLAYER_ATTACK1)
		self:SetNextPrimaryFire(CurTime() + 1)
		self:SetNextSecondaryFire(CurTime() + 1)
	end
end

local seedsmenu
function SWEP:Reload()
	if CLIENT then
		local allowed, seeds = false, {}
		for k, v in pairs(self.Seeds) do
			if v > 0 then
				seeds[k] = v
				allowed = true
			end
		end
		if !allowed then return end
		if IsValid(seedsmenu) then return end
		seedsmenu = vgui.Create("DFrame")
		seedsmenu:SetTitle("")
		seedsmenu:ShowCloseButton(false)
		seedsmenu:SetDraggable(false)
		seedsmenu:SetWide(220)
		seedsmenu:ParentToHUD()
		seedsmenu.Close = function(self)
			self:Remove()
		end
		seedsmenu.Paint = function(self, w, h)
			draw.RoundedBox(8, 0, 0, w, h, Color(47, 54, 76, 255))
			draw.SimpleText("Deine Samen", "Farming_SegoeUI_16", w / 2, 2, color_white, TEXT_ALIGN_CENTER)
		end
		local ply = LocalPlayer()
		seedsmenu.CreatedTime = SysTime()
		seedsmenu.ReadyToClose = false
		seedsmenu.Think = function()
			if !ply:Alive() then
				seedsmenu:Close()
			end
			if input.IsKeyDown(KEY_R) then
				if seedsmenu.ReadyToClose then
					seedsmenu:Close()
				end
			else
				if !seedsmenu.ReadyToClose and SysTime() - seedsmenu.CreatedTime > 0.1 then
					seedsmenu.ReadyToClose = true
				end
			end
		end
		local exitbtn = vgui.Create("DButton", seedsmenu)
		exitbtn:SetSize(22, 22)
		exitbtn:SetFont("Farming_SegoeUI_20")
		exitbtn:SetText("X")
		exitbtn:SetColor(Color(250, 250, 250, 255))
		exitbtn:SetPos(seedsmenu:GetWide() - 22, 0)
		exitbtn.Paint = function(self, w)
			draw.RoundedBoxEx(8, 0, 0, w, 40, Color(70, 84, 162, 255), false, true)
		end
		exitbtn.DoClick = function(self)
			surface.PlaySound("ui/buttonclick.wav")
			seedsmenu:Close()
		end
		local menusize = 40
		for k, v in pairs(seeds) do
			local seed_tbl = FarmingCFG.Crops[k]
			if !seed_tbl then continue end
			local seed = vgui.Create("DPanel", seedsmenu)
			seed:SetPos(5, menusize)
			seed:SetSize(210, 20)
			seed.Paint = function(self, w, h)
				surface.SetDrawColor(39, 42, 51, 255)
				surface.DrawRect(0, 0, w, h)
				surface.SetDrawColor(50, 50, 50, 255)
				surface.DrawOutlinedRect(0, 0, w, h)
				draw.SimpleText(seed_tbl.seedname.." (x"..v..")", "Farming_SegoeUI_16", w / 2, 1, color_white, TEXT_ALIGN_CENTER)
			end
			menusize = menusize + 30
		end
		seedsmenu:SetTall(menusize)
		seedsmenu:Center()
		seedsmenu:MakePopup()
	end
end

local function IsTouchingEntity(ent, ent2)
	local emin, emax = ent:WorldSpaceAABB()
	local vmin, vmax = ent2:WorldSpaceAABB()
	if emin.x <= vmax.x and emax.x >= vmin.x and emin.y <= vmax.y and emax.y >= vmin.y and emin.z <= vmax.z and emax.z >= vmin.z then
		return true
	end
	return false
end

function SWEP:CheckForStuckingStuff(ent, whitelisted)
	local forbidden = false
	local center, radius  = ent:LocalToWorld(ent:OBBCenter()), ent:BoundingRadius() + 2
	local wspacemin, wspacemax = ent:WorldSpaceAABB()
	for _, v in ipairs(ents.FindInSphere(center, radius)) do
		if ent != v and whitelisted != v then
			local typ = v:IsPlayer() and v:Alive() and 1 or v:IsNPC() and 1 or v:GetClass() == "plant_plot" and 1 or v:IsSolid() and 0
			if typ then
				if typ == 0 then
					local phys = v:GetPhysicsObject()
					if !IsValid(phys) or !phys:IsMoveable() or !phys:IsMotionEnabled() then
						continue
					end
				end
				if IsTouchingEntity(ent, v) then
					forbidden = true
				end
			end
		end
		if forbidden then break end
	end
	return forbidden
end

function SWEP:SetupModel()
	self.GhostProp = ents.Create("prop_physics")
	local prop = self.GhostProp
	if !IsValid(prop) then return false end
	prop:SetModel("models/props/eryk/farmingmod/cropplot.mdl")
	prop:Spawn()
	prop:SetMaterial("models/wireframe")
	prop:PhysicsDestroy()
	prop:SetNotSolid(true)
	prop:DrawShadow(false)
	return prop
end

function SWEP:IsFree()
	local tr = self.Owner:GetEyeTrace()
	if !tr.Hit then
		return false
	end
	if self.Owner:customEntityLimitReached(tbl) or !self.Owner:canAfford(self.BuildCost) then
		return false
	end
	local normal = tr.HitNormal
	local normal_z = normal.z
	local flat_normal_z = normal_z > 0.75 and 1 or normal_z < -0.75 and -1
	if (flat_normal_z != 1 or tr.StartPos:DistToSqr(tr.HitPos) >= self.MaxRange) then
		return false
	end
	local ent = tr.Entity
	if ent:IsValid() then
		local phys = ent:GetPhysicsObject()
		if phys:IsValid() and phys:IsMoveable() and phys:IsMotionEnabled() or ent:GetClass() == "func_breakable_surf" or ent:GetClass() == "plant_plot" then
			return false
		end
	end
	local prop = IsValid(self.GhostProp) and self.GhostProp or self:SetupModel()
	if !IsValid(prop) then
		return false
	end
	prop:SetPos(tr.HitPos + Vector(0, 0, 2))
	prop:SetAngles(Angle(0, self.Owner:GetAngles().y, 0))
	if self:CheckForStuckingStuff(prop, ent) then
		return false
	end
	return true, tr, ent
end

function SWEP:CreateGhostProp(curtime)
	local allowed = self:IsFree()
	if !IsValid(self.GhostProp) then return false end
	if !allowed then
		self.GhostProp:SetNoDraw(true)
		return false
	else
		self.GhostProp:SetNoDraw(false)
		return true
	end
end

function SWEP:Think()
	if SERVER then
		self:SetCanBuild(self:CreateGhostProp(CurTime()))
	end
end

function SWEP:Holster()
	if SERVER then
		SafeRemoveEntity(self.GhostProp)
	end
	return true
end

function SWEP:OnRemove()
	if SERVER then
		SafeRemoveEntity(self.GhostProp)
	end
end

function SWEP:OnDrop()
	self:Remove()
end