AgrolinerTUW20 = {};

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

function AgrolinerTUW20:load(xmlFile)
	self.setUnloadingState = SpecializationUtil.callSpecializationsFunction("setUnloadingState");
	self.trailerRaycastCallback = AgrolinerTUW20.trailerRaycastCallback;

	self.triggerNode = {};
	self.triggerNode.index = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.unloadingTrigger#node"));
	self.triggerNode.distance = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.unloadingTrigger#maxDistance"), 1);
	self.unloadingTipTrigger = nil;
	
	self.pipe = {};
	self.pipe.node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.pipe#index"));
	self.pipe.distance = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.pipe#raycastDistance"), 7);
	self.pipe.out = false;
	
	self.unloadingCapacity = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.unloadingCapacity"), 100);
	self.saveMinRpm = 0;
	self.planeOpen = false;

	self.isUnloading = false;
	
	self.isLoading = true;
	
	local path = Utils.getFilename("overlay.png", self.baseDirectory);
    self.unloadingOverlay = Overlay:new("hudPDAControl", path, g_currentMission.fruitSymbolX, g_currentMission.fruitSymbolY-0.11, g_currentMission.fruitSymbolSize, g_currentMission.fruitSymbolSize * (4 / 3)); 

end;

function AgrolinerTUW20:delete()
end;

function AgrolinerTUW20:readStream(streamId, connection)
	self.isLoading = true;
	local isUnloading = streamReadBool(streamId);
	self:setUnloadingState(isUnloading, true);
end;

function AgrolinerTUW20:writeStream(streamId, connection)
	streamWriteBool(streamId, self.isUnloading);
end;

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

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

function AgrolinerTUW20:update(dt)
	if self:getIsActiveForInput() then
		if InputBinding.hasEvent(InputBinding.Neptun_ToggleTank) then
			if self.pipe.out then
				self:setAnimationTime(1, self.animationParts[1].offSet, false);
				self:setUnloadingState(false);
			else
				self:setAnimationTime(1, self.animationParts[1].animDuration, false);
			end;
		end;
		if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then
			self:setUnloadingState(not self.isUnloading);
		end;
	end;
	
	if self.animationParts[1].inputDone and self.animationParts[1].clipEndTime then
		self.pipe.out = true;
	elseif not self.animationParts[1].clipEndTime then
		self.pipe.out = false;
	end;
end;

function AgrolinerTUW20:updateTick(dt)
	self.trailerFoundId = 0;
	self.unloadingTipTrigger = nil;
	
	if self.fillLevel > 0 and self.pipe.out then
		for k, tipTrigger in pairs(g_currentMission.tipTriggers) do
			local trailerX, trailerY, trailerZ = getWorldTranslation(self.triggerNode.index);
			local triggerX, triggerY, triggerZ = getWorldTranslation(tipTrigger.triggerId);
			local distance = Utils.vector3Length(trailerX-triggerX, trailerY-triggerY, trailerZ-triggerZ);
			if distance < self.triggerNode.distance then
				self.unloadingTipTrigger = tipTrigger;
			end;
		end;
		if self.unloadingTipTrigger == nil then
			local x, y, z = getWorldTranslation(self.pipe.node);
			local dx, dy, dz = localDirectionToWorld(self.pipe.node, 0, -0.5, 0);
			raycastAll(x, y, z, dx, dy, dz, "trailerRaycastCallback", self.pipe.distance, self);
		end;
	end;
	
	if self:getIsActive() then
		local renderOverlay = false;
		local deltaLevel = 0;
		if self.isUnloading then
			self:setAnimationTime(2, self.animationParts[2].animDuration, false);
		else
			self:setAnimationTime(2, self.animationParts[2].offSet, false);
		end;
		if self.trailerFoundId ~= nil and self.trailerFoundId ~= 0 then
			local trailer = g_currentMission.nodeToVehicle[self.trailerFoundId];
			if trailer ~= nil and trailer ~= self and trailer:allowFillType(self.currentFillType, true) and trailer.allowFillFromAir and trailer.capacity ~= trailer.fillLevel then
				if self.isUnloading then
					deltaLevel = math.min(self.unloadingCapacity*dt/1000.0, trailer.capacity-trailer.fillLevel);
					trailer:setFillLevel(trailer.fillLevel+deltaLevel, self.currentFillType);
				else
					renderOverlay = true;
				end;
			elseif self.isUnloading then
				self:setUnloadingState(false);
			end;
		elseif self.unloadingTipTrigger ~= nil then
			local tipTrigger = self.unloadingTipTrigger;
			local fruitType = FruitUtil.fillTypeToFruitType[self.currentFillType];
			local fruitAccept = tipTrigger.acceptedFruitTypes[fruitType];
			if tipTrigger.isFarmTrigger and fruitAccept then
				if self.isUnloading then
					deltaLevel = self.unloadingCapacity*dt/1000.0;
					g_currentMission.missionStats.farmSiloAmounts[self.currentFillType] = g_currentMission.missionStats.farmSiloAmounts[self.currentFillType] + deltaLevel;
				else
					renderOverlay = true;
				end;
			elseif fruitAccept then
				if self.isUnloading then
					deltaLevel = self.unloadingCapacity*dt/1000.0;
					local priceMultiplier = tipTrigger.priceMultipliers[fruitType];
					local difficultyMultiplier = math.max(3 * (3 - g_currentMission.missionStats.difficulty), 1);
					local money = FruitUtil.fruitIndexToDesc[fruitType].pricePerLiter * priceMultiplier * difficultyMultiplier * deltaLevel;
					g_currentMission:addSharedMoney(money);
				else
					renderOverlay = true;
				end;
			else
				if FruitUtil.fruitIndexToDesc[fruitType].name ~= nil then
					g_currentMission:addWarning(g_i18n:getText(FruitUtil.fruitIndexToDesc[fruitType].name) .. g_i18n:getText("notAcceptedHere"), 0.018, 0.033);
				end;
			end;
			if deltaLevel > 0 then
				tipTrigger:updateMoving(deltaLevel);
			end;
		elseif self.isUnloading then
			self:setUnloadingState(false);
		end;
		self.fillLevel = self.fillLevel-deltaLevel;
		if deltaLevel == 0 and self.isUnloading then
			self:setUnloadingState(false);
		end;
		if self.fillLevel <= 0.0 then
			self.fillLevel = 0.0;
			if self.isUnloading then
				self:setUnloadingState(false);
			end;
			Utils.setEmittingState(self.dischargeParticleSystems[self.currentFillType], self.isUnloading);
			self.currentFillType = Fillable.FILLTYPE_UNKNOWN;
		end;
		self:setFillLevel(self.fillLevel, self.currentFillType);
		self.renderOverlay = renderOverlay;
		Utils.setEmittingState(self.dischargeParticleSystems[self.currentFillType], self.isUnloading);
	end;
end;

function AgrolinerTUW20:trailerRaycastCallback(transformId, x, y, z, distance)
	local vehicle = g_currentMission.nodeToVehicle[transformId];
	if vehicle ~= nil then
		if vehicle.exactFillRootNode == transformId then
			self.trailerFoundId = transformId;
			return false;
		end;
	end;
	return true;
end;

function AgrolinerTUW20:setUnloadingState(state, noEventSend)
	SetUnloadingEvent.sendEvent(self, state, noEventSend);
	self.isUnloading = state;
end;

function AgrolinerTUW20:draw()	
	if self.pipe.out then
		g_currentMission:addHelpButtonText(g_i18n:getText("Neptun_ToggleTank"), InputBinding.Neptun_ToggleTank);
		if self.animationParts[1].inputDone then
			if self.isUnloading then
				g_currentMission:addHelpButtonText(g_i18n:getText("Neptun_EndUnload"), InputBinding.IMPLEMENT_EXTRA2);
			elseif self.renderOverlay then
				self.unloadingOverlay:render();
				g_currentMission:addHelpButtonText(g_i18n:getText("Neptun_Unload"), InputBinding.IMPLEMENT_EXTRA2);
			end;
		end;
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("Neptun_ToggleTank"), InputBinding.Neptun_ToggleTank);
	end;
end;

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

function AgrolinerTUW20:onDetach()
	if self.deactivateOnDetach then
        self:onDeactivate(self);
    else

    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 AgrolinerTUW20:onLeave()
	if self.deactivateOnLeave then
        self:onDeactivate(self);
    else

    end;
end;

function AgrolinerTUW20:onDeactivate()
	self:setUnloadingState(false);
	self.unloadingTipTrigger = nil;
	for k, particle in pairs(self.dischargeParticleSystems) do
		Utils.setEmittingState(particle, false);
	end;
    self:onDeactivateSounds(self);
end;