-- Bahnuebergang Trigger
-- @author: Sven777b
-- @date: 25.09.2010

     print("  Map: Zugschranke geladen"); 

Bahnuebergang = {};

_G.Bahnuebergang = Bahnuebergang;
function Bahnuebergang.onCreate(id)
	if _G.uebergaenge == nil then
		_G.uebergaenge = {};
	end;
	table.insert(_G.uebergaenge, Uebergang:new(id));
end;

function Bahnuebergang:update(dt)
	if _G.uebergaenge ~= nil then
		for k,v in pairs(_G.uebergaenge) do
			v:update(dt);
		end;
	end;
end;

function Bahnuebergang:delete()
end;
function Bahnuebergang:loadMap(name)
end;
function Bahnuebergang:deleteMap()
end;
function Bahnuebergang:mouseEvent(posX, posY, isDown, isUp, button)
end;
function Bahnuebergang:keyEvent(unicode, sym, modifier, isDown)
end;
function Bahnuebergang:draw()
end;


Uebergang = {};
local Uebergang_mt = Class(Uebergang);

function Uebergang:new(id, customMt)
    local instance = {};
    if customMt ~= nil then
        setmetatable(instance, customMt);
    else
        setmetatable(instance, Uebergang_mt);
    end;
		--Trigger
    local t1 = getUserAttribute(id, "trigger1");
    local t2 = getUserAttribute(id, "trigger2");
    if t1 ~= nil and t2 ~= nil then
    	instance.trigger1 = Utils.indexToObject(id, t1);
    	instance.trigger2 = Utils.indexToObject(id, t2);
    	addTrigger(instance.trigger1, "triggerCallback", instance);
    	addTrigger(instance.trigger2, "triggerCallback", instance);
    end;
		--Warnlichter
    local c=1;
    instance.lichter = {};
    instance.warnlicht = false;
    instance.WLtimer = 0;
    instance.WLphase = true;
    instance.LDtimer = 0;
    instance.EDtimer = 0;
    while true do
    	local l1 = getUserAttribute(id, "warnlicht"..c);
    	if l1 == nil then break; end;
    	local idL = Utils.indexToObject(id, l1);
    	local numc = getNumOfChildren(idL);
    	if numc > 0 then
    		local licht = {};
    		licht.typ = Utils.getNoNil(getUserAttribute(idL, "typ"),1);
    		licht.ls = {};
    		for child=0,(numc-1) do
    			li = getChildAt(idL,child);
    			if li ~= nil then
		    		table.insert(licht.ls, li);
		    	end;
		    end;
    		table.insert(instance.lichter,licht);
	    end;
    	c=c+1;
    end;
		--Schranken
		local c=1;
		instance.schranken = {};
		instance.schrankenRunter = false;
		instance.schrankenUnten = false;
		instance.schrankenOben = false;
		while true do
			local s = getUserAttribute(id, "schranke"..c);
			if s == nil then break; end;
			local sidx = Utils.indexToObject(id,s);
			if sidx ~= nil then
				local schranke = {};
				schranke.idx = sidx;
				schranke.zeit = Utils.getNoNil(getUserAttribute(sidx,"zeit"),5)*1000;
				local x,y,z = Utils.getVectorFromString(getUserAttribute(sidx, "min"));
				schranke.min = {};
				schranke.min[1] = Utils.getNoNil(math.rad(x),0);
				schranke.min[2] = Utils.getNoNil(math.rad(y),0);
				schranke.min[3] = Utils.getNoNil(math.rad(z),0);
				x,y,z = Utils.getVectorFromString(getUserAttribute(sidx, "max"));
				schranke.max = {};
				schranke.max[1] = Utils.getNoNil(math.rad(x),0);
				schranke.max[2] = Utils.getNoNil(math.rad(y),0);
				schranke.max[3] = Utils.getNoNil(math.rad(z),0);
				table.insert(instance.schranken,schranke);
			end;
			c=c+1;
		end;
		--Traffic Collisions
		instance.trafficCol = Utils.indexToObject(id, getUserAttribute(id, "trafficCollision"));
		instance.trafficColPos = {getTranslation(instance.trafficCol)};
		g_currentMission.nodeToVehicle[instance.trafficCol] = {};
		local nc = getNumOfChildren(instance.trafficCol);
		for c=0,(nc-1) do
			local childid = getChildAt(instance.trafficCol,c);
			g_currentMission.nodeToVehicle[childid] = {};
		end;
		--Sounds
		instance.sounds = {};
		instance.soundsRunning = {};
		for c=1,3 do
			local s = getUserAttribute(id, "sound"..c);
			if s ~= nil then
				instance.sounds[c] = Utils.indexToObject(id,s);
				setVisibility(instance.sounds[c],false);
				instance.soundsRunning[c] = false;
			end;
		end;
		
		instance.leaveDelay = Utils.getNoNil(getUserAttribute(id, "leaveDelay"),0)*1000;
		instance.enterDelay = Utils.getNoNil(getUserAttribute(id, "enterDelay"),0)*1000;
    instance.onTrack = {};
    instance.TrainsOnTrack = 0;
    instance.isEnabled = true;
    
    return instance;
end;

function Uebergang:update(dt)
	if self.isEnabled then

		if self.TrainsOnTrack > 0 then
--TrainsOnTrack
			self.LDtimer = 0;
			--warnlichter an
			if not self.warnlicht then
				setTranslation(self.trafficCol,unpack(self.trafficColPos));
				self.warnlicht = true;
				self.WLtimer = 0;
				self.EDtimer = 0;
				self.WLphase = true;
				if self.sounds[1] ~= nil then
					setVisibility(self.sounds[1], true);
					self.soundsRunning[1] = true;
				end;
			end;
			--Schranken zu
			if self.EDtimer > self.enterDelay then
				if not self.schrankenUnten then
					if self.sounds[2] ~= nil and not self.soundsRunning[2] then
						setVisibility(self.sounds[2],true);
						self.soundsRunning[2] = true;
					end;
					self.schrankenOben = false;
					local alleSchrankenUnten = true;
					for s=1,table.getn(self.schranken) do
						local schranke = self.schranken[s];
						local crot = {getRotation(schranke.idx)};
						local nrot = Utils.getMovedLimitedValues(crot,schranke.max,schranke.min,3,schranke.zeit,dt,false);
						setRotation(schranke.idx,unpack(nrot));
						for i=1,3 do
							if math.abs(math.abs(crot[i])-math.abs(nrot[i])) > 0.001 then
								alleSchrankenUnten = false;
							end;
						end;
					end;
					self.schrankenUnten = alleSchrankenUnten;
				else
					if self.soundsRunning[1] then
						setVisibility(self.sounds[1],false);
						self.soundsRunning[1] = false;
					end;
					if self.soundsRunning[2] then
						setVisibility(self.sounds[2],false);
						self.soundsRunning[2] = false;
					end;
				end;
			else
				self.EDtimer = self.EDtimer + dt;
			end;
--TrainsOnTrack
		else
--NoTrainsOnTrack
			self.LDtimer = self.LDtimer + dt;
			--Schranken hoch
			if self.LDtimer > self.leaveDelay then
				if not self.schrankenOben then
					if self.sounds[3] ~= nil and not self.soundsRunning[3] then
						setVisibility(self.sounds[3],true);
						self.soundsRunning[3] = true;
					end;
					self.schrankenUnten = false;
					local alleSchrankenOben = true;
					for s=1,table.getn(self.schranken) do
						local schranke = self.schranken[s];
						local crot = {getRotation(schranke.idx)};
						local nrot = Utils.getMovedLimitedValues(crot,schranke.max,schranke.min,3,schranke.zeit,dt,true);
						setRotation(schranke.idx,unpack(nrot));
						for i=1,3 do
							if math.abs(math.abs(crot[i])-math.abs(nrot[i])) > 0.001 then
								alleSchrankenOben = false;
							end;
						end;
					end;
					self.schrankenOben = alleSchrankenOben;
				end;
				--Warnlichter aus	
				if self.warnlicht and self.schrankenOben then
					if self.soundsRunning[3] then
						setVisibility(self.sounds[3],false);
						self.soundsRunning[3] = false;
					end;
					for l=1,table.getn(self.lichter) do
						local licht = self.lichter[l];
						for i=1,table.getn(licht.ls) do
							setVisibility(licht.ls[i], false);
						end;
					end;
					self.warnlicht = false;
					local p = self.trafficColPos;
					setTranslation(self.trafficCol,p[1],(p[2]+10),p[3]);
				end;
			end;
--NoTrainsOnTrack
		end;

		if self.warnlicht then
			self.WLtimer = self.WLtimer + dt;
			if self.WLtimer > 500 then
				self.WLphase = not self.WLphase;
				self.WLtimer = 0;
			end;
				
			for l=1,table.getn(self.lichter) do
				local licht = self.lichter[l];
				if licht.typ==1 then
					setVisibility(licht.ls[1], self.WLphase);
				end;
			end;
		end;
		
	end;
end;

function Uebergang:triggerCallback(triggerId, otherId, onEnter, onLeave, onStay)
    if onEnter and self.isEnabled then
        if self.onTrack[otherId] == nil then
        	self.onTrack[otherId] = triggerId;
        	self.TrainsOnTrack = tablecount(self.onTrack);
        elseif self.onTrack[otherId] ~= triggerId then
        	self.onTrack[otherId] = nil;
        	self.TrainsOnTrack = tablecount(self.onTrack);
        end;
    end;
end;

addModEventListener(Bahnuebergang);
g_onCreateUtil.addOnCreateFunction("BahnuebergangOnCreate", Bahnuebergang.onCreate);


function tablecount(tab)
	local c = 0;
	for k,v in pairs(tab) do
		c = c + 1;
	end;
	return c;
end;