/*
	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
AddCSLuaFile("cl_init.lua");
AddCSLuaFile("shared.lua");
include("shared.lua");
include("modules/dialling.lua");
--################# Defines
-- Models
ENT.Models = {
	Base="models/zup/stargate/sga_base.mdl",
	Chevron={
		"models/zup/stargate/sga_chev1.mdl",
		"models/zup/stargate/sga_chev2.mdl",
		"models/zup/stargate/sga_chev3.mdl",
		"models/zup/stargate/sga_chev4.mdl",
		"models/zup/stargate/sga_chev5.mdl",
		"models/zup/stargate/sga_chev6.mdl",
		"models/zup/stargate/sga_chev7.mdl",
	},
	Dial={
		"models/zup/stargate/sga_dial_part1.mdl",
		"models/zup/stargate/sga_dial_part2.mdl",
	},
	Incoming={
		"models/zup/stargate/sga_incoming_part1.mdl",
		"models/zup/stargate/sga_incoming_part2.mdl",
	},
}
-- Sounds
ENT.Sounds = {
	Ring=Sound("stargate/gate_roll_atlantis.mp3"),
	Open=Sound("stargate/gate_open_atlantis.mp3"),
	Travel=Sound("stargate/gate_travel.mp3"),
	Close=Sound("stargate/gate_close.mp3"),
	Chevron=Sound("stargate/chevron_atlantis.mp3"),
	Inbound=Sound("stargate/chevron_atlantis_incoming.mp3"),
	Lock=Sound("stargate/chevron_lock_atlantis.mp3"),
	LockInbound=Sound("stargate/chevron_lock_atlantis_incoming.mp3"),
	Fail=Sound("stargate/dial_fail_atlantis.mp3"),
}
-- In which slot do the chevron a lock?
ENT.ChevronLocks = {4,8,12,24,28,32,36,16,20};
ENT.AlwaysFast = true; -- Tells the activation code in stargate_base/events.lua:ActivateStargate() not to add a delay when called by this gate here (Atlantis always dials fast!)
--################# SENT CODE ###############

--################# Init @aVoN
function ENT:Initialize()
	self.Entity:SetModel(self.Models.Base);
	self.Entity:PhysicsInit(SOLID_VPHYSICS);
	self.Entity:SetMoveType(MOVETYPE_VPHYSICS);
	self.Entity:SetSolid(SOLID_VPHYSICS);
	self.BaseClass.Initialize(self); -- BaseClass Initialize call
	self:AddRing();
	self:AddChevron();
end

--################# Either allow the player to spawn this or not
function ENT:SpawnFunction(p,t)
	if (not t.Hit) then return end
	local e = ents.Create("stargate_atlantis");
	e:SetPos(t.HitPos+Vector(0,0,90));
	e:Spawn();
	e:Activate();
	--################# Set correct angle for the spawned prop
	local ang = p:GetAimVector():Angle(); ang.p = 0; ang.r = 0; ang.y = (ang.y+180) % 360
	e:SetAngles(ang);
	e:PutIntoRamps(t);
	return e;
end

--################# Creates the ring for the gate @aVoN
function ENT:AddRing()
	local pos = self.Entity:GetPos();
	self.Ring = {Dial={},Incoming={}};
	for i=1,2 do
		local e = ents.Create("prop_dynamic_override");
		e:SetModel(self.Models.Dial[i]);
		e:SetPos(pos);
		e:SetParent(self.Entity);
		e:SetDerive(self.Entity); -- Derive Material/Color from "Parent"
		e:DrawShadow(false);
		e:Spawn();
		e:Activate();
		self.Ring.Dial[i] = e;
		local e = ents.Create("prop_dynamic_override");
		e:SetModel(self.Models.Incoming[i]);
		e:SetPos(pos);
		e:SetParent(self.Entity);
		e:SetDerive(self.Entity); -- Derive Material/Color from "Parent"
		e:DrawShadow(false);
		e:Spawn();
		e:Activate();
		self.Ring.Incoming[i] = e;
	end
end

--################# Turns on a light on the ring @aVoN
function ENT:RingLight(light,inbound)
	local ring = self.Ring.Dial;
	if(inbound) then ring = self.Ring.Incoming end;
	local part = 1;
	if(light < 0) then
		light = light % 36;
	elseif(light > 36) then
		light = light - 36;
	end
	if(light > 18) then
		part = 2; -- Take second  ring part
		light = light - 18;
		-- Deactivate the other ring part. We don't need it anymore
		ring[1]:Fire("SetBodyGroup",0);
	else
		-- Deactivate the other ring part. We don't need it anymore
		ring[2]:Fire("SetBodyGroup",0);
	end
	ring[part]:Fire("SetBodyGroup",light);
end

--################# Adds all chevrons @aVoN
function ENT:AddChevron()
	self.Chevron={};
	local pos = self.Entity:GetPos();
	for i=1,7 do
		local e = ents.Create("prop_dynamic_override");
		e:SetModel(self.Models.Chevron[i]);
		e:SetParent(self.Entity);
		e:SetDerive(self.Entity); -- Derive Material/Color from "Parent"
		e:DrawShadow(false);
		e:SetPos(pos);
		e:Spawn();
		e:Activate();
		self.Chevron[i] = e;
	end
end

--################# Activates or deactivates a chevron @aVoN
function ENT:ActivateChevron(chev,b,inbound)
	if(not (self and self.Chevron)) then return end;
	if(self.Chevron[chev]) then
		if(b) then
			self.Chevron[chev]:Fire("skin",1);
			if(not inbound) then
				self.Entity:Fire("SetBodyGroup",chev+1);
			end
			self.Entity:SetNWBool("chevron"..chev,true); -- Dynamic light of the chevron
		else
			self.Chevron[chev]:Fire("skin",0);
			self.Entity:Fire("SetBodyGroup",math.Clamp(chev-1,0,7));
			self.Entity:SetNWBool("chevron"..chev,false); -- Dynamic light of the chevron
		end
	end
end

--################# Stops the gate's lights
function ENT:Shutdown()
	if(not (self and self.RingLight)) then return end;
	self:RingLight(0,true);
	self:RingLight(0,false);
	self.Entity:Fire("SetBodyGroup",0,0.05); -- Needs a certain delay
end
