-- kirovets.lua
--
-- Author Aluha74rus

-- 08.06.2020
--

kirovets = {};

local kirovets_directory = g_currentModDirectory;


function kirovets.prerequisitesPresent(specializations)
    return true;
end
function kirovets.registerEventListeners(vehicleType)	
	SpecializationUtil.registerEventListener(vehicleType, "onLoad",       kirovets);
	SpecializationUtil.registerEventListener(vehicleType, "onDelete",     kirovets)
	SpecializationUtil.registerEventListener(vehicleType, "onUpdate",     kirovets)
	SpecializationUtil.registerEventListener(vehicleType, "onUpdateTick", kirovets)
	SpecializationUtil.registerEventListener(vehicleType, "stopMotor",    kirovets)
end
function kirovets.registerFunctions(vehicleType)
    SpecializationUtil.registerFunction(vehicleType, "playCabAnim",         kirovets.playCabAnim)
end
function kirovets:onLoad(savegame)
	
    if self.isClient then
        local RezimiVibraciyaIndex = getXMLString(self.xmlFile, "vehicle.motorized.RezimiVibraciya#node");
        if RezimiVibraciyaIndex ~= nil then
            self.RezimiVibraciya = {};
            self.RezimiVibraciya.node = I3DUtil.indexToObject(self.components, RezimiVibraciyaIndex, self.i3dMappings)
            self.RezimiVibraciya.maxRot = MathUtil.degToRad(Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.motorized.RezimiVibraciya#maxRot"),0));
        end
        local KppVibraciyaIndex = getXMLString(self.xmlFile, "vehicle.motorized.KppVibraciya#node");
        if KppVibraciyaIndex ~= nil then
            self.KppVibraciya = {};
            self.KppVibraciya.node = I3DUtil.indexToObject(self.components, KppVibraciyaIndex, self.i3dMappings)
            self.KppVibraciya.maxRot = MathUtil.degToRad(Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.motorized.KppVibraciya#maxRot"),0));
        end
        local TahometrVibraciyaIndex = getXMLString(self.xmlFile, "vehicle.motorized.TahometrVibraciya#node");
        if TahometrVibraciyaIndex ~= nil then
            self.TahometrVibraciya = {};
            self.TahometrVibraciya.node = I3DUtil.indexToObject(self.components, TahometrVibraciyaIndex, self.i3dMappings)
            self.TahometrVibraciya.maxRot = MathUtil.degToRad(Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.motorized.TahometrVibraciya#maxRot"),0));
        end
    end
    self.leverFoldableControlMaxTimeout = 11000
    self.leverFoldableMaxTime = 0
    self.leverFoldableMax = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.kirovets.leverFoldableMax#node"));
    self.leverFoldableControlMinTimeout = 11000
    self.leverFoldableMinTime = 0
    self.leverFoldableMin = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.kirovets.leverFoldableMin#node"));
	
    self.massaLights = {}
    self.massaLights.lightShaderNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.lights.massaLights.light#shaderNode"))
    self.massaLights.intensity = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.lights.massaLights.light#intensity")) or 1000
    self.massaLights.lightNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.lights.massaLights.light#node"))
    self.massaLights.realLightNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.lights.massaLights.realLight#node"))
    if self.massaLights.realLightNode ~= nil then
        light.defaultColor = {getLightColor(self.massaLights.realLightNode)}
        setVisibility(realLightNode, false)
    end
    if self.massaLights.lightNode ~= nil then
        setVisibility(self.massaLights.lightNode, false)
    end
    self.massaLightsAktive = false
	
    self.cabAnims = {};
    local baseString = string.format("vehicle.kirovets.");
	
    if hasXMLProperty(self.xmlFile, "vehicle.kirovets.cabAnims") then
        self.cabAnims.knopkaStart = getXMLString(self.xmlFile,baseString.."cabAnims.mainAnimations#knopkaStart");
        self.cabAnims.knopkaStop =  getXMLString(self.xmlFile,baseString.."cabAnims.mainAnimations#knopkaStop");
        self.cabAnims.knopkaMassa = getXMLString(self.xmlFile,baseString.."cabAnims.mainAnimations#knopkaMassa");
        
        self.cabAnims.lights = {};
        i=0;
        while true do
            self.cabAnims.lights[i] = getXMLString(self.xmlFile,baseString..string.format("cabAnims.mainAnimations.lights#animName%d", i));
            if self.cabAnims.lights[i] == nil then
                break;
            end
            i=i+1;
        end
    end
	
    local klawishaPoworotNode = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.enterable.klawishaPoworot#node"));
    if klawishaPoworotNode ~= nil then
        self.klawishaPoworot = {};
        self.klawishaPoworot.node = klawishaPoworotNode;
        local x, y, z = StringUtil.getVectorFromString(getXMLString(self.xmlFile, "vehicle.enterable.klawishaPoworot#minRot"));
        self.klawishaPoworot.minRot = {};
        self.klawishaPoworot.minRot[1] = MathUtil.degToRad(Utils.getNoNil(x, 0));
        self.klawishaPoworot.minRot[2] = MathUtil.degToRad(Utils.getNoNil(y, 0));
        self.klawishaPoworot.minRot[3] = MathUtil.degToRad(Utils.getNoNil(z, 0));

        local x, y, z = StringUtil.getVectorFromString(getXMLString(self.xmlFile, "vehicle.enterable.klawishaPoworot#rotLeft"));
        self.klawishaPoworot.leftRot = {};
        self.klawishaPoworot.leftRot[1] = MathUtil.degToRad(Utils.getNoNil(x, 0));
        self.klawishaPoworot.leftRot[2] = MathUtil.degToRad(Utils.getNoNil(y, 0));
        self.klawishaPoworot.leftRot[3] = MathUtil.degToRad(Utils.getNoNil(z, 0));

        local x, y, z = StringUtil.getVectorFromString(getXMLString(self.xmlFile, "vehicle.enterable.klawishaPoworot#rotRight"));
        self.klawishaPoworot.rightRot = {};
        self.klawishaPoworot.rightRot[1] = MathUtil.degToRad(Utils.getNoNil(x, 0));
        self.klawishaPoworot.rightRot[2] = MathUtil.degToRad(Utils.getNoNil(y, 0));
        self.klawishaPoworot.rightRot[3] = MathUtil.degToRad(Utils.getNoNil(z, 0));

        self.klawishaPoworot.rotTime = Utils.getNoNil(getXMLString(self.xmlFile, "vehicle.enterable.klawishaPoworot#rotTime"), 1)*1000;
		self.klawishaPoworot.lastDir = 1;
    end
	
	-- Rezimi
	self.Rezimi = {};
	self.Rezimi = I3DUtil.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.motorized.Rezimi#node"));
	if self.Rezimi ~= nil then
		self.ForwRot =  MathUtil.degToRad(Utils.getNoNil(getXMLFloat(self.xmlFile,  "vehicle.motorized.Rezimi#Wpered")));
		self.BackwRot = MathUtil.degToRad(Utils.getNoNil(getXMLFloat(self.xmlFile,  "vehicle.motorized.Rezimi#Nazad")));
		self.RightRot = MathUtil.degToRad(Utils.getNoNil(getXMLFloat(self.xmlFile,  "vehicle.motorized.Rezimi#Prawo")));
		self.LeftRot =  MathUtil.degToRad(Utils.getNoNil(getXMLFloat(self.xmlFile,  "vehicle.motorized.Rezimi#Lewo")));
		self.GangMoveSpeed = 	 Utils.getNoNil(getXMLFloat(self.xmlFile,  "vehicle.motorized.Rezimi#moveSpeed"))/10000;
        self.NEUTRALSTELLUNG = false; self.Forwards = false; self.Gang1 = false; self.Gang2 = false; self.Gang3 = false; self.Gang4 = false; self.Gang3Mitte = false; self.Gang3RMitte = false; self.Gang3Rechts = false; self.GangLinks = false; self.GangRechts = false; self.Gang3RLinks = false; self.Backwards = false;    self.LEVEL1 = false; self.LEVEL2 = false; self.LEVEL3 = false; self.LEVEL4 = false; self.LEVEL1R = false; self.LEVEL2R = false;    self.LEVEL3R = false;
    end;
	
    local KPPIndex = getXMLString(self.xmlFile, "vehicle.motorized.KPP#node");
    if KPPIndex ~= nil then
        self.KPP = {};
        self.KPP.node = I3DUtil.indexToObject(self.components, KPPIndex, self.i3dMappings)
    end	
end
function kirovets:onDelete()
    if self.isClient then
    end
end
function kirovets:onUpdate(dt, isActiveForInput, isSelected)
    if self.massaLightsAktive then
        local value = 1
        local _,y,z,w = getShaderParameter(self.massaLights.lightShaderNode, "lightControl")
        setShaderParameter(self.massaLights.lightShaderNode, "lightControl", math.max(value*self.massaLights.intensity, 1), y, z, w, false)
    elseif not self.massaLightsAktive then
        value = 0
        local _,y,z,w = getShaderParameter(self.massaLights.lightShaderNode, "lightControl")
        setShaderParameter(self.massaLights.lightShaderNode, "lightControl", math.max(value*self.massaLights.intensity, 0), y, z, w, false)
    end
	
    local KlawishaMassaEnableTimeStartDelay = 500;
	local KlawishaMassaEnableTime = (self.spec_motorized.motorStartTime - self.spec_motorized.motorStartDuration) + KlawishaMassaEnableTimeStartDelay;
	
    local KlawishaStartEnableTimeStartDelay = 1000;
	local KlawishaStartEnableTime = (self.spec_motorized.motorStartTime - self.spec_motorized.motorStartDuration) + KlawishaStartEnableTimeStartDelay;
	local Duration = 2040;
	local DisableTime = KlawishaStartEnableTime + Duration;
	
    local massaLightsEnableTimeStartDelay = 2040;
	local massaLightsEnableTime = (self.spec_motorized.motorStartTime - self.spec_motorized.motorStartDuration) + massaLightsEnableTimeStartDelay;
    if self.isClient then
	
		if self.cabAnims.knopkaMassa ~= nil then
		    if (g_currentMission.time <= KlawishaMassaEnableTime  and self.spec_motorized.isMotorStarted) then
                self:playCabAnim(self.cabAnims.knopkaMassa, 1);
		    else 
                self:playCabAnim(self.cabAnims.knopkaMassa, -1);
		    end
		end
		
		if self.cabAnims.knopkaStart ~= nil then
		    if (g_currentMission.time <= DisableTime and g_currentMission.time >= KlawishaStartEnableTime  and self.spec_motorized.isMotorStarted) then
                self:playCabAnim(self.cabAnims.knopkaStart, 1);
		    else
				self.massaLightsAktive = false
                self:playCabAnim(self.cabAnims.knopkaStart, -1);
		    end
		end
		
		if (g_currentMission.time <= massaLightsEnableTime  and self.spec_motorized.isMotorStarted) then
			self.massaLightsAktive = true
		else
			self.massaLightsAktive = false
		end
        
        if self.cabAnims.lights ~= nil then
            for i=0, self.spec_lights.numLightTypes do 
                if bitAND(self.spec_lights.lightsTypesMask, 2^i) ~= 0 then
                    self:playCabAnim(self.cabAnims.lights[i], 1);
                else
                    self:playCabAnim(self.cabAnims.lights[i], -1);
                end
            end
        end
	end
	
	if self.spec_motorized.isMotorStarted  then
		
		-- if self.cabAnims.knopkaStop ~= nil  and self.spec_motorized.isMotorStarted then
                self:playCabAnim(self.cabAnims.knopkaStop, 1);
		    else
                self:playCabAnim(self.cabAnims.knopkaStop, -1);
		    end
		-- end
		
        local speed = self.lastSpeedReal*3600;
        if self.KPP ~= nil  then    
            if speed < 0.1 then
                setRotation(self.KPP.node, MathUtil.degToRad(10),   MathUtil.degToRad(0), MathUtil.degToRad(0));
            else
			    if speed >= 0.1 and speed < 0.3 then
                    setRotation(self.KPP.node, MathUtil.degToRad(-7), MathUtil.degToRad(0), MathUtil.degToRad(0));
                elseif speed >= 0.3 and speed < 8 then
                    setRotation(self.KPP.node, MathUtil.degToRad(-14), MathUtil.degToRad(0), MathUtil.degToRad(0));
                elseif speed >= 8 and speed < 22 then
                    setRotation(self.KPP.node, MathUtil.degToRad(-21), MathUtil.degToRad(0), MathUtil.degToRad(0));
                elseif speed >= 22 and speed < 35 then
                    setRotation(self.KPP.node, MathUtil.degToRad(-28),  MathUtil.degToRad(0), MathUtil.degToRad(0));
                end;
            end;
        end;
-- Rezimi ---------------------------------------------------------------
	        local Gx, Gy, Gz = getRotation(self.Rezimi);
	---------- HOCHSCHALTEN -------------------------------------------
			if self.movingDirection > 0 then
			    self.Forwards = true;
                local speed = self.lastSpeedReal*3600;
			
				-- GANG 1 --------------------
				if speed >= 0.3 and self.Gang4 == false then
					self.LEVEL3 = true;
					if self.Gang3Mitte == false and self.Gang3 == false then
						Gx = Gx + (dt * self.GangMoveSpeed);	-- Gang in Neutralstellung
						if Gx >= 0 then
							Gx = 0;
							self.Gang3Mitte = true;
						end;
					elseif  self.Gang3Mitte == true and self.Gang3Rechts == false then
						Gz = Gz + (dt * self.GangMoveSpeed);	-- Gang nach rechts
						if Gz >= self.RightRot then
							Gz = self.RightRot;
							self.Gang3Rechts = true;
							self.Gang3Mitte = false;
				            g_soundManager:playSample(self.sampleRev,1.5*dt);
						end;
					elseif  self.Gang3Rechts == true and self.Gang3 == false then	
						Gx = Gx + (dt * self.GangMoveSpeed);	-- Gang nach vorne
						if Gx >= self.ForwRot then
							Gx = self.ForwRot;
							self.Gang3Mitte = false;
                            self.Gang3Rechts = false;									
							self.Gang3 = true;			
						end;
			    -- GANG 4 --------------------
					elseif speed > 30 and self.Gang3 == true and self.Gang4 == false then
						Gx = Gx - (dt * self.GangMoveSpeed);	-- Gang nach hinten
						if Gx <= self.BackwRot then
							Gx = self.BackwRot;
							self.Gang4 = true;
							self.Gang3 = false;
							self.Gang3Mitte = false;
							self.Gang3Rechts = false;
							self.LEVEL3 = false;
						end;
                    end;
	---------- RUNTERSCHALTEN -------------------------------------------
	            -- GANG 3 --------------------	
				elseif speed < 30 and self.Gang4 == true and self.Gang3 == false then
					Gx = Gx + (dt * self.GangMoveSpeed);	-- Gang nach vorne
					if Gx >= self.ForwRot then
						Gx = self.ForwRot;				        
				        self.Gang4 = false;
				        self.Gang3 = true;
						self.Gang3RMitte = false;
						self.Gang3RLinks = false;
					end;
				-- GANG 2 --------------------
				elseif (self.LEVEL2R or speed < 20) and self.Gang3 == true then
				self.LEVEL2R = true;
					if self.Gang3RMitte == false then
    					Gx = Gx - (dt * self.GangMoveSpeed);	-- Gang nach hinten
						if Gx <= 0 then
							Gx = 0;
							self.Gang3RMitte = true;
							self.Gang3RLinks = false;
						end;
					elseif self.Gang3RMitte == true and self.Gang3RLinks == false then
						Gz = Gz - (dt * self.GangMoveSpeed);	-- Gang nach links
						if Gz <= 0 then
							Gz = 0;
							self.Gang3RLinks = true;
							self.Gang3RMitte = false;
							self.Gang3 = false;
							self.Gang4 = false;								
						end;
					end;
				end;
			
	---------- RÜCKWÄRTSGANG -------------------------------------------	
			elseif self.movingDirection < 0 then
				self.Backwards = true;
				if self.NEUTRALSTELLUNG == true then
					if self.GangLinks == false then
						Gz = Gz - (dt * self.GangMoveSpeed);	-- Gang nach links
						if Gz <= self.LeftRot then
							Gz = self.LeftRot;
							self.GangLinks = true;
						end;
					elseif self.GangLinks == true then
						Gx = Gx + (dt * self.GangMoveSpeed);	-- Gang nach vorne
						if Gx >= self.BackwRot then
							Gx = self.BackwRot;
						end;
					end;
			        else self.NEUTRALSTELLUNG = false;
				end;
					
	---------- NEUTRALSTELLUNG -------------------------------------------
			else
				if Gx > 0 then
					Gx = Gx - (dt * self.GangMoveSpeed);	-- Gang nach hinten
					if Gx <= 0 then
						Gx = 0;
					end;
				elseif Gx < 0 then
					Gx = Gx + (dt * self.GangMoveSpeed);	-- Gang nach hinten
					if Gx >= 0 then
						Gx = 0;
					end;
				elseif Gx == 0 and Gz > 0 then
					Gz = Gz - (dt * self.GangMoveSpeed);	-- Gang nach links
					if Gz <= 0 then
						Gz = 0;
					end;
				elseif Gx == 0 and Gz < 0 then
					Gz = Gz + (dt * self.GangMoveSpeed);	-- Gang nach rechts
					if Gz >= 0 then
						Gz = 0;
					end;
				elseif Gx == 0 and Gz == 0 then
					self.NEUTRALSTELLUNG = true; self.Forwards = false; self.Gang1 = false; self.Gang2 = false; self.Gang3 = false; self.Gang4 = false; self.Gang3Mitte = false; self.Gang3RMitte = false; self.Gang3Rechts = false; self.GangLinks = false; self.GangRechts = false; self.Gang3RLinks = false; self.Backwards = false; self.LEVEL1 = false; self.LEVEL2 = false; self.LEVEL3 = false; self.LEVEL4 = false; self.LEVEL1R = false; self.LEVEL2R = false; self.LEVEL3R = false;
				end;
	        end;
		setRotation(self.Rezimi, Gx, Gy, Gz);
end
function kirovets:onUpdateTick(dt, isActiveForInput, isSelected)

    if self.isClient then
        if self:getIsMotorStarted() then
	        if self.RezimiVibraciya ~= nil then
	            local minRandom = -0.1;
	            local maxRandom = 0.1;
	            local angle = MathUtil.lerp(minRandom, maxRandom, math.random()) + self.RezimiVibraciya.maxRot * (self.spec_motorized.motor:getEqualizedMotorRpm() / self.spec_motorized.motor:getMaxRpm());
	            angle = MathUtil.clamp(angle, 0, self.RezimiVibraciya.maxRot);
	            setRotation(self.RezimiVibraciya.node, 0, 0, angle);
	        end
	        if self.KppVibraciya ~= nil then
	            local minRandom = -0.1;
	            local maxRandom = 0.1;
	            local angle = MathUtil.lerp(minRandom, maxRandom, math.random()) + self.KppVibraciya.maxRot * (self.spec_motorized.motor:getEqualizedMotorRpm() / self.spec_motorized.motor:getMaxRpm());
	            angle = MathUtil.clamp(angle, 0, self.KppVibraciya.maxRot);
	            setRotation(self.KppVibraciya.node, 0, 0, angle);
	        end
	        if self.TahometrVibraciya ~= nil then
	            local minRandom = -0.5;
	            local maxRandom = 0.5;
	            local angle = MathUtil.lerp(minRandom, maxRandom, math.random()) + self.TahometrVibraciya.maxRot * (self.spec_motorized.motor:getEqualizedMotorRpm() / self.spec_motorized.motor:getMaxRpm());
	            angle = MathUtil.clamp(0, angle, self.TahometrVibraciya.maxRot);
	            setRotation(self.TahometrVibraciya.node, 0, angle, 0);
	        end
        end
    end
    if self:getIsActive() then
        if self.spec_lights.turnLightState ~= nil then
			if self.klawishaPoworot ~= nil then
				local dir = 0;
				local hasRotChanged = false;
				local destRot = self.klawishaPoworot.minRot;
				
				if self.spec_lights.turnLightState == 1 then
					destRot = self.klawishaPoworot.leftRot;
					dir = 1;
				elseif self.spec_lights.turnLightState == 2 then
					destRot = self.klawishaPoworot.rightRot;
					dir = -1;
				end
				if self.klawishaPoworot.lastDir ~= dir then
					self.klawishaPoworot.lastDir = dir;
					self.klawishaPoworot.rotatingTime = 0;
				end
				
				if self.klawishaPoworot.rotatingTime ~= nil then
					self.klawishaPoworot.rotatingTime = self.klawishaPoworot.rotatingTime + dt;
					local t = math.min(1.0, self.klawishaPoworot.rotatingTime / self.klawishaPoworot.rotTime);
					if t == 1 then
						self.klawishaPoworot.rotatingTime = nil;
					end
					local rot = {getRotation(self.klawishaPoworot.node)};
					
					local rx1,ry1,rz1,rw1 = mathEulerToQuaternion(unpack(rot));
					local rx2,ry2,rz2,rw2 = mathEulerToQuaternion(unpack(destRot));
					
					local qx,qy,qz,qw = MathUtil.nlerpQuaternionShortestPath(rx1,ry1,rz1,rw1, rx2,ry2,rz2,rw2, t);
					setQuaternion(self.klawishaPoworot.node, qx,qy,qz,qw);
				end
			end;
		end;
	end;
end
function kirovets:playCabAnim(animName, animSpeed)    
    local animTime = self:getAnimationTime(animName);
    if not self:getIsAnimationPlaying(animName) then    
        self:playAnimation(animName, animSpeed, animTime, true);
    end
end
function kirovets:stopMotor(noEventSend)
	if self.isClient then
	    if self.TahometrVibraciya ~= nil then
	        setRotation(self.TahometrVibraciya.node, 0, 0, 0);
	    end
	    if self.RezimiVibraciya ~= nil then
	        setRotation(self.RezimiVibraciya.node, 0, 0, 0);
	    end
	    if self.KppVibraciya ~= nil then
	        setRotation(self.KppVibraciya.node, 0, 0, 0);
	    end
    end
end