--
-- RuFa
--
-- written by fruktor, visit: www.eifok-team.de
--

RuFa = {};

RuFa.modDir = g_currentModDirectory;

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

function RuFa:load(xmlFile)

	self.playerCallbackRuFa = SpecializationUtil.callSpecializationsFunction("playerCallbackRuFa"); 
	self.setRuFa = SpecializationUtil.callSpecializationsFunction("setRuFa"); 
	
	self.doRuFa = false;
	self.bFront = true;
	self.bBack = false;
	
	self.rufa = {};
	
	local trigger = Utils.indexToObject( self.components, getXMLString(xmlFile, string.format("vehicle.rufa#trigger")) );
	if trigger == nil then
		--print("[Error?::RuFa] node is OK, but trigger could not be located. Check line "..tostring(i+1).." in your vehicle.xml");
	else
		addTrigger( trigger, "playerCallbackRuFa", self );	
	end;
	
	
	local anim = getXMLString(xmlFile, string.format("vehicle.rufa#anim", i));
	local doorIC = getXMLInt(xmlFile, string.format("vehicle.rufa#doorIcIndex", i));
	local wsIndex = getXMLInt(xmlFile, string.format("vehicle.rufa#wsIndex", i));
	
	self.rufa.trigger = trigger;
	self.rufa.anim = anim;
	self.rufa.doorIC = doorIC;
	self.rufa.wsIndex = wsIndex;
	self.rufa.plIR = false;
	self.rufa.forcebrake = false;		
			
	for _,wheel in pairs(self.wheels) do
		wheel.origRotSpeed = wheel.rotSpeed;
	end;	
end;

function RuFa:delete()
	if self.rufa.trigger ~= nil then
		removeTrigger(self.rufa.trigger);
	end;
end;

function RuFa:readStream(streamId, connection)
	local state = streamReadBool(streamId);	
	self:setRuFa(state, true);
end;

function RuFa:writeStream(streamId, connection)
	streamWriteBool(streamId, self.doRuFa);
	--local ct = self:getAnimationTime(self.rufa.anim);
	--streamWriteFloat32(streamId, ct);
end;

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

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

function RuFa:update(dt)
	if self.rufa.plIR then
		g_currentMission:addHelpButtonText( g_i18n:getText("SET_RUFA"), InputBinding.SET_RUFA );	
		setTextColor(1.0, 1.0, 1.0, 1.0);
		setTextAlignment(RenderText.ALIGN_LEFT); 		
		renderText( 0.5, 0.06, 0.02, g_i18n:getText("SET_RUFA") );
		if InputBinding.hasEvent(InputBinding.SET_RUFA)then
			local state = true;
			local obj = self.interactiveObjects[self.rufa.doorIC];
			if obj ~= nil then
				state = obj.isOpen;
			end;
			if state then
				local doRuFa = not self.doRuFa;
				self:setRuFa( doRuFa );
			end;
		end
	end;
	if self.rufa.forcebrake == true then
		if self.isServer then
			Steerable.updateVehiclePhysics(self, 0, self.axisForwardIsAnalog, 0, self.axisSideIsAnalog, dt);
		end;		
		local ct = self:getAnimationTime(self.rufa.anim);
		--local dur = self:getAnimationDuration(self.rufa.anim);
		--print("ct/dur="..tostring(ct).." / "..tostring(dur).." / "..tostring(self.doRuFa));
		if ct == 0 and self.doRuFa == false then 
			self.rufa.forcebrake = false;
		elseif ct == 1 and self.doRuFa == true then
			self.rufa.forcebrake = false;
		end
	end;
	if self.rLights ~= nil then
		if self.doRuFa then
			self.rLights.rev.bUsage = false;
			for _,wheel in pairs(self.wheels) do
				wheel.rotSpeed = -wheel.origRotSpeed;
			end;	
		elseif self.rLights.rev.bUsage == false then
			self.rLights.rev.bUsage = true;
		end;	
	end;
end;

function RuFa:updateTick(dt)
	if self.rufa.wsIndex ~= nil then
		self.rufa.plIR = self.ws[self.rufa.wsIndex].plIR;
	end;
end;

function RuFa:onLeave()
end;

function RuFa:draw()
end;

function RuFa:playerCallbackRuFa(triggerId, otherId, onEnter, onLeave, onStay)
	
	if onEnter and g_currentMission.controlPlayer and g_currentMission.player ~= nil and otherId == g_currentMission.player.rootNode then
		self.rufa.plIR = true;
	elseif onLeave then
		self.rufa.plIR = false;
	end;
	
end;


function RuFa:setRuFa(state, noEventSend)
	if noEventSend == nil or noEventSend == false then
		SetRuFaEvent.sendEvent(self, state, noEventSend);
	end;
	self.doRuFa = state;
	self.invertedDrivingDirection = state;
	local dir = 1;
	if not self.doRuFa then
		dir = -1;
	end;			
	self:playAnimation(self.rufa.anim, dir, Utils.clamp(self:getAnimationTime(self.rufa.anim), 0, 1), true);
	self.rufa.forcebrake = true;
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;



--
--
--
--
--
SetRuFaEvent = {};
SetRuFaEvent_mt = Class(SetRuFaEvent, Event);

InitEventClass(SetRuFaEvent, "SetRuFaEvent");

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

function SetRuFaEvent:new(object, state)
    local self = SetRuFaEvent:emptyNew()
    self.object = object;
	self.state = state;
    return self;
end;

function SetRuFaEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.object = networkGetObject(id);
	self.state = streamReadBool(streamId);
    self:run(connection);
end;

function SetRuFaEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.object));
	streamWriteBool(streamId, self.state);
end;

function SetRuFaEvent:run(connection)
    self.object:setRuFa(self.state, true);
    if not connection:getIsServer() then
        g_server:broadcastEvent(SetRuFaEvent:new(self.object, self.state), nil, connection, self.object);
    end;
end;

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