AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
include("shared.lua")

------------------------------//
function ENT:SpawnFunction(ply, tr)
	if (not tr.Hit) then return end
	local SpawnPos = tr.HitPos + tr.HitNormal * 1
	local ent = ents.Create(self.ClassName)
	local angle = ply:GetAimVector():Angle()
	angle = Angle(0, angle.yaw, 0)
	angle:RotateAroundAxis(angle:Up(), 180)
	ent:SetAngles(angle)
	ent:SetPos(SpawnPos)
	ent:Spawn()
	ent:Activate()

	return ent
end

function ENT:Initialize()
	self:SetModel(self.Model)
	self:PhysicsInit(SOLID_VPHYSICS)
	self:SetMoveType(MOVETYPE_NONE)
	self:SetSolid(SOLID_VPHYSICS)
	self:SetCollisionGroup(COLLISION_GROUP_WEAPON)
	self:DrawShadow(false)
	self:SetModelScale(1)
	local phys = self:GetPhysicsObject()

	if (phys:IsValid()) then
		phys:Wake()
		phys:EnableMotion(false)
	end

	self.PhysgunDisabled = true
	self:UpdateVisuals()
end

function ENT:UpdateVisuals()
	local rType = self:GetResourceType()

	if (rType == "Random") then
		self:SetSkin(0)
	elseif (rType == "Iron") then
		self:SetSkin(1)
	elseif (rType == "Bronze") then
		self:SetSkin(2)
	elseif (rType == "Silver") then
		self:SetSkin(3)
	elseif (rType == "Gold") then
		self:SetSkin(4)
	elseif (rType == "Coal") then
		self:SetSkin(5)
	end

	local rAmount = self:GetResourceAmount()
	local rMaxAmount = self:GetMax_ResourceAmount()

	if (rAmount <= 0) then
		self:SetBodygroup(0, 5)
	elseif (rAmount < rMaxAmount * 0.1) then
		self:SetBodygroup(0, 4)
	elseif (rAmount < rMaxAmount * 0.25) then
		self:SetBodygroup(0, 3)
	elseif (rAmount < rMaxAmount * 0.5) then
		self:SetBodygroup(0, 2)
	elseif (rAmount < rMaxAmount * 0.75) then
		self:SetBodygroup(0, 1)
	elseif (rAmount <= rMaxAmount) then
		self:SetBodygroup(0, 0)
	end
end

function ENT:HasResource()
	if (self:GetResourceAmount() > 0) then
		return true
	else
		return false
	end
end

function ENT:DecreaseOre(amount)
	local newAmount = self:GetResourceAmount() - amount

	if (newAmount < 0) then
		newAmount = 0
	end

	self:SetResourceAmount(newAmount)
	zrmine.f.CreateEffectTable("zrms_ore_mine", "zrmine_sfx_resourcedespawn", self, self:GetAngles(), self:GetPos())
	self:UpdateVisuals()
end

function ENT:RefreshOre()
	if (self:GetResourceAmount() < self:GetMax_ResourceAmount()) then
		local increaseAmount = self:GetResourceAmount() + zrmine.config.Ore_RefreshAmount

		if (increaseAmount > self:GetMax_ResourceAmount()) then
			increaseAmount = self:GetMax_ResourceAmount()
		end

		self:SetResourceAmount(increaseAmount)
		zrmine.f.CreateEffectTable("zrms_ore_refresh", nil, self, self:GetAngles(), self:GetPos())
		self:UpdateVisuals()
	end
end

function ENT:GetRandomOre()
	local OreChancePool = {}

	for k, v in pairs(zrmine.config.Mine_ResourceChance) do
		for i = 1, v do
			table.insert(OreChancePool, k)
		end
	end

	local failChance = 100 - zrmine.config.Pickaxe_HarvestChance

	if (failChance > 0) then
		for i = 1, (100 - zrmine.config.Pickaxe_HarvestChance) do
			table.insert(OreChancePool, "Nothing")
		end
	end

	return table.Random(OreChancePool)
end

function ENT:Harvest(Owner, amount)
	local harvestedResourceTable = {}
	local rtype

	if (self:GetResourceType() == "Random") then
		rtype = self:GetRandomOre()

		if (rtype ~= "Nothing") then
			harvestedResourceTable[rtype] = amount
			self:DecreaseOre(amount)
			zrmine.f.CreateInsertEffect(self, rtype)
		end
	else
		local OreChancePool = {}
		local failChance = 100 - zrmine.config.Pickaxe_HarvestChance

		if (failChance > 0) then
			for i = 1, (100 - zrmine.config.Pickaxe_HarvestChance) do
				table.insert(OreChancePool, "Nothing")
			end

			for i = 1, zrmine.config.Pickaxe_HarvestChance do
				table.insert(OreChancePool, self:GetResourceType())
			end
		end

		rtype = table.Random(OreChancePool)

		--rtype = self:GetResourceType()
		if (rtype ~= "Nothing") then
			harvestedResourceTable[rtype] = amount
			self:DecreaseOre(amount)
			zrmine.f.CreateInsertEffect(self, rtype)
		end
	end

	return harvestedResourceTable
end

-- Save
local function Save_Ore_Spawner()
	local data = {}

	for u, j in pairs(ents.FindByClass("zrms_ore")) do
		table.insert(data, {
			class = j:GetClass(),
			pos = j:GetPos(),
			ang = j:GetAngles(),
			rtype = j:GetResourceType(),
			ramount = j:GetMax_ResourceAmount()
		})
	end

	if not file.Exists("zrms", "DATA") then
		file.CreateDir("zrms")
	end

	file.Write("zrms/" .. game.GetMap() .. "_OreSpawns" .. ".txt", util.TableToJSON(data))
end

local function Load_Ore_Spawner()
	if file.Exists("zrms/" .. game.GetMap() .. "_OreSpawns" .. ".txt", "DATA") then
		local data = file.Read("zrms/" .. game.GetMap() .. "_OreSpawns" .. ".txt", "DATA")
		data = util.JSONToTable(data)

		for k, v in pairs(data) do
			local oreSpawner = ents.Create("zrms_ore")
			oreSpawner:SetPos(v.pos)
			oreSpawner:SetAngles(v.ang)
			oreSpawner:SetResourceType(v.rtype)
			oreSpawner:SetResourceAmount(v.ramount)
			oreSpawner:SetMax_ResourceAmount(v.ramount)
			oreSpawner:Spawn()
		end

		print("[Zeros Retro MiningSystem] Finished loading OreSpawn entities.")
	else
		print("[Zeros Retro MiningSystem] No map data found for ResourceOre entities. Please place some and do !savezrms to create the data.")
		end
	end

	hook.Add("InitPostEntity", "zrms_SpawnOreSpawner", Load_Ore_Spawner)
	hook.Add("PostCleanupMap", "zrms_SpawnOreSpawnerPostCleanUp", Load_Ore_Spawner)

	hook.Add("PlayerSay", "zrms_HandleConCanCommands", function(ply, text)
		if string.sub(string.lower(text), 1, 9) == "!savezrms" then
			if zrmine.f.IsAdmin(ply) then
				Save_Ore_Spawner()
				zrmine.f.Notify(ply, "Ore Spawner´s have been saved for the map " .. game.GetMap() .. "!", 0)
			else
				zrmine.f.Notify(ply, "You do not have permission to perform this action, please contact an admin.", 1)
				end
			end
		end)

		concommand.Add("zrmine_spawn", function(ply, cmd, args)
			if zrmine.f.IsAdmin(ply) then
				Save_Ore_Spawner()
				zrmine.f.Notify(ply, "Ore Spawner´s have been saved for the map " .. game.GetMap() .. "!", 0)
			else
				zrmine.f.Notify(ply, "You do not have permission to perform this action, please contact an admin.", 1)
				end
			end)
