--[[
/*******************************************************************************\
*                                                                               *
* Levitator.lua                                                                 *
*                                                                               *
*********************************************************************************
* Licensed under the MIT or X11 License                                         *
*                                                                               *
* Copyright (c) 2016 Eisbearg                                                   *
*                                                                               *
* Permission is hereby granted, free of charge, to any person obtaining a copy  *
* of this software and associated documentation files (the "Software"), to deal *
* in the Software without restriction, including without limitation the rights  *
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell     *
* copies of the Software, and to permit persons to whom the Software is         *
* furnished to do so, subject to the following conditions:                      *
*                                                                               *
* The above copyright notice and this permission notice shall be included in    *
* all copies or substantial portions of the Software.                           *
*                                                                               *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR    *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,      *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE   *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER        *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, *
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN     *
* THE SOFTWARE.                                                                 *
\*******************************************************************************/
--]]




Levitator = {};

Levitator._NAME			= "Levitator"
Levitator._COPYRIGHT	= "Copyright (C) 2016 Eisbearg"
Levitator._DESCRIPTION	= "Specialization that will levitate vehicles"
Levitator._VERSION		= "1.2.0"




 source(Utils.getFilename("inspect.lua", g_currentModDirectory.."scripts/"))




function Levitator.prerequisitesPresent(specializations)
    return true;
end;


function Levitator:load(savegame)
    self.isSelectable = true;
	self.toggleLevitator = SpecializationUtil.callSpecializationsFunction("toggleLevitator");
	self.Levitator = {};

	self.isSelectable = true;

	local name = getXMLString(self.xmlFile, "vehicle.storeData.name");
	if name == nil then name = getXMLString(self.xmlFile, "vehicle.storeData.name.en"); end;
	if name == nil then name = getXMLString(self.xmlFile, "vehicle.storeData.name.de"); end;
	if name == nil then name = getXMLString(self.xmlFile, "vehicle.storeData.name.es"); end;
	if name == nil then name = getXMLString(self.xmlFile, "vehicle.storeData.name.fr"); end;
	if name == nil then name = getXMLString(self.xmlFile, "vehicle.storeData.name.pt"); end;
	if name == nil then name = getXMLString(self.xmlFile, "vehicle.storeData.name.ru"); end;
	if name == nil then name = "UnknownVehicle"; end;
	print("--- inserting "..Levitator._NAME.." in vehicle "..name);

	self.Levitator.id = Levitator._NAME;
	self.Levitator.name = name;
	self.Levitator.move = false;
	self.Levitator.active = false;
	self.Levitator.downForce = 0;
	self.Levitator.yForce = 0;
	self.Levitator.pitch = 0;
	self.Levitator.dt = 0;
	
	self.lastDigitalSide = 0;

--        self.tipRotationNodes = Utils.loadRotationNodes(self.xmlFile, {}, "vehicle.tipRotationNodes.tipRotationNode", "levitator", self.components);

	self.wiper = false;
 self.wiperAnimation = getXMLString(self.xmlFile, "vehicle.wiperAnimation#animationName");
 self.wiperAnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.wiperAnimation#speed"), 1);
	self.wiper2 = false;
 self.wiper2Animation = getXMLString(self.xmlFile, "vehicle.wiper2Animation#animationName");
 self.wiper2AnimationSpeed = Utils.getNoNil(getXMLFloat(self.xmlFile, "vehicle.wiper2Animation#speed"), 1);

    self.pipeGrainParticleSystem = {};
    self.pipeGrainParticleSystemindex = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.pipeGrainParticleSystem#index"));
    Utils.loadParticleSystem(self.xmlFile, self.pipeGrainParticleSystem, "vehicle.pipeGrainParticleSystem", self.pipeGrainParticleSystemindex, false, nil, self.baseDirectory);
    self.pipeGrainParticleSystem2 = {};
    self.pipeGrainParticleSystem2index = Utils.indexToObject(self.components, getXMLString(self.xmlFile, "vehicle.pipeGrainParticleSystem2#index"));
    Utils.loadParticleSystem(self.xmlFile, self.pipeGrainParticleSystem2, "vehicle.pipeGrainParticleSystem2", self.pipeGrainParticleSystem2index, false, nil, self.baseDirectory);
end;


function Levitator:delete()
Utils.deleteParticleSystem(self.pipeGrainParticleSystem); 
Utils.deleteParticleSystem(self.pipeGrainParticleSystem2); 
end;


function Levitator:mouseEvent(posX, posY, isDown, isUp, button)
end;


function Levitator:keyEvent(unicode, sym, modifier, isDown)

end;


function Levitator:activateFlightMode()
	setLinearDamping(self.components[1].node, 0.18);
	setAngularDamping(self.components[1].node, 0.29);
	self.Levitator.downForce = self:getTotalMass(true, false) * 9.81;
	self.Levitator.yForce = self.Levitator.downForce * 5;
	self.cruiseControl.average = (self.cruiseControl.minSpeed + self.cruiseControl.maxSpeed);
	self.setCruiseControlMaxSpeed(self, self.cruiseControl.average);
end;


function Levitator:deactivateFlightMode()
	setLinearDamping(self.components[1].node, 0.0);
	setAngularDamping(self.components[1].node, 0.01);
	self.Levitator.downForce = self:getTotalMass(true, false) * 9.81;
	self.Levitator.yForce = self.Levitator.downForce * 5;
	self.cruiseControl.average = (self.cruiseControl.minSpeed + self.cruiseControl.maxSpeed);
	self.setCruiseControlMaxSpeed(self, self.cruiseControl.average);
end;


function Levitator:update(dt)
--    if self.isClient then
--        Utils.updateRotationNodes(self, self.tipRotationNodes, dt, self.isMotorStarted);
--		end

			local altAboveGround, altAboveNN = Levitator:getAltitude(self.components[1].node);
	                               self.altAboveGround = altAboveGround;
	                               if self.isMotorStarted and self.altAboveGround < 5 then
					Utils.setEmittingState(self.pipeGrainParticleSystem, true);
				else
			  	Utils.setEmittingState(self.pipeGrainParticleSystem, false);
			end;
                                                          if self.isMotorStarted and self.altAboveGround < 12 then
					Utils.setEmittingState(self.pipeGrainParticleSystem2, true);
				else
			  	Utils.setEmittingState(self.pipeGrainParticleSystem2, false);
			end;

if self.isMotorStarted and (g_currentMission.environment.dayTime > 22*3600000 or g_currentMission.environment.dayTime < 6*3600000) then
				self.wiper2 = true;
else
				self.wiper2 = false;
               end;
			   
if self.wiper2Animation ~= nil and self.playAnimation ~= nil then
	if self.wiper2 then
	        self:playAnimation(self.wiper2Animation, self.wiper2AnimationSpeed, self:getAnimationTime(self.wiper2Animation), true);
                 else
	        self:playAnimation(self.wiper2Animation, -self.wiper2AnimationSpeed, self:getAnimationTime(self.wiper2Animation), true);
              end;
       end;
			   
if self.wiperAnimation ~= nil and self.playAnimation ~= nil then
	if self.wiper then
	        self:playAnimation(self.wiperAnimation, self.wiperAnimationSpeed, self:getAnimationTime(self.wiperAnimation), true);
                 else
	        self:playAnimation(self.wiperAnimation, -self.wiperAnimationSpeed, self:getAnimationTime(self.wiperAnimation), true);
              end;
       end;

--	if self.isMotorStarted and Utils.isSamplePlaying(self.sampleMotor) then
		if self.isMotorStarted and SoundUtil.isSamplePlaying(self.sampleMotor) then
			if self.Levitator.active == false then Levitator.activateFlightMode(self); end
			self.Levitator.active = true;
				self.wiper = true;
		else
			if self.Levitator.active == true then Levitator.deactivateFlightMode(self); end
			self.Levitator.active = false;
				self.wiper = false;
		end;

	if not self.Levitator.active then return end;
	
	Levitator.updateMovement(self, dt);
	
	setLinearDamping(self.components[1].node, 0.18);
	setAngularDamping(self.components[1].node, 0.33);
	
	local dX,dY,dZ = localDirectionToWorld(self.components[1].node, 1, 0, 0);
	local sinDir = dX / 1;
	local cosDir = dZ / -1;

	local zSteer = 280 * self.axisForward * -1;
	local xForce = zSteer * cosDir;
	local zForce = zSteer * sinDir;
	if Input.isMouseButtonPressed(Input.MOUSE_BUTTON_LEFT) or Input.isMouseButtonPressed(Input.MOUSE_BUTTON_RIGHT) then
		if Input.isMouseButtonPressed(Input.MOUSE_BUTTON_LEFT) then
			self.Levitator.pitch = self.Levitator.pitch + 0.66
			if self.Levitator.pitch > self.Levitator.downForce / 2 then self.Levitator.pitch = self.Levitator.downForce / 2 end;
		end;
		if Input.isMouseButtonPressed(Input.MOUSE_BUTTON_RIGHT) then
			self.Levitator.pitch = self.Levitator.pitch - 0.39
			if self.Levitator.pitch < self.Levitator.downForce / -4 then self.Levitator.pitch = self.Levitator.downForce / -4 end;
		end;
	else
		self.Levitator.pitch = 0;
	end

	if self.axisForward == 1 or self.axisForward == -1 or self.lastDigitalForward == 1 or self.lastDigitalForward == -1  then
                                       dg = 0;
           else
                                       dg = 2.9;
		end;
	
	self.Levitator.yForce = self.Levitator.pitch + self.Levitator.downForce;
	addForce(self.components[1].node, xForce, self.Levitator.yForce,  zForce, 0, dg, 0, true);
--	addForce(self.components[1].node, xForce, self.Levitator.yForce,  zForce, 0, 0.66, 0, true);

	
	local yTurnSpeed = 0;
	if self.axisSide > 0.1 or self.axisSide < -0.1 or self.lastDigitalSide > 0.1 or self.lastDigitalSide < -0.1  then
		if self.axisSideIsAnalog then
			yTurnSpeed = self.axisSide * -0.81;
		else
			yTurnSpeed = self.lastDigitalSide * -0.81;
		end;
	end;

	local AVx, AVy, AVz = getAngularVelocity(self.components[1].node);
	if yTurnSpeed == 0 then
		setAngularVelocity(self.components[1].node, AVx * 0.75, AVy * 0.95, AVz * 0.75);
	else
		setAngularVelocity(self.components[1].node, AVx * 0.75, yTurnSpeed, AVz * 0.75);
	end;
end;


function Levitator:updateTick(dt)
end;


function Levitator:draw()
	if self.isEntered then

		setTextAlignment(RenderText.ALIGN_CENTER);
		setTextColor(1,1,1,1);

		if self.Levitator.active then
			renderText(0.87, 0.31, 0.016, g_i18n:getText("move"));
			renderText(0.87, 0.29, 0.016, string.format(g_i18n:getText("current") .. " %3.4f ", self.Levitator.pitch));
			local altAboveGround, altAboveNN = Levitator:getAltitude(self.components[1].node);
			renderText(0.87, 0.26, 0.016, string.format(g_i18n:getText("ground") .. " %4.2f m", altAboveGround));
			renderText(0.87, 0.24, 0.016, string.format(g_i18n:getText("NN") .. " %4.2f m", altAboveNN));
			local xLV, yLV, zLV = getLinearVelocity(self.components[1].node);
			renderText(0.87, 0.22, 0.016, string.format(g_i18n:getText("verticalVelocity") .. " %4.2f m/s", yLV));
			setTextBold(false);
		end;
	
		setTextAlignment(RenderText.ALIGN_LEFT);
		setTextColor(1,1,1,1);
	end;
end;


function Levitator:toggleLevitator(state, nes)
end;


function Levitator:readStream(streamId, connection)
end;
		
	
function Levitator:writeStream(streamId, connection)
end;


function Levitator:getMorldDirectionDegree(rootNode)
	local dX,dY,dZ = localDirectionToWorld(rootNode, 0, 0, 1);
	local sinus = dX / 1;
	local cosinus = dZ / 1;
	local direction = math.deg(math.atan2(sinus, cosinus));
	return direction, sinus, cosinus;
end;


function Levitator:getMorldDirectionDegree2(rootNode)
	local dX,dY,dZ = localDirectionToWorld(rootNode, 0, 0, 1);
	local sinus = dX / 1;
	local cosinus = dZ / 1;
	local direction = math.deg(math.atan2(cosinus, sinus));
	return direction, sinus, cosinus;
end;


function Levitator:getMorldDirectionDegree3(rootNode)
	local dX,dY,dZ = localDirectionToWorld(rootNode, 0, 0, -1);
	local sinus = dX / 1;
	local cosinus = dZ / 1;
	local direction = math.deg(math.atan2(cosinus, sinus));
	return direction, sinus, cosinus;
end;


function Levitator:getAltitude(rootNode)
	local terrainHeight = getTerrainHeightAtWorldPos(g_currentMission.terrainRootNode, getWorldTranslation(rootNode));
	local x, altAboveNN = getWorldTranslation(rootNode);
	local altAboveGround = altAboveNN - terrainHeight;
	if altAboveGround < 0 then altAboveGround = 0.0 end;
	return altAboveGround, altAboveNN, terrainHeight;
end;


function Levitator:getTailForce(rootNode, xSteer)
		
		local dX,dY,dZ = localDirectionToWorld(rootNode, 0, 0, -1);
		local sinDir = dX / 1;
		local cosDir = dZ / 1;
		local xBackward = 10 * sinDir;
		local zBackward = 10 * cosDir;
		
		dX,dY,dZ = localDirectionToWorld(rootNode, 1, 0, 0);
		sinDir = dX / 1;
		cosDir = dZ / 1;
		local xTurnForce = xSteer * sinDir;
		local zTurnForce = xSteer * cosDir;

	return xTurnForce, 0, zTurnForce, xBackward, 0.6, zBackward 
end;


function Levitator:updateMovement(dt)
    if not self.isEntered then return; end
	
	                local axisAccelerate = InputBinding.getDigitalInputAxis(InputBinding.AXIS_ACCELERATE_VEHICLE);
                local axisBrake = InputBinding.getDigitalInputAxis(InputBinding.AXIS_BRAKE_VEHICLE)
                local axisForward = Utils.clamp((axisAccelerate-axisBrake)*0.5, -1, 1);
	
	                if InputBinding.isAxisZero(axisForward) then
                    axisAccelerate = InputBinding.getAnalogInputAxis(InputBinding.AXIS_ACCELERATE_VEHICLE);
	                    axisBrake = InputBinding.getAnalogInputAxis(InputBinding.AXIS_BRAKE_VEHICLE)
	                    self.axisForward = Utils.clamp((axisAccelerate-axisBrake)*0.5, -1, 1);
                    if not InputBinding.isAxisZero(self.axisForward) then
                        self.axisForwardIsAnalog = true;
	                    end
                   self.lastDigitalForward = 0;
                    end
        
    self.axisSide = InputBinding.getDigitalInputAxis(InputBinding.AXIS_MOVE_SIDE_VEHICLE);
    if InputBinding.isAxisZero(self.axisSide) then
        self.axisSide = InputBinding.getAnalogInputAxis(InputBinding.AXIS_MOVE_SIDE_VEHICLE)
        if not InputBinding.isAxisZero(self.axisSide) then
            self.axisSideIsAnalog = true;
        end
        self.lastDigitalSide = 0;
    else
        self.axisSide = Utils.clamp(self.lastDigitalSide + dt/self.axisSmoothTime*self.axisSide, -1, 1);
        self.axisSideIsAnalog = false;
        self.lastDigitalSide = self.axisSide;
    end;
        
    if not self:getIsActiveForInput(false) then
        if not self.axisSideIsAnalog then
            self.axisSide = 0;
        end
        if not self.axisForwardIsAnalog then
            self.axisForward = 0;
        end
    end
        
--    if self.isMotorStarted and self.motorStartTime <= g_currentMission.time then
--    end;
    
end;

