/*
	Stargate Wire/RD Lib for GarrysMod10
	Copyright (C) 2007  aVoN

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

--################# Adds LifeSupport,ResourceDistribution and WireSupport to an entity when getting called - HAS TO BE CALLED BEFORE ANY OTHERTHING IS DONE IN A SENT (like includes) @aVoN
-- My suggestion is to put this on the really top of the shared.lua
StarGate.WireRD = {};
function StarGate.LifeSupportAndWire(ENT)
	ENT.WireDebugName = ENT.WireDebugName or "No Name";
	ENT.HasWire = StarGate.HasWire;
	ENT.HasResourceDistribution = StarGate.HasResourceDistribution;
	ENT.HasRD = StarGate.HasResourceDistribution; -- Quick reference
	
	-- General handlers
	ENT.OnRemove = StarGate.WireRD.OnRemove;
	ENT.OnRestore = StarGate.WireRD.OnRestore;

	-- Wire Handlers
	ENT.CreateWireOutputs = StarGate.WireRD.CreateWireOutputs;
	ENT.CreateWireInputs = StarGate.WireRD.CreateWireInputs;
	ENT.SetWire = StarGate.WireRD.SetWire;
	ENT.GetWire = StarGate.WireRD.GetWire;
	
	-- RD Handling
	ENT.AddResource = StarGate.WireRD.AddResource;
	ENT.GetResource = StarGate.WireRD.GetResource;
	ENT.ConsumeResource = StarGate.WireRD.ConsumeResource;
	ENT.SupplyResource = StarGate.WireRD.SupplyResource;
	ENT.GetUnitCapacity = StarGate.WireRD.GetUnitCapacity;
	ENT.GetNetworkCapacity = StarGate.WireRD.GetNetworkCapacity;
	
	-- For LifeSupport and Resource Distribution and Wire - Makes all connections savable with Duplicator
	ENT.PreEntityCopy = StarGate.WireRD.PreEntityCopy;
	ENT.PostEntityPaste = StarGate.WireRD.PostEntityPaste;
end

--################# What version is installed? @aVoN
local RD; -- QuickIndex
local IsThree;
local function RDThree()
	if(IsThree ~= nil) then return IsThree end;
	if(CAF and CAF.GetAddon("Resource Distribution")) then
		IsThree = true;
		RD = CAF.GetAddon("Resource Distribution");
		return true;
	end
	IsThree = false;
	return false;
end

--################# OnRemove @aVoN
--added compatiblity with RD3 @JDM12989
function StarGate.WireRD.OnRemove(self)
	if(RDThree()) then
		RD.RemoveRDEntity(self.Entity);
	elseif(Dev_Unlink_All and self.resources2links) then
		Dev_Unlink_All(self.Entity);
	end
	if(WireAddon and (self.Outputs or self.Inputs)) then
		Wire_Remove(self.Entity);
	end
end

--################# OnRestore @aVoN
function StarGate.WireRD.OnRestore(self)
	if(WireAddon) then
		Wire_Restored(self.Entity);
	end
end

--##############################
-- Wire handling
--##############################

--################# Creates Wire Outputs @aVoN
function StarGate.WireRD.CreateWireOutputs(self,...)
	if(WireAddon) then
		self.Outputs = Wire_CreateOutputs(self.Entity,{unpack(arg)});
	end
end

--################# Creates Wire Inputs @aVoN
function StarGate.WireRD.CreateWireInputs(self,...)
	if(WireAddon) then
		self.Inputs = Wire_CreateInputs(self.Entity,{unpack(arg)});
	end
end

--################# Sets a Wire value @aVoN
function StarGate.WireRD.SetWire(self,key,value)
	if(WireAddon) then
		-- Supports bools and converts them to numbers
		if(value == true) then 
			value = 1;
		elseif(value == false) then
			value = 0;
		end
		-- If still not a number, make it a num now!
		value = tonumber(value);
		if(value) then
			Wire_TriggerOutput(self.Entity,key,value);
			if(self.WireOutput) then
				self:WireOutput(key,value);
			end
		end
	end
end

--################# Gets a Wire value @aVoN
function StarGate.WireRD.GetWire(self,key,default)
	if(WireAddon) then
		if(self.Inputs[key] and self.Inputs[key].Value) then
			return self.Inputs[key].Value or default or 0;
		end
		return default or 0;
	end
end


--##############################
--  Resource Distribution Handling
--##############################

--################# Register a Resource @aVoN
--added compatiblity with RD3 @JDM12989
function StarGate.WireRD.AddResource(self,resource,maximum,default)
	if(self.HasRD) then
		if(RDThree()) then
			RD.AddResource(self.Entity,resource,maximum or 0,default or 0);
			--FIXME: Add LS3 registering here.
		else
			if(LS_RegisterEnt) then -- Register to life support
				if(not self.__RegisteredToLS) then
					self.__RegisteredToLS = true;
					LS_RegisterEnt(self.Entity,"Generator"); -- Always register this as a generator
				end
			end
			RD_AddResource(self.Entity,resource,maximum or 0);
		end
	end
end

--################# Get a Resource's ammount @aVoN
--added compatiblity with RD3 @JDM12989
function StarGate.WireRD.GetResource(self,resource,default)
	if(self.HasRD) then
		if(RDThree()) then
			return RD.GetResourceAmount(self.Entity,resource) or default or 0;
		else
			return RD_GetResourceAmount(self.Entity,resource) or default or 0;
		end
	end
	return default or 0;
end

--################# Consume some of this resource @aVoN
--added compatiblity with RD3 @JDM12989
function StarGate.WireRD.ConsumeResource(self,resource,ammount)
	if(self.HasRD) then
		if(RDThree()) then
			return RD.ConsumeResource(self.Entity,resource,ammount or 0);
		else
			return RD_ConsumeResource(self.Entity,resource,ammount or 0);
		end
	end
end

--################# Supply a specific ammount to this resource @aVoN
--added compatiblity with RD3 @JDM12989
function StarGate.WireRD.SupplyResource(self,resource,ammount)
	if(self.HasRD) then
		if(RDThree()) then
			RD.SupplyResource(self.Entity,resource,ammount or 0);
		else
			RD_SupplyResource(self.Entity,resource,ammount or 0);
		end
	end
end

--################# This units capacity @aVoN
--added compatiblity with RD3 @JDM12989
function StarGate.WireRD.GetUnitCapacity(self,resource,default)
	if(self.HasRD) then
		if(RDThree()) then
			return RD.GetUnitCapacity(self.Entity,resource) or default or 0;
		else
			return RD_GetUnitCapacity(self.Entity,resource) or default or 0;
		end
	end
	return default or 0;
end

--################# This networks capacity @aVoN
--added compatiblity with RD3 @JDM12989
function StarGate.WireRD.GetNetworkCapacity(self,resource,default)
	if(self.HasRD) then
		if(RDThree()) then
			return RD.GetNetworkCapacity(self.Entity,resource) or default or 0;
		else
			return RD_GetNetworkCapacity(self.Entity,resource) or default or 0;
		end
	end
	return default or 0;
end


--##############################
--  Duplicator handling
--##############################


--################# Store Entity modifiers @aVoN
function StarGate.WireRD.PreEntityCopy(self)
	if(RD_BuildDupeInfo) then RD_BuildDupeInfo(self.Entity) end;
	if(WireAddon) then
		local data = WireLib.BuildDupeInfo(self.Entity);
		if(data) then
			duplicator.StoreEntityModifier(self.Entity,"WireDupeInfo",data);
		end
	end
end

--################# Restore entity modifiers @aVoN
function StarGate.WireRD.PostEntityPaste(self,Player,Ent,CreatedEntities)
	if(RD_ApplyDupeInfo) then RD_ApplyDupeInfo(Ent,CreatedEntities) end;
	if(WireAddon) then
		if(Ent.EntityMods and Ent.EntityMods.WireDupeInfo) then
			WireLib.ApplyDupeInfo(Player,Ent,Ent.EntityMods.WireDupeInfo,function(id) return CreatedEntities[id] end);
		end
	end
end

