-- @ Autor  Tobias F. (John Deere 6930)
-- @ Last Edit  02/11/2011
-- @ history:
		--01/08/2011 - initializing Specialization
		--02/11/2011 - fixing multiplayererror
-- InvertDrivingDirection
-- Specialization to invert the DrivingDirection
--[[XML Data:
<invertSteering rootNode="" clip="" speedScale=""/> ]]
 
InvertDrivingDirection = {};

function InvertDrivingDirection.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Motorized, specializations);
end;

function InvertDrivingDirection:load(xmlFile)
	self.invertSteering = InvertDrivingDirection.invertSteering;
	self.invertedDrivingDirection = false;
	self.lastAcceleration = 0;
	self.invertTimeOut = 0;
	self.showWarningTime = 0;
	self.invertSteeringAnimation = {};
	self.invertSteeringAnimation.animRootNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.invertSteering#rootNode"));
	if self.invertSteeringAnimation.animRootNode ~= nil and self.invertSteeringAnimation.animRootNode ~= 0 then
		self.invertSteeringAnimation.animCharSet = getAnimCharacterSet(self.invertSteeringAnimation.animRootNode);
		if self.invertSteeringAnimation.animCharSet ~= 0 then
			local clip = getAnimClipIndex(self.invertSteeringAnimation.animCharSet, getXMLString(xmlFile, "vehicle.invertSteering#clip"));
			assignAnimTrackClip(self.invertSteeringAnimation.animCharSet, 0, clip);
			setAnimTrackLoopState(self.invertSteeringAnimation.animCharSet, 0, false);
			self.invertSteeringAnimation.animSpeedScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.invertSteering#speedScale"), 1);
			self.invertSteeringAnimation.animDuration = getAnimClipDuration(self.invertSteeringAnimation.animCharSet, clip);
		end;
	end;
end;

function InvertDrivingDirection:delete()
end;

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

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

function InvertDrivingDirection:update(dt)
	if self:getIsActiveForInput() then
		if InputBinding.hasEvent(InputBinding.INVERTDRIVINGDIRECTION) and self.invertTimeOut <= self.time then
			self:invertSteering(not self.invertedDrivingDirection);
		end;
	end;
	if self:getIsActive() then
		if self.invertTimeOut > self.time then
			local animCharSet = self.invertSteeringAnimation.animCharSet;
			if self.invertedDrivingDirection then
				if self.invokeIgnition ~= nil then
					self:invokeIgnition(false);
				end;
				if animCharSet ~= 0 then
				    if getAnimTrackTime(animCharSet, 0) < 0.0 then
						setAnimTrackTime(animCharSet, 0, 0.0);
					end;
					setAnimTrackSpeedScale(animCharSet, 0, self.invertSteeringAnimation.animSpeedScale);
					enableAnimTrack(animCharSet, 0);
				end;	
			else
				if self.invokeIgnition ~= nil then
					self:invokeIgnition(false);
				end;
				if animCharSet ~= 0 then
					if getAnimTrackTime(animCharSet, 0) > self.invertSteeringAnimation.animDuration then
						setAnimTrackTime(animCharSet, 0, self.invertSteeringAnimation.animDuration);
					end;
					setAnimTrackSpeedScale(animCharSet, 0, -self.invertSteeringAnimation.animSpeedScale);
					enableAnimTrack(animCharSet, 0);
				end;	
			end;		
			if self.isServer then
				Steerable.updateVehiclePhysics(self, 0, self.axisForwardIsAnalog, 0, self.axisSideIsAnalog, dt);
			end;
		end;
		
		if self.invertedDrivingDirection then
			if self.isHired and self.dismiss ~= nil and self.stopAITractor ~= nil then
				self:dismiss();
				self:stopAITractor();
				self.showWarningTime = self.time + 3000;
			end;
		end;	
	end;
end;

function InvertDrivingDirection:readStream(streamId, connection)
    local invertedDrivingDirection = streamReadBool(streamId);
	if invertedDrivingDirection ~= self.invertedDrivingDirection then
		self:invertSteering(invertedDrivingDirection, true);
	end;
end;

function InvertDrivingDirection:writeStream(streamId, connection)
    streamWriteBool(streamId, self.invertedDrivingDirection);
end;

function InvertDrivingDirection:draw()
	if self.showWarningTime > self.time then
		g_currentMission:addWarning(g_i18n:getText("warning_ai_active"), 0, 0.03);
	end;
	if not self.invertedDrivingDirection  then
		g_currentMission:addHelpButtonText(g_i18n:getText("ACTIVATE_INVERTDRIVING"), InputBinding.INVERTDRIVINGDIRECTION);
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("DEACTIVATE_INVERTDRIVING"), InputBinding.INVERTDRIVINGDIRECTION);
	end;
end;

function InvertDrivingDirection:invertSteering(steeringIsInverted, noEventSend)
	SetInvertSteeringEvent.sendEvent(self, steeringIsInverted, noEventSend)
	for _,wheel in pairs(self.wheels) do
		wheel.rotSpeed = -wheel.rotSpeed;
	end;
	self.invertTimeOut = self.time+10+self.invertSteeringAnimation.animDuration;
	self.invertedDrivingDirection = steeringIsInverted;
end;

local wheelsUtilUpdateWheelsPhysics = WheelsUtil.updateWheelsPhysics;
WheelsUtil.updateWheelsPhysics = function(self, dt, currentSpeed, acceleration, doHandbrake, requiredDriveMode, isAlreadyInverted)
	local accelerationValue = acceleration;
	if isAlreadyInverted == nil or isAlreadyInverted == false then
		if self.invertedDrivingDirection ~= nil then
			if self.invertedDrivingDirection == true then
				accelerationValue = -accelerationValue;
			end;
		end;
	end;
	wheelsUtilUpdateWheelsPhysics(self, dt, currentSpeed, accelerationValue, doHandbrake, requiredDriveMode, true);
end;