-- Förderband
-- Farmer Zero v1.1
Foerderband = {};

function Foerderband.prerequisitesPresent(specializations)
	return SpecializationUtil.hasSpecialization(Fillable, specializations);
end;

function Foerderband:load(xmlFile)
	self.WheelBlocks = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Blocks#index"));
	self.Belt = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Belt#index"));
	self.unloadingTrigger = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.unloadingTrigger#node"));
	self.unloadingCapacity = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.unloadingCapacity"), 180);
	self.nolight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.onoffl#nolight"));
	self.noworkl = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.onoffl#noworkl"));
	self.nobeaconl = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.beaconLights.beaconLight#index"));
	self.warnflag = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.onoffl#warnflag"));
	self.worksound = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.worksound#index"));
	setVisibility(self.worksound, false);
	setShaderParameter(self.warnflag, "displacementSpeedFrequencyAndTexOff", 0.6,8,0.3,0.26,false);
	self.setworklight = false;
	self.fallOutParticle = false;
	self.fallOut = false;
	self.isShovel = true;
	self.Bandout = false;
	self.startrollbelt = false;
	self.Transport = false;
	self.fillingtext = false;
	self.SpecialParts = true;
	self.FruitName = FruitUtil.FRUITTYPE_UNKNOWN;
	self.currentInputFruitType = nil;
	self.lastFillLevel = self.fillLevel;

	local hydraulicsCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.hydraulics#count"), 0);
	self.hydraulics = {};
	for i=1, hydraulicsCount do
		local hydraulicName = string.format("vehicle.hydraulics.hydraulic%d", i);
		self.hydraulics[i] = {};
		self.hydraulics[i].node = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#index"));
		self.hydraulics[i].punch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punch"));
		self.hydraulics[i].translationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punchFixpoint"));
		self.hydraulics[i].fixPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#fixpoint"));
		local ax, ay, az;
		if self.hydraulics[i].punch ~= nil then
			ax, ay, az = getWorldTranslation(self.hydraulics[i].punch);
		else
			ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
		end;
		local bx, by, bz = getWorldTranslation(self.hydraulics[i].translationPunch);
		self.hydraulics[i].punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		self.hydraulics[i].doScale = Utils.getNoNil(getXMLBool(xmlFile, hydraulicName .. "#doScale"), false);
	end;

	self.fruitExtraObjects = {};
	local i = 0;
	while true do
	local key = string.format("vehicle.fruitExtraObjects.fruitExtraObject(%d)", i);
	local t = getXMLString(xmlFile, key.."#fruitType");
	local index = getXMLString(xmlFile, key.."#index");
	if t==nil or index==nil then
		break;
	end;
	local node = Utils.indexToObject(self.components, index);
	if node ~= nil then
		if self.currentExtraObject == nil then
			self.currentExtraObject = node;
			setVisibility(node, true);
		else
			setVisibility(node, false);
		end;
		self.fruitExtraObjects[t] = node;
	end;
	i = i + 1
	end;

	self.PlayerTriggerCallback = Foerderband.PlayerTriggerCallback;
	self.trigger = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.PlayerTrigger#index"));
	addTrigger(self.trigger, "PlayerTriggerCallback", self);
	self.deleteListenerId = addDeleteListener(self.trigger, "delete", self);
	self.PlayerinTrigger = false;

end;

function Foerderband:delete()
	removeTrigger(self.trigger);
	removeDeleteListener(self.trigger, self.deleteListenerId);
end;

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

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

function Foerderband:update(dt)
	if self.startrollbelt and self.Bandout then
		self.speed = self.speed + dt*0.0008;
		setShaderParameter(self.Belt, "moveit", 0,self.speed,0,0,false);
		setShaderParameter(self.currentExtraObject, "moveit", 0,-self.speed,0,0,false);
		self.fallOutParticle = true;
	else
		self.fallOutParticle = false; self.startrollbelt = false;
		setShaderParameter(self.Belt, "moveit", 0,0,0,0,false);
		setShaderParameter(self.currentExtraObject, "moveit", 0,0,0,0,false);
		self.speed = 0;
	end;

	if self.PlayerinTrigger == true then
		if InputBinding.hasEvent(InputBinding.FBand_Transport) then
			if self.Bandout then
				self:setAnimationTime(1, self.animationParts[1].offSet, false);
			else
				self:setAnimationTime(1, self.animationParts[1].animDuration, false);
			end;
		end;
		if self.animationParts[1].inputDone and self.animationParts[1].clipEndTime then
			self.Bandout = true; self.isShovel = true;
			if InputBinding.isPressed(InputBinding.FBand_UP) then
				self:setAnimationTime(2, self.animationParts[2].currentPosition+(self.animationParts[2].offSet+dt), false);
			elseif InputBinding.isPressed(InputBinding.FBand_DOWN) then
				self:setAnimationTime(2, self.animationParts[2].currentPosition-(self.animationParts[2].offSet+dt), false);
			end;
		elseif not self.animationParts[1].clipEndTime then
			self:setAnimationTime(2, self.animationParts[2].startPosition, false);
			self.Bandout = false; self.isShovel = nil; self.Transport = false; self.setworklight = false;
		end;
		if self.Bandout then
			if InputBinding.hasEvent(InputBinding.FBand_Stange) then
				self.Transport = not self.Transport
			end;
			if InputBinding.hasEvent(InputBinding.worklights) then
				self.setworklight = not self.setworklight;
			end;
			if InputBinding.hasEvent(InputBinding.FBGlobal) then
				self.fillingtext = not self.fillingtext;
			end;
			if self.fillingtext then
				g_currentMission:addHelpButtonText(g_i18n:getText("FBGlobal"), InputBinding.FBGlobal);
			else
				g_currentMission:addHelpButtonText(g_i18n:getText("FBNormal"), InputBinding.FBGlobal);
			end;
			if self.animationParts[1].inputDone then
				if self.Transport then
					g_currentMission:addHelpButtonText(g_i18n:getText("FBStange_2"), InputBinding.FBand_Stange);
				else
					g_currentMission:addHelpButtonText(g_i18n:getText("FBStange_1"), InputBinding.FBand_Stange);
				end;
				g_currentMission:addExtraPrintText(string.format(""..InputBinding.getKeyNamesOfDigitalAction(InputBinding.FBand_UP) .. " / " .. InputBinding.getKeyNamesOfDigitalAction(InputBinding.FBand_DOWN)..":              "..g_i18n:getText("FBand_3")..""));
			end;
		g_currentMission:addHelpButtonText(g_i18n:getText("worklights"), InputBinding.worklights);
		g_currentMission:addHelpButtonText(g_i18n:getText("FBand_1"), InputBinding.FBand_Transport);
		else
		g_currentMission:addHelpButtonText(g_i18n:getText("FBand_2"), InputBinding.FBand_Transport);
		end;
	end;

	if self:getIsActiveForInput() then
		if InputBinding.hasEvent(InputBinding.FBand_Transport) and not self.Transport then
			if self.Bandout then
				self:setAnimationTime(1, self.animationParts[1].offSet, false);
			else
				self:setAnimationTime(1, self.animationParts[1].animDuration, false);
			end;
		end;
		if self.animationParts[1].inputDone and self.animationParts[1].clipEndTime then
			self.Bandout = true; self.isShovel = true;
		elseif not self.animationParts[1].clipEndTime then
			self:setAnimationTime(2, self.animationParts[2].startPosition, false);
			self.Bandout = false; self.isShovel = nil; self.setworklight = false;
		end;
	end;

	for i=1, table.getn(self.hydraulics) do
		local ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
		local bx, by, bz = getWorldTranslation(self.hydraulics[i].fixPoint);
		local x, y, z = worldDirectionToLocal(getParent(self.hydraulics[i].node), bx-ax, by-ay, bz-az);

		setDirection(self.hydraulics[i].node, x, y, z, 0, 1, 0);
		local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		if self.hydraulics[i].doScale then
			local xScale, yScale, zScale = getScale(self.hydraulics[i].node);
			local newScale = yScale * (distance / self.hydraulics[i].punchDistance);
			setScale(self.hydraulics[i].node, 1, 1, newScale);
		else
			if self.hydraulics[i].punch ~= nil then
				setTranslation(self.hydraulics[i].punch, 0, 0, distance-self.hydraulics[i].punchDistance);
			end;
		end;
	end;
	local hydraulicSoundEnabled = false;
	for i=1, 2 do
		if not self.animationParts[i].inputDone then
			hydraulicSoundEnabled = true;
		end;
	end;
	if hydraulicSoundEnabled then
		if not self.hydraulicSoundEnabled and self.hydraulicSound ~= nil and (self:getIsActiveForSound() or self.PlayerinTrigger == true) then
			playSample(self.hydraulicSound, 0, self.hydraulicSoundVolume, 0);
			setSamplePitch(self.hydraulicSound, self.hydraulicSoundPitchOffset-0.4);
			self.hydraulicSoundEnabled = true;
		end;
	else
		if self.hydraulicSoundEnabled then
			stopSample(self.hydraulicSound);
			self.hydraulicSoundEnabled = false;
		end;
	end;
end;

function Foerderband:updateTick(dt)
if self.Bandout then
	self.inRange = false;
	local nearestDistance = 3.0;
	local px, py, pz = getWorldTranslation(self.unloadingTrigger);
	for i=1, table.getn(g_currentMission.attachables) do
		local vx, vy, vz = getWorldTranslation(g_currentMission.attachables[i].rootNode);
		local distance = Utils.vector2Length(px-vx, pz-vz);
		local attachable = g_currentMission.attachables[i];
		if distance < nearestDistance and attachable.rootNode ~= self.unloadingTrigger and attachable.fillTypes ~= nil and attachable.setFillLevel ~= nil and attachable.fillLevel ~= nil and attachable:allowFillType(self.currentFillType, true) then
			for fruitType,v in pairs(attachable.fillTypes) do
				if fruitType == self.currentFillType then
					if attachable.fillLevel == attachable.capacity or self.filllevel == 0 then
						self.startrollbelt = false;
					elseif attachable.fillLevel ~= attachable.capacity and self.fillLevel ~= 0 then
						local deltaLevel = self.unloadingCapacity*dt/1000.0;
						local fillDelta = math.min(deltaLevel, self.fillLevel)
						self:setFillLevel(self.fillLevel - fillDelta, self.currentFillType);
						attachable:setFillLevel(attachable.fillLevel + fillDelta, self.currentFillType);
						self.startrollbelt = true;
						self.inRange = true;
						self.Transport = false;
						local VehicleName = attachable.name
						if g_i18n:hasText(self.FruitName) then
						self.FruitName = g_i18n:getText(self.FruitName);
						end;
						if self.PlayerinTrigger == true and not self.fillingtext then
							g_currentMission:addExtraPrintText(string.format("%s: %s, %d | %s: %d",self.name ,self.FruitName, self.fillLevel, VehicleName, attachable.fillLevel));
						elseif self.fillingtext then
							setTextBold(true);
							setTextColor(1,1,1,1);
							renderText(0.372,0.97,0.020,string.format("%s: %s, %d  | %s: %d",self.name ,self.FruitName, self.fillLevel, VehicleName, attachable.fillLevel));
						end;
					end;
				end;
			end;
		end;
	end;
end;
	if not self.inRange and self.startrollbelt then
		self.startrollbelt = false;
	end;
	if self.fillLevel == 0 then
		self.currentFillType = FruitUtil.FRUITTYPE_UNKNOWN;
		self.FruitName = FruitUtil.FRUITTYPE_UNKNOWN;
	end;
	if self.currentFillType ~= Fillable.FILLTYPE_UNKNOWN then
		local fruitTypeN = FruitUtil.fillTypeToFruitType[self.currentFillType];
		self.currentInputFruitType = fruitTypeN
		Foerderband.updateExtraObjects(self)
	end;
	if self.Transport then
		self:setAnimationTime(3, self.animationParts[3].animDuration, false);
	else
		self:setAnimationTime(3, self.animationParts[3].offSet, false);
	end;
	if not self.animationParts[3].inputDone then
		if self.attacherVehicle then
		self.attacherVehicle:detachImplementByObject(self);
		end;
	end;
	if not self.animationParts[1].clipStartTime then
		setShaderParameter(self.warnflag, "displacementSpeedFrequencyAndTexOff", 0,0,0,0,false);
		self.wheels[1].steeringAxleScale = 0; self.wheels[2].steeringAxleScale = 0; self.SpecialParts = false;
		if self.beaconLightsActive then
			self.beaconLightsActive = false; setVisibility(self.nobeaconl, self.SpecialParts);
		end;
	else
		if self:doCheckSpeedLimit() and self.lastSpeed * 3600 > 5 then
		local highspeed = self.lastSpeed * 3600
		if highspeed > 5 and highspeed < 70 then
			setShaderParameter(self.warnflag, "displacementSpeedFrequencyAndTexOff", 1.2,8,0.3,0.26,false);
			setRotation(self.warnflag, 0,highspeed,0,0,false);
		end;
		else
			setShaderParameter(self.warnflag, "displacementSpeedFrequencyAndTexOff", 0.2,8,0.3,0.26,false);
			setRotation(self.warnflag, 0,0,0,0,false);
		end;
		self.wheels[1].steeringAxleScale = -0.7; self.wheels[2].steeringAxleScale = -0.7; self.SpecialParts = true;
	end;
	self.lastFillLevel = self.fillLevel;
	Utils.setEmittingState(self.dischargeParticleSystems[self.currentFillType], self.fallOutParticle);
	setVisibility(self.worksound, self.fallOutParticle); setVisibility(self.noworkl, self.setworklight);
	setVisibility(self.nolight, self.SpecialParts);
end;

function Foerderband:draw()
if not self.Transport then
	if self.Bandout then
		g_currentMission:addHelpButtonText(g_i18n:getText("FBand_1"), InputBinding.FBand_Transport);
	else
		g_currentMission:addHelpButtonText(g_i18n:getText("FBand_2"), InputBinding.FBand_Transport);
	end;
end;
end;

function Foerderband:onAttach()
	setVisibility(self.WheelBlocks, false);
end;
function Foerderband:onDetach()
	setVisibility(self.WheelBlocks, true);
end;

function Foerderband:readStream(streamId, connection)
	self.fillingtext(streamReadBool(streamId), false);
end;

function Foerderband:writeStream(streamId, connection)
	streamWriteBool(streamId, self.fillingtext);
end;

function Foerderband:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	if not resetVehicles then
		self.fillingtext = Utils.getNoNil(getXMLBool(xmlFile,key.."#FillText"),false);
		self.Bandout = Utils.getNoNil(getXMLBool(xmlFile,key.."#BandOut"),false);
	end;
	return BaseMission.VEHICLE_LOAD_OK;
end;

function Foerderband:getSaveAttributesAndNodes(nodeIdent)
	local attributes = ' FillText="'..tostring(self.fillingtext)..'"'..
	' BandOut="'.. tostring(self.Bandout) ..'"';
	local node = nil;
	return attributes, node;
end;

function Foerderband:PlayerTriggerCallback(triggerId, otherId, onEnter, onLeave, onStay, otherShapeId)
	if onEnter or onStay then
		if (g_currentMission.player ~= nil and otherId == g_currentMission.player.rootNode) then
			self.PlayerinTrigger = true;
		end;
	elseif onLeave then
		self.PlayerinTrigger = false;
	end;
end;

function Foerderband.updateExtraObjects(self)
	if self.currentExtraObject ~= nil then
		self.currentExtraObject = nil;
	end;
	if self.currentInputFruitType ~= FruitUtil.FRUITTYPE_UNKNOWN then
		local name = FruitUtil.fruitIndexToDesc[self.currentInputFruitType].name;
		local extraObject = self.fruitExtraObjects[name];
		self.FruitName = name;
		if extraObject ~= nil then
			self.currentExtraObject = extraObject;
		end;
	end;
end;