TA23065 = {};
print("  TA23065 loaded");
function TA23065.prerequisitesPresent(specializations)
return SpecializationUtil.hasSpecialization(Trailer, specializations) and SpecializationUtil.hasSpecialization(AnimatedVehicle, specializations);
    
end;

function TA23065:load(xmlFile)

	self.updateTargetTimehaeckselklappe = SpecializationUtil.callSpecializationsFunction("updateTargetTimehaeckselklappe");

	self.haeckselklappe = {};
	self.haeckselklappe.index 		= Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.haeckselklappe#index"));
	self.haeckselklappe.charSet 	= getAnimCharacterSet(self.haeckselklappe.index);
	self.haeckselklappe.clip 		= getXMLString(xmlFile, "vehicle.haeckselklappe#clip");
	self.haeckselklappe.clipIdx 	= getAnimClipIndex(self.haeckselklappe.charSet, self.haeckselklappe.clip);	
	self.haeckselklappe.speedScale 	= getXMLFloat(xmlFile, "vehicle.haeckselklappe#speedScale");
	self.haeckselklappe.duration 	= getAnimClipDuration(self.haeckselklappe.charSet, self.haeckselklappe.clipIdx);
	self.haeckselklappe.curTime 	= getAnimTrackTime(self.haeckselklappe.charSet, 0);
	self.haeckselklappe.targetTime 	= 0;
	self.haeckselklappe.maxFillLevel = getXMLInt(xmlFile, "vehicle.haeckselklappe#maxFillLevel"); 
	local x, y, z = getTranslation( self.fillAutoAimTargetNode );
	self.haeckselklappe.autoAimPos = {x, y, z};
	self.haeckselklappe.autoAimTrans = getXMLFloat(xmlFile, "vehicle.haeckselklappe#autoAimTrans");
	self.setVehicleRpmUp = SpecializationUtil.callSpecializationsFunction("setVehicleRpmUp");
	self.saveMinRpm = 0;
	self.isActor = false;
	self.setachsverschiebung = SpecializationUtil.callSpecializationsFunction("setachsverschiebung");
	local achse = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.achse#index"));
	if achse ~= nil then
		self.achse = {};
		self.achse.node = achse;
		local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.achse#minRot"));
		self.achse.minRot = {};
		self.achse.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
		self.achse.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
		self.achse.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.achse#maxRot"));
		self.achse.maxRot = {};
		self.achse.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
		self.achse.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
		self.achse.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		self.achse.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.achse#rotTime"), 1)*1000;
		self.supportTrans1 = {};
		self.supportTrans1.node = achse;
		local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.achse#minTrans"));
		self.supportTrans1.minRot = {};
		self.supportTrans1.minRot[1] = x;
		self.supportTrans1.minRot[2] = y;
		self.supportTrans1.minRot[3] = z;
		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.achse#maxTrans"));
		self.supportTrans1.maxRot = {};
		self.supportTrans1.maxRot[1] = x;
		self.supportTrans1.maxRot[2] = y;
		self.supportTrans1.maxRot[3] = z;
		self.supportTrans1.rotTime = self.achse.rotTime;
	end;
	self.smokeParticleSystems = {};
    local entry = {};
      entry.ps = {};
      Utils.loadParticleSystem(xmlFile, entry.ps, "vehicle.smokeParticleSystem", self.components, false, nil, self.baseDirectory);
      if table.getn(entry.ps) > 0 then
          entry.isActive = false;
          table.insert(self.smokeParticleSystems, entry);
      end
      local i=0;
      while true do
          local baseName = string.format("vehicle.smokeParticleSystems.smokeParticleSystem(%d)", i);
          if not hasXMLProperty(xmlFile, baseName) then
              break;
          end;
          local entry = {};
          entry.ps = {};
          Utils.loadParticleSystem(xmlFile, entry.ps, baseName, self.components, false, nil, self.baseDirectory);
          if table.getn(entry.ps) > 0 then
              entry.isActive = false;
             entry.cuttingArea = i+1;
              table.insert(self.smokeParticleSystems, entry);
          end
          i = i+1;
      end;
	
	self.achserear = false;
	self.achsefront = true;
	
	
end;

function TA23065:delete()
	for _, entry in ipairs(self.smokeParticleSystems) do
          Utils.deleteParticleSystem(entry.ps);
          entry.isActive = false;
	end;
end;

function TA23065:readStream(streamId, connection)
	--self.haeckselklappe.targetTime = streamReadFloat32(streamId);
	local curTime = streamReadFloat32(streamId);
	self.haeckselklappe.targetTime = curTime;
	--self:updateTargetTimehaeckselklappe(curTime, true);
end;

function TA23065:writeStream(streamId, connection)
	streamWriteFloat32(streamId, self.haeckselklappe.targetTime);
end;

function TA23065:mouseEvent(posX, posY, isDown, isUp, button)

end;

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

end;

function TA23065:update(dt)
	
	local pro = self.capacity / 100;
		local percent = self.fillLevel/(self.capacity/100);

		if achsefront then
 
 
		if percent <= 50.0 then  
			achsefront = false;
			self.achserear = false;
			achsverschiebungEvent.sendEvent(self, self.achserear);
		end;
  
		else

		if percent > 50.0 then 
			achsefront = true;
			self.achserear = true;
			achsverschiebungEvent.sendEvent(self, self.achserear);
		end;
    
	end; 	
		if self:getIsActive() then
			if (self.tipState == Trailer.TIPSTATE_OPENING or self.tipState == Trailer.TIPSTATE_OPEN) then
				if self.attacherVehicle  ~= nil then
					if self.attacherVehicle.motor ~= nil then
                    self:setVehicleRpmUp(dt, true);
					end;
				end;
			elseif (self.tipState == Trailer.TIPSTATE_CLOSING or self.tipState == Trailer.TIPSTATE_CLOSED) then
					self:setVehicleRpmUp(nil, false);
					end;
				end;
       
	local curTime = getAnimTrackTime(self.haeckselklappe.charSet, 0);
	local targetTime = nil;
	self.haeckselklappe.curTime = curTime;

	if self:getIsActiveForInput() then	
		if InputBinding.isPressed(InputBinding.haeckselklappe_open) then
			targetTime = Utils.getMovedLimitedValues({self.haeckselklappe.curTime}, {0}, {self.haeckselklappe.duration}, 1, self.haeckselklappe.duration, dt, false);
		elseif InputBinding.isPressed(InputBinding.haeckselklappe_close) then
			targetTime = Utils.getMovedLimitedValues({self.haeckselklappe.curTime}, {0}, {self.haeckselklappe.duration}, 1, self.haeckselklappe.duration, dt, true);
		end;
	end;
	
	if self.fillLevel >= self.haeckselklappe.maxFillLevel then
        targetTime = Utils.getMovedLimitedValues({self.haeckselklappe.curTime}, {0}, {self.haeckselklappe.duration}, 1, self.haeckselklappe.duration, dt, false);
    end;

	if targetTime ~= nil then
			self:updateTargetTimehaeckselklappe(targetTime[1]);
	end;
	
		
	self.jointmove = false;
	if math.abs(curTime - self.haeckselklappe.targetTime) > 5 then
		if curTime < self.haeckselklappe.targetTime then
			assignAnimTrackClip(self.haeckselklappe.charSet, 0, self.haeckselklappe.clipIdx, self.haeckselklappe.clip); 
			setAnimTrackSpeedScale(self.haeckselklappe.charSet, 0, self.haeckselklappe.speedScale);
			enableAnimTrack(self.haeckselklappe.charSet, 0);	
			self.jointmove = true;
		elseif curTime > self.haeckselklappe.targetTime then
			assignAnimTrackClip(self.haeckselklappe.charSet, 0, self.haeckselklappe.clipIdx, self.haeckselklappe.clip); 
			setAnimTrackSpeedScale(self.haeckselklappe.charSet, 0, -self.haeckselklappe.speedScale);
			enableAnimTrack(self.haeckselklappe.charSet, 0);	
			self.jointmove = true;
		end;
		local fac = self.haeckselklappe.targetTime/self.haeckselklappe.duration;
		setTranslation( self.fillAutoAimTargetNode, 
			self.haeckselklappe.autoAimPos[1], self.haeckselklappe.autoAimPos[2], self.haeckselklappe.autoAimPos[3]+fac*self.haeckselklappe.autoAimTrans );
	else
		--assignAnimTrackClip(self.haeckselklappe.charSet, 0, self.haeckselklappe.clipIdx, self.haeckselklappe.clip); 
		setAnimTrackSpeedScale(self.haeckselklappe.charSet, 0, 0);
		disableAnimTrack(self.haeckselklappe.charSet, 0);	
		clearAnimTrackClip(self.haeckselklappe.charSet, 0);		
		self.jointmove = false;
	end;
	
end;

function TA23065:updateTick(dt)
		if self.achserear ~= nil then	
			if self.achserear then
				local x, y, z = getTranslation(self.supportTrans1.node);
				local trans = {x,y,z};
				local newTrans = Utils.getMovedLimitedValues(trans, self.supportTrans1.maxRot, self.supportTrans1.minRot, 3, self.supportTrans1.rotTime, dt, true);
				setTranslation(self.supportTrans1.node, unpack(newTrans));
				if math.abs(self.supportTrans1.minRot[1]-newTrans[1]) < 0.001 then
					local x, y, z = getRotation(self.achse.node);
					local rot = {x,y,z};
					local newRot = Utils.getMovedLimitedValues(rot, self.achse.maxRot, self.achse.minRot, 3, self.achse.rotTime, dt, true);
					setRotation(self.achse.node, unpack(newRot));
				end;
			else
				local x, y, z = getRotation(self.achse.node);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.achse.maxRot, self.achse.minRot, 3, self.achse.rotTime, dt, false);
				setRotation(self.achse.node, unpack(newRot));
				if math.abs(self.achse.maxRot[1]-newRot[1]) < 0.001 then
					local x, y, z = getTranslation(self.supportTrans1.node);
					local trans = {x,y,z};
					local newTrans = Utils.getMovedLimitedValues(trans, self.supportTrans1.maxRot, self.supportTrans1.minRot, 3, self.supportTrans1.rotTime, dt, false);
					setTranslation(self.supportTrans1.node, unpack(newTrans));
				end;
			end;
			for i, jointDesc in pairs(self.componentJoints) do
				setJointFrame(self.componentJoints[i].jointIndex, 0, self.componentJoints[i].jointNode);
			end;
		end;
	
	if self.fillLevel > 0 then
	    if self.currentFillType == Fillable.FILLTYPE then
			self:setAddedParts(0);			
		end;              
	end;

		if self.isClient then
               for _,ps in pairs(self.smokeParticleSystems) do                  
                  if self.currentFillType == Fillable.FILLTYPE_MANURE and self.fillLevel > 3000 and self.movingDirection == 0 then                       
                      Utils.setEmittingState(ps.ps, true);
                  else
                      Utils.setEmittingState(ps.ps, false);
                  end
               end
		end;

	
end;

function TA23065: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, -1200);
			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.0000011*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 TA23065:setTowballDirection()
	
end;

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

function TA23065:readStream(streamId, connection)
	self.achserear = streamReadBool(streamId);
end;

function TA23065:writeStream(streamId, connection)
	streamWriteBool(streamId, self.achserear);
end;

function TA23065:onDetach()
	
	if not self.achserear then
			self.achserear = not self.achserear;
			achsverschiebungEvent.sendEvent(self, self.achserear);
		end;

	if self.deactivateOnDetach then
        self:onDeactivate(self);
    else
        self:onDeactivateSounds(self);
    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;
end;

function TA23065:draw()
		if self.fillLevel <= self.haeckselklappe.maxFillLevel then
		g_currentMission:addExtraPrintText( string.format(g_i18n:getText("haeckselklappe_close"), InputBinding.getKeyNamesOfDigitalAction(InputBinding.haeckselklappe_close) ) );
   	    g_currentMission:addExtraPrintText( string.format(g_i18n:getText("haeckselklappe_open"),  InputBinding.getKeyNamesOfDigitalAction(InputBinding.haeckselklappe_open) ) );
	   end;
		
end;

function TA23065:updateTargetTimehaeckselklappe(targetTime, noEventSend)
	UpdateTargetTimehaeckselklappeEvent.sendEvent(self, targetTime, noEventSend);
	
	self.haeckselklappe.targetTime = targetTime;
	--print("self.haeckselklappe.targetTime="..self.haeckselklappe.targetTime);
end;

--
--
--
--
--
UpdateTargetTimehaeckselklappeEvent = {};
UpdateTargetTimehaeckselklappeEvent_mt = Class(UpdateTargetTimehaeckselklappeEvent, Event);

InitEventClass(UpdateTargetTimehaeckselklappeEvent, "UpdateTargetTimehaeckselklappeEvent");

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

function UpdateTargetTimehaeckselklappeEvent:new(object, value)
    local self = UpdateTargetTimehaeckselklappeEvent:emptyNew()
    self.object = object;
	self.value = value;
    return self;
end;

function UpdateTargetTimehaeckselklappeEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
	self.object = networkGetObject(id);
	self.value = streamReadFloat32(streamId);
    self:run(connection);
end;

function UpdateTargetTimehaeckselklappeEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.object));
	streamWriteFloat32(streamId, self.value);
end;

function UpdateTargetTimehaeckselklappeEvent:run(connection)
	self.object:updateTargetTimehaeckselklappe(self.value, true);
	if not connection:getIsServer() then
		g_server:broadcastEvent(UpdateTargetTimehaeckselklappeEvent:new(self.object, self.value), nil, connection, self.object);
	end;
end;

function UpdateTargetTimehaeckselklappeEvent.sendEvent(vehicle, value, noEventSend)

	if vehicle.haeckselklappe.targetTime ~= value then
		if noEventSend == nil or noEventSend == false then
			if g_server ~= nil then
				g_server:broadcastEvent(UpdateTargetTimehaeckselklappeEvent:new(vehicle, value), nil, nil, vehicle);
			else
				g_client:getServerConnection():sendEvent(UpdateTargetTimehaeckselklappeEvent:new(vehicle, value));
			end;
		end;
	end;
end;