--
-- Marshall_Rotor
-- Class for all Marshall_Rotors
--
-- @author  LS_UK Modteam
-- @date  04/08/11
--
 
Marshall_Rotor = {};


function Marshall_Rotor.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Sprayer, specializations) and SpecializationUtil.hasSpecialization(ImplementLinks, specializations);
end;

function Marshall_Rotor:load(xmlFile)


	self.setTransRot = SpecializationUtil.callSpecializationsFunction("setTransRot");
	self.TransRotAnimation = getXMLString(xmlFile, "vehicle.TransRot#animationName");
	self.TransRot = false;
	  
	self.rotateSpinners = {};
	local i=0;
	while true do
		local baseName = string.format("vehicle.rotateSpinners.node(%d)", i);
		local index = getXMLString(xmlFile, baseName.. "#index");
		local x,y,z = Utils.getVectorFromString(getXMLString(xmlFile, baseName.. "#rotationSpeed"));
		local rotationSpeed = {x,y,z};
		local runOutTime = Utils.getNoNil(getXMLFloat(xmlFile, baseName.. "#runOutTime"), 2)*1000;
		if index == nil or rotationSpeed == nil or runOutTime == nil then
			break;
		end;
		local node = Utils.indexToObject(self.components, index);
		if node ~= nil then
			local entry = {};
			entry.node = node;
			entry.runOutTime = runOutTime;
			entry.rotationSpeedMax = rotationSpeed;
			entry.rotationSpeedMin = {0,0,0};
			entry.rotationSpeedCurrent = {0,0,0};
			table.insert(self.rotateSpinners, entry);
		end;
		i = i+1;
	end;	
	
	local rotarySound = getXMLString(xmlFile, "vehicle.rotarySound#file");
	if rotarySound ~= nil and rotarySound ~= "" then
		rotarySound = Utils.getFilename(rotarySound, self.baseDirectory);
		self.rotarySound = createSample("rotarySound");
		loadSample(self.rotarySound, rotarySound, false);
		self.rotarySoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotarySound#pitchOffset"), 0);
		self.rotarySoundVolume = 0.0;
		self.rotarySoundVolumeMin = 0.0;
		self.rotarySoundVolumeMax = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotarySound#volume"), 1.0);
		self.rotarySoundEnabled = false;
	end;

	  self.spreaderParticleSystems = {};
      local i = 0;
      while true do
        local namei = string.format("vehicle.spreaderParticleSystems.spreaderParticleSystems(%d)", i);
		local nodei = Utils.indexToObject(self.components, getXMLString(xmlFile, namei .. "#index"));
		if nodei == nil then
			break;
		end; 
        Utils.loadParticleSystem(xmlFile, self.spreaderParticleSystems, namei, nodei, false, nil, self.baseDirectory)		
		i = i +1;		
      end;
	  
 	  self.setVehicleRpmUp = SpecializationUtil.callSpecializationsFunction("setVehicleRpmUp");
	  self.saveMinRpm = 0; 
      self.printWarningTime = 0;
end;
  
function Marshall_Rotor:delete()
	if self.rotarySound ~= nil then
		delete(self.rotarySound);
	end;
 	Utils.deleteParticleSystem(self.spreaderParticleSystems);
end;

function Marshall_Rotor:readStream(streamId, connection)
    self:setTransRot(streamReadBool(streamId), true);
end;

function Marshall_Rotor:writeStream(streamId, connection)
    streamWriteBool(streamId, self.TransRot);
	
end;
 
function Marshall_Rotor:mouseEvent(posX, posY, isDown, isUp, button)
end;

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

function Marshall_Rotor:update(dt)

      if self:getIsActiveForInput() then
            if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then
				self:setTransRot(not self.isTransRotOn);
            end;
			if InputBinding.isPressed(InputBinding.IMPLEMENT_EXTRA) and self.PTOId then
				self.printWarningTime = self.time + 1500;
			end;	
      end;
	
	for i, jointDesc in pairs(self.componentJoints) do
		setJointFrame(self.componentJoints[i].jointIndex, 0, self.componentJoints[i].jointNode);
	end;	
end;

function Marshall_Rotor:updateTick(dt)
    if self:getIsActive() then
		if not self.attacherVehicle.isMotorStarted then
			self.isTurnedOn = false;
		end;
		if self.PTOId then
			self.isTurnedOn = false;
		end;
		local isKeyEvent = false;	
		if self.isTurnedOn then
 			isKeyEvent = true;	
		else
 			isKeyEvent = false;	
		end;
		self:setVehicleRpmUp(dt, isKeyEvent);	
		local volume = Utils.getMovedLimitedValues({self.rotarySoundVolume}, {self.rotarySoundVolumeMax}, {self.rotarySoundVolumeMin}, 1, 1200, dt, not self.isTurnedOn);
		self.rotarySoundVolume = volume[1];
			if self.isTurnedOn and not self.PTOId then
				if not self.rotarySoundEnabled and self:getIsActiveForSound() then
					playSample(self.rotarySound, 0, self.rotarySoundVolume, 0);
					setSamplePitch(self.rotarySound, self.rotarySoundPitchOffset);
					self.rotarySoundEnabled = true;
				end;
				if self.rotarySoundVolume < self.rotarySoundVolumeMax then
					setSampleVolume(self.rotarySound, self.rotarySoundVolume);
				end;
				else
				if self.rotarySoundEnabled then
					if self.rotarySoundVolume <= self.rotarySoundVolumeMin then
						stopSample(self.rotarySound);
						self.rotarySoundEnabled = false;
					else
						setSampleVolume(self.rotarySound, self.rotarySoundVolume);
					end;
				end;

			end;	
 		for k, spinner in pairs(self.rotateSpinners) do
			local values = Utils.getMovedLimitedValues(spinner.rotationSpeedCurrent, spinner.rotationSpeedMax, spinner.rotationSpeedMin, 3, spinner.runOutTime, dt, not self.isTurnedOn);
			spinner.rotationSpeedCurrent = values;
			rotate(spinner.node, unpack(spinner.rotationSpeedCurrent));
		end;
	end;	
	
	if self.isTurnedOn and not self.PTOId then
		Utils.setEmittingState(self.spreaderParticleSystems, true);
	else
		Utils.setEmittingState(self.spreaderParticleSystems, false);
	end;

end;

function Marshall_Rotor:draw()
	if self.isClient then
		if self.isTransRotOn then
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("CLOSEDOOR"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA2);
		else
			g_currentMission:addHelpButtonText(string.format(g_i18n:getText("OPENDOOR"), self.typeDesc), InputBinding.IMPLEMENT_EXTRA2);
		end;
		if self.printWarningTime > self.time then
			g_currentMission:addWarning(g_i18n:getText("turnON_ErrorMS75"), 0.018, 0.033);
		end;
	end;
end;

function Marshall_Rotor:onAttach(attacherVehicle)
	self.attacherVehicle = attacherVehicle;
	if self.attacherVehicleCopy == nil then
		self.attacherVehicleCopy = self.attacherVehicle;
	end;
	self.saveMinRpm = self.attacherVehicle.motor.minRpm;
end;

function Marshall_Rotor:onDetach()
	if self.spreaderParticleSystems ~= nil then
		Utils.setEmittingState(self.spreaderParticleSystems, false);
	end; 
	for k, steerable in pairs(g_currentMission.steerables) do
		if self.attacherVehicleCopy == steerable then
			steerable.motor.minRpm = self.saveMinRpm;
			self.attacherVehicleCopy = nil;
		end;
	end;
	if self.rotarySoundEnabled then
		stopSample(self.rotarySound);
		self.rotarySoundEnabled = false;
	end;	
end;

function Marshall_Rotor:onLeave()
	if self.deactivateOnLeave then
		Marshall_Rotor.onDeactivate(self);
	else
		Marshall_Rotor.onDeactivateSounds(self);
	end;
	if self.spreaderParticleSystems ~= nil then
		Utils.setEmittingState(self.spreaderParticleSystems, false);
	end; 
end;

function Marshall_Rotor:onDeactivate()

	Marshall_Rotor.onDeactivateSounds(self)
 	if self.spreaderParticleSystems ~= nil then
		Utils.setEmittingState(self.spreaderParticleSystems, false);
	end; 
end;

function Marshall_Rotor:onDeactivateSounds()
	if self.rotarySoundEnabled then
		stopSample(self.rotarySound);
		self.rotarySoundEnabled = false;
	end;
end;

function Marshall_Rotor:setVehicleRpmUp(dt, isActive)
	if self.attacherVehicle ~= nil and self.saveMinRpm ~= 0 then
		if dt ~= nil then
			if isActive == true then
				self.attacherVehicle.motor.minRpm = math.max(self.attacherVehicle.motor.minRpm-dt, -1000);
			else
				self.attacherVehicle.motor.minRpm = math.min(self.attacherVehicle.motor.minRpm+dt*2, self.saveMinRpm);
			end;
		else
			self.attacherVehicle.motor.minRpm = self.saveMinRpm;
		end;
		if self.attacherVehicle.isMotorStarted then
			local fuelUsed = 0.00000011*math.abs(self.attacherVehicle.motor.minRpm);
			self.attacherVehicle:setFuelFillLevel(self.attacherVehicle.fuelFillLevel-fuelUsed);
			g_currentMission.missionStats.fuelUsageTotal = g_currentMission.missionStats.fuelUsageTotal + fuelUsed;
			g_currentMission.missionStats.fuelUsageSession = g_currentMission.missionStats.fuelUsageSession + fuelUsed;
		end;
	end;
end;

function Marshall_Rotor:setTransRot(isTransRot,noEventSend)
	SetTransRotEvent.sendEvent(self, isTransRot, noEventSend);
	-- Play TransRot animation --
	self.isTransRotOn = isTransRot;
	if self.isTransRotOn then
		if self.TransRotAnimation ~= nil and self.playAnimation ~= nil then
			self:playAnimation(self.TransRotAnimation, 1, nil, true);
			self.TransRot = true;

		end;
	else
		if self.TransRotAnimation ~= nil and self.playAnimation ~= nil then
			self:playAnimation(self.TransRotAnimation, -1, nil, true);
			self.TransRot = false;
	
		end;
	end;


end;

SetTransRotEvent = {};
SetTransRotEvent_mt = Class(SetTransRotEvent, Event);

InitEventClass(SetTransRotEvent, "SetTransRotEvent");

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

function SetTransRotEvent:new(vehicle, isTransRot)
    local self = SetTransRotEvent:emptyNew()
    self.vehicle = vehicle;
	self.isTransRot = isTransRot;
    return self;
end;

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

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

function SetTransRotEvent:run(connection)   
	self.vehicle:setTransRot(self.isTransRot, true);
    if not connection:getIsServer() then
        g_server:broadcastEvent(SetTransRotEvent:new(self.vehicle, self.isTransRot), nil, connection, self.vehicle);
    end;
end;

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