/*
	Stargate SENT 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/>.
*/

--################# HEADER #################
include("shared.lua");
ENT.RenderGroup = RENDERGROUP_OPAQUE -- This FUCKING THING avoids the clipping bug I have had for ages since stargate BETA 1.0. DAMN!

ENT.LightPositions = {
	Vector(8,88.2829,104.5427),
	Vector(8,134.7614,23.2695),
	Vector(8,118.6142,-68.3697),
	Vector(8,-118.5464,-68.4004),
	Vector(8,-134.9181,22.6665),
	Vector(8,-86.8867,105.0110),
	Vector(8,0.0461,136.2538),
	Vector(8,47.0651,-128.8588),
	Vector(8,-46.6631,-128.9825),
}
ENT.SpritePositions = {
	Vector(8,84.7845,100.6584),
	Vector(8,128.5390,23.2034),
	Vector(8,114.1802,-65.6066),
	Vector(8,-113.6151,-65.8050),
	Vector(8,-130.3172,22.9665),
	Vector(8,-84.0521,100.6424),
	Vector(8,0.1143,131.3542),
	Vector(8,44.9670,-123.5822),
	Vector(8,-45.0003,-123.5938),
}

ENT.ChevronSprite = StarGate.MaterialFromVMT(
	"ChevronSprite",
	[["Sprite"
	{
		"$spriteorientation" "vp_parallel"
		"$spriteorigin" "[ 0.50 0.50 ]"
		"$basetexture" "sprites/glow04"
		"$spriterendermode" 5
	}]]
);

--################# SENT CODE ###############


--##################################
--#### Name/Address/Private Handling
--##################################


--################# Get the address of this gate @aVoN
-- ATTENTION: Make sure, this will be ALWAYS uppercased!
function ENT:GetGateAddress()
	return self:GetNWString("Address",""):upper();
end

--################# Set a gate address @aVoN
function ENT:SetGateAddress(s)
	if(s and (s:len() == 6 or s == "")) then
		LocalPlayer():ConCommand("_StarGate.SetValue "..self.Entity:EntIndex().." Address \""..s.."\"");
	end
end

--################# Get the name of this gate @aVoN
function ENT:GetGateName()
	return self:GetNWString("Name","");
end

--################# Set the gate's name @aVoN
function ENT:SetGateName(s)
	if(s) then
		LocalPlayer():ConCommand("_StarGate.SetValue "..self.Entity:EntIndex().." Name \""..s.."\"");
	end
end

--################# Is the stargate private? @aVoN
function ENT:GetPrivate()
	return self:GetNWBool("Private",false);
end

--################# Set Private state @aVoN
function ENT:SetPrivate(b)
	LocalPlayer():ConCommand("_StarGate.SetValue "..self.Entity:EntIndex().." Private "..tostring(b));
end

--################# Dials a gate @aVoN
function ENT:DialGate(address,mode)
	if(not mode) then mode = false end; -- Nil seems to be "true'ed" with util.tobool!
	LocalPlayer():ConCommand("_StarGate.SetValue "..self.Entity:EntIndex().." Dial "..tostring(mode).." "..address);
end

--################# Stops Dialling a Gate or closes it  @aVoN
function ENT:AbortDialling()
	LocalPlayer():ConCommand("_StarGate.SetValue "..self.Entity:EntIndex().." AbortDialling true");
end

--##################################
--#### Color and Lights
--##################################

--################# Draws tiny sprites on the gate - Makes it look cooler! @aVoN
-- Does not work with ENT.RenderGroup = RENDERGROUP_OPAQUE
-- It only works with RENDERGROUP_BOTH or RENDERGROUP_TRANLUSCENT
-- But sadly then the ring sometimes clips (Strange behaviour).

function ENT:Draw()
	self.Entity:DrawModel();
	if(not self.ChevronColor) then return end;
	render.SetMaterial(self.ChevronSprite);
	local col = Color(self.ChevronColor.r,self.ChevronColor.g,self.ChevronColor.b,100); -- Decent please -> Less alpha
	for i=1,9 do
		if(self.Entity:GetNWBool("chevron"..i,false)) then
			render.DrawSprite(self.Entity:LocalToWorld(self.SpritePositions[i]),24,24,col);
		end
	end
end

-- And for some obvious reasons, the hooks "Pre/PostDrawOpaque/Translucent" do not work anymore.
-- SO: FUCK OFF SPRITES - We have to life without them

local stargates = {};
function ENT:Initialize()
	table.insert(stargates,self.Entity);
end

local col = Color(0,0,0,255); -- Out here to fight garbage collection issues
hook.Add("RenderScreenspaceEffects","StarGate.Hook.RenderScreenspaceEffects.ChevronSprites",
	function()
		for k,v in pairs(stargates) do
			if(ValidEntity(v)) then
				if(not v.ChevronColor) then return end;
				render.SetMaterial(v.ChevronSprite);
				col.r = v.ChevronColor.r;
				col.g = v.ChevronColor.g;
				col.b = v.ChevronColor.b;
				for i=1,9 do
					if(v.Entity:GetNWBool("chevron"..i,false)) then
						render.DrawSprite(v:LocalToWorld(v.SpritePositions[i]),32,32,col);
					end
				end
			else
				stargates[k] = nil;
			end
		end
	end
);

--################# Think function, to set the gates address @aVoN
function ENT:Think()
	--######### Dynamic Lights, toggleable by the client!
	if(not StarGate.Visuals("cl_stargate_dynlights")) then return end;
	if(self.ChevronColor and (self.NextLight or 0) < CurTime()) then
		self.NextLight = CurTime()+0.001;
		for i=1,9 do
			if(self.Entity:GetNWBool("chevron"..i,false)) then
				-- Clientside lights, yeah! Can be toggled by clients this causes much less lag when deactivated. Method below is from Catdaemon's harvester
				local dlight = DynamicLight(self:EntIndex()..i);
				if(dlight) then
					dlight.Pos = self.Entity:LocalToWorld(self.LightPositions[i]);
					dlight.r = self.ChevronColor.r;
					dlight.g = self.ChevronColor.g;
					dlight.b = self.ChevronColor.b;
					dlight.Brightness = 0.5;
					dlight.Decay = 150;
					dlight.Size = 150;
					dlight.DieTime = CurTime()+1;
				end
			end
		end
	end
end


--##################################
--#### VGUI/Dial Menu
--##################################

local VGUI;
usermessage.Hook("StarGate.OpenDialMenu",
	function(data)
		local e = data:ReadEntity();
		if(ValidEntity(e) and e:GetClass():find("stargate_")) then
			if(not VGUI) then VGUI = vgui.Create("SControlePanel") end;
			VGUI:SetVisible(true);
			VGUI:SetEntity(e);
		end
	end
);

--################# Show the addresse of a gate when set @aVoN
hook.Add("HUDPaint","StarGate.Hook.HUDPaint.ShowAddressAndNames",
	function()
		local x,y = gui.MousePos();
		if(x == 0 and y == 0) then -- Avoids this popping up, if the dial dialogue is opened
			local p = LocalPlayer();
			if(ValidEntity(p)) then
				local trace = LocalPlayer():GetEyeTrace();
				if(trace.Hit and ValidEntity(trace.Entity)) then
					local e = trace.Entity;
					if(e.IsStargate) then
						local address = e:GetGateAddress();
						if(address ~= "") then
							local name = e:GetGateName();
							if(name == "") then name = "N/A" end;
							local message = "Address: "..address.." - Name: "..name;
							draw.WordBox(8,40,ScrH()/2,message,"Default",Color(50,50,75,100),Color(255,255,255,255));
						end
					end
				end
			end
		end
	end
);
