--
-- LockSteeringaxles - V1.1
-- allows to lock/unlock the steeringaxles
--
-- @Author  FIAT80-90DT
-- @date  	29.08.2011
-- @Edit	04.12.2013 - bugfixes | better network-support | add steeringaxle for the reversetrip
--
-- www.modding-stage.com -- 

LockSteeringaxles = {};

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

function LockSteeringaxles:load(xmlFile)
	self.lockAxles = SpecializationUtil.callSpecializationsFunction("lockAxles");
	
	self.enableIfReverse = Utils.getNoNil(getXMLBool(xmlFile, "vehicle.wheels.enableSteeringaxlesIfReverse"), true);
	
	for i=1, table.getn(self.wheels) do 
		self.wheels[i].backupScale = self.wheels[i].steeringAxleScale;
		self.wheels[i].backupMax = self.wheels[i].steeringAxleRotMax;
		self.wheels[i].backupMin = self.wheels[i].steeringAxleRotMin;
    end;
	
	if InputBinding.LOCK_AXLES == nil then
		InputBinding.LOCK_AXLES = InputBinding.IMPLEMENT_EXTRA3;
	end;
end;

function LockSteeringaxles:readStream(streamId, connection)
	self:lockAxles(streamReadBool(streamId), true);
end;

function LockSteeringaxles:writeStream(streamId, connection)
	streamWriteBool(streamId, self.lock);
end;

function LockSteeringaxles:delete()
end;

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

function LockSteeringaxles:keyEvent(unicode, sym, modifier, isDown)
end;

function LockSteeringaxles:update(dt)
	if self:getIsActiveForInput() then
		if InputBinding.hasEvent(InputBinding.LOCKSTEERING_TSM200) then
			self:lockAxles(not self.lock);			
		end;
	end;
	
	-- # Section from sven18koehler # --
	if self.updateSteeringAxleAngle and self.enableIfReverse then
		if self.attacherVehicle ~= nil and self.movingDirection < 0 then
			local x,y,z = worldDirectionToLocal(self.steeringAxleNode, localDirectionToWorld(self.attacherVehicle.steeringAxleNode, 0, 0, 1));
			local dot = z;
			dot = dot / Utils.vector2Length(x,z);
			local angle = math.acos(dot);
			if x < 0 then
				angle = -angle;
			end;
			local startSpeed = self.steeringAxleAngleScaleStart;
			local endSpeed = self.steeringAxleAngleScaleEnd;
			local scale = Utils.clamp(1 + (self.lastSpeed*-3600-startSpeed) * 1.0/(startSpeed-endSpeed), 0, 1);
			self.steeringAxleAngle = angle*scale;
		end;
	end;
	--#--
end;

function LockSteeringaxles:updateTick(dt)
end;

function LockSteeringaxles:lockAxles(lock, noEventSend)
	for i=1, table.getn(self.wheels) do 
		local wheel = self.wheels[i];
		if lock then 
			wheel.steeringAxleScale = 0;
			wheel.steeringAxleRotMax = 0;
			wheel.steeringAxleRotMin = 0;
		else
			wheel.steeringAxleScale = wheel.backupScale;
			wheel.steeringAxleRotMax = wheel.backupMax;
			wheel.steeringAxleRotMin = wheel.backupMin;
		end;
	end;
	self.lock = lock;
	LockSteeringaxlesEvent.sendEvent(self, self.lock, noEventSend);
end;

function LockSteeringaxles:draw()
	if self.lock then
		g_currentMission:addHelpButtonText(g_i18n:getText("unlockSteeringaxles"), InputBinding.LOCKSTEERING_TSM200);
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("lockSteeringaxles"), InputBinding.LOCKSTEERING_TSM200);
	end;
end;
						
						
						
--####	EVENT	####-- 
	
--@author	-	FIAT80-90DT																
--@date		-	28.08.11											

LockSteeringaxlesEvent = {};
LockSteeringaxlesEvent_mt = Class(LockSteeringaxlesEvent, Event);

InitEventClass(LockSteeringaxlesEvent, "LockSteeringaxlesEvent");

function LockSteeringaxlesEvent:emptyNew()
    local self = Event:new(LockSteeringaxlesEvent_mt);
    self.className="LockSteeringaxlesEvent";
    return self;
end;

function LockSteeringaxlesEvent:new(vehicle, lock)
    local self = LockSteeringaxlesEvent:emptyNew()
    self.vehicle = vehicle;
	self.lock = lock;
    return self;
end;

function LockSteeringaxlesEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.vehicle = networkGetObject(id);
	
	self.lock = streamReadBool(streamId);
	self:run(connection);
end;

function LockSteeringaxlesEvent:run(connection)
	self.vehicle:lockAxles(self.lock, true);
	if not connection:getIsServer() then
        g_server:broadcastEvent(LockSteeringaxlesEvent:new(self.vehicle, self.lock), nil, connection, self.vehicle);
    end;
end;

function LockSteeringaxlesEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteBool(streamId, self.lock);
end;


function LockSteeringaxlesEvent.sendEvent(vehicle, lock, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(LockSteeringaxlesEvent:new(vehicle, lock), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(LockSteeringaxlesEvent:new(vehicle, lock));
		end;
	end;
end;