local metadata = {
"## Interface:FS15 1.1.0.0 RC12",
"## Title: FoerderBandLoad",
"## Notes: Funktionen für Förderband",
"## Author: Marhu",
"## Version: 2.1.3-3b",
"## Date: 16.02.2015",
"## Web: http://marhu.net"
}
  
source(g_currentModDirectory.."FoerderBandStatusEvent.lua");
source(g_currentModDirectory.."FoerderBandMoveBeltEvent.lua");

g_FoerderBandLoadDir = g_currentModDirectory;

FoerderBandLoad = {};

function FoerderBandLoad.prerequisitesPresent(specializations)
    return true
end;

function FoerderBandLoad:load(xmlFile)
	self.setFillLevel = Utils.overwrittenFunction(self.setFillLevel, FoerderBandLoad.setFillLevel);
	self.fillShovelFromTrigger = Utils.overwrittenFunction(self.fillShovelFromTrigger, FoerderBandLoad.fillShovelFromTrigger);
	self.shovelTipTrigger.getTipInfoForTrailer = Utils.overwrittenFunction(self.shovelTipTrigger.getTipInfoForTrailer, FoerderBandLoad.getTipInfoForTrailer);
	self.shovelTipTrigger.updateTrailerTipping = Utils.overwrittenFunction(self.shovelTipTrigger.updateTrailerTipping, FoerderBandLoad.updateTrailerTipping);
	self.updateInitialize = FoerderBandLoad.updateInitialize;
	self.findTrailer = FoerderBandLoad.findTrailer;
	self.TrailerRaycast = FoerderBandLoad.TrailerRaycast;
	self.updateTriggerBackup = FoerderBandLoad.updateTriggerBackup;
	self.updateBelts = FoerderBandLoad.updateBelts;
	self.UpDown = FoerderBandLoad.UpDown;
	self.LeftRight = FoerderBandLoad.LeftRight;
	self.transport = FoerderBandLoad.transport;
	self.setDrawbar = FoerderBandLoad.setDrawbar;
	self.setOn = FoerderBandLoad.setOn;
	
	self.FoerderBandLoadDir = g_FoerderBandLoadDir
	
	self.Belts = {}
	local i = 0;
    while true do
        local key = string.format("vehicle.ScrollerNodes.ScrollerNode(%d)", i);
        if not hasXMLProperty(xmlFile, key) then
            break;
        end;
		self.Belts[i+1] = {}
		self.Belts[i+1].node = Utils.indexToObject(self.components, getXMLString(xmlFile, key .. "#index"));
		self.Belts[i+1].Parameter = getXMLString(xmlFile, key .. "#shaderParameterName");
		self.Belts[i+1].scrollSpeed = getXMLFloat(xmlFile, key .. "#scrollSpeed");
		self.Belts[i+1].Achse = getXMLFloat(xmlFile, key .. "#Achse");
		self.Belts[i+1].scroll = {0,0,0}
		i = i + 1
	end;
	
	self.TrailerFindNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.TrailerFindNode#index"));
	self.TrailerFindLight = getChildAt(self.TrailerFindNode,0);
	
	self.literPerSecond = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.literPerSecond#value"), 1500);
	
	self.BandEffect = EffectManager:loadEffect(xmlFile , "vehicle.BandEffect" , self.components , self )
		
	for i=1,table.getn(Fillable.fillTypeIndexToDesc) do
		self.fillTypes[Fillable.fillTypeIndexToDesc[i].index] = true
	end
	
	local SoundRefNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.workSound#node"));
	local workSound  = getXMLString(xmlFile, "vehicle.workSound#file");
	if workSound  ~= nil and workSound  ~= "" then
		workSound  = Utils.getFilename(workSound, self.baseDirectory);
		self.workSoundRadius = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.workSound#radius"), 50);
		self.workSoundInnerRadius = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.workSound#innerRadius"), 10);
		self.workSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.workSound#volume"), .8);
		self.workSound = createAudioSource("workSound", workSound, self.workSoundRadius, self.workSoundInnerRadius, self.workSoundVolume, 0);
		link(SoundRefNode, self.workSound);
		setVisibility(self.workSound, false);
	end;
			
	local LampNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.SignalLamps#index"));
	if LampNode then
		self.SignalLamps = {}
		for i = 1,getNumOfChildren(LampNode) do
			self.SignalLamps[i] = getChildAt(getChildAt(LampNode,i-1),0);
			setVisibility(self.SignalLamps[i], false);
		end
	end
	
	self.transTime = 10 * 1000;
	self.FillLvlBuffer = 0.5;
	self.transPlaneTime = 0;
	self.transPlaneTmax = 1000;
	self.minFillLvlToUnload = self.capacity;
	self.bodyTypes = true; --for Multifruit Mod
	self.GrabBale = g_currentMission.time - 1
	self.TransportMode = true;
	self.IdentNum = tostring(self.rootNode)
	self.CheckBddy = {}
	self.IsOn = true;
	self.loaded = true;
	self.Initialize = true;
	
	local Foerderer0 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Foerderer#index"));
	if Foerderer0 then
		self.Foerderer = {};
		self.Foerderer.node =  Foerderer0;
		self.Foerderer.maxRot = {math.rad(-7),math.rad(180),math.rad(0)}; -- x-5
		self.Foerderer.minRot = {math.rad(-35),math.rad(180),math.rad(0)};
		self.Foerderer.TransportRot = {math.rad(-5),math.rad(180),math.rad(0)};
	end
	local Traeger = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Traeger#index"));
	if Traeger then
		self.Traeger = {};
		self.Traeger.node =  Traeger;
		self.Traeger.maxRot = {math.rad(5),math.rad(0),math.rad(0)};
		self.Traeger.minRot = {math.rad(35),math.rad(0),math.rad(0)};
		self.Traeger.transRot = {math.rad(-180),math.rad(0),math.rad(0)};
		self.FoerderK = {};
		self.FoerderK.node =  getChildAt(Traeger,0);
		self.FoerderK.maxRot = {math.rad(0),math.rad(-100),math.rad(0)};
		self.FoerderK.minRot = {math.rad(0),math.rad(100),math.rad(0)};
		self.FoerderK.transRot = {math.rad(0),math.rad(0),math.rad(0)};
	end;
	local Trichter = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.Trichter#index"));
	if Trichter then
		self.Trichter = {};
		self.Trichter.nodeT =  Trichter;
		self.Trichter.maxTrans = {0,0,-0.511};
		self.Trichter.minTrans = {0,0,-0.056};
		self.Trichter.nodeR =  getChildAt(Trichter,0);
		self.Trichter.maxRot = {math.rad(55),math.rad(0),math.rad(0)};
		self.Trichter.minRot = {math.rad(0),math.rad(0),math.rad(0)};
	end
	
	for i = 1, table.getn(self.inputAttacherJoints) do
		if self.inputAttacherJoints[i].jointType == Vehicle.JOINTTYPE_TRAILER then
			for j = 1, table.getn(self.components) do
				if self.components[j].node == self.inputAttacherJoints[i].rootNode then
					for k = 1, table.getn(self.componentJoints) do
						if self.componentJoints[k].componentIndices[2] == j then
							self.Drawbar = {}
							self.Drawbar.Joint = self.componentJoints[k]
							self.Drawbar.rootNode = self.inputAttacherJoints[i].rootNode
							break;
						end
					end
					break;
				end
			end
			break;
		end
	end
	
	self.FoerderBandDirtyFlag = self:getNextDirtyFlag();
end;

function FoerderBandLoad:delete()
end;

function FoerderBandLoad:getSaveAttributesAndNodes(nodeIdent)

	local attributes = "";
    local nodes = "";
	
    local rot1 = {getRotation(self.Foerderer.node)}
	local rot2 = {getRotation(self.Traeger.node)}
	local rot3 = {getRotation(self.FoerderK.node)}
	local Mode = 0
	if self.TransportMode ~= nil then
		Mode = self.TransportMode and 2 or 1
	end
	attributes = attributes ..' Foerderer="'.. tostring(rot1[1])..'" Traeger="'..tostring(rot2[1])..'" FoerderK="'..tostring(rot3[2])..'" Mode="'..tostring(Mode)..'"';
	
    return attributes,nodes;
end

function FoerderBandLoad:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	local ModeTable = {[0] = nil,[1]=false,[2]=true};
	local Mode = tonumber(Utils.getNoNil(getXMLFloat(xmlFile, key .. string.format("#Mode")), 2));
	if Mode ~= 2 then
		self.TransportMode = ModeTable[Mode];
		self.loadAttri = true;
		self.LastTransportMode = self.TransportMode;
		local rot1 = {getRotation(self.Foerderer.node)}
		local rot2 = {getRotation(self.Traeger.node)}
		local rot3 = {getRotation(self.FoerderK.node)}
		local rot3 = {getRotation(self.FoerderK.node)}
		local rot4 = {getRotation(self.Trichter.nodeR)}
		local trans = {getRotation(self.Trichter.nodeT)}
		
		local rot1x = Utils.getNoNil(getXMLFloat(xmlFile, key .. string.format("#Foerderer")), self.Foerderer.maxRot[1]);
		local rot2x = Utils.getNoNil(getXMLFloat(xmlFile, key .. string.format("#Traeger")), self.Traeger.transRot[1]);
		local rot3y = Utils.getNoNil(getXMLFloat(xmlFile, key .. string.format("#FoerderK")), self.FoerderK.transRot[2]);
		
		rot1[1] = rot1x
		rot2[1] = rot2x
		rot3[2] = rot3y
		rot4[1] = self.Trichter.maxRot[1]
		trans[3] = self.Trichter.maxTrans[3]
		
		setRotation(self.Foerderer.node, unpack(rot1));
		setRotation(self.Traeger.node, unpack(rot2));
		setRotation(self.FoerderK.node, unpack(rot3));
		setRotation(self.Trichter.nodeR, unpack(rot4));
		setTranslation(self.Trichter.nodeT, unpack(trans));
		
		for i=1, table.getn(self.movingTools) do
			local tool = self.movingTools[i]
			Cylindered.updateComponentJoints(self, tool, true);
		end
	end
		
	return BaseMission.VEHICLE_LOAD_OK;
end

function FoerderBandLoad:writeStream(streamId, connection)
	local rot1 = {getRotation(self.Foerderer.node)}
	local rot2 = {getRotation(self.Traeger.node)}
	local rot3 = {getRotation(self.FoerderK.node)}
	local Mode = 0
	if self.TransportMode ~= nil then
		Mode = self.TransportMode and 2 or 1
	end
	streamWriteInt8(streamId, Mode);
	streamWriteFloat32(streamId, rot1[1]);
	streamWriteFloat32(streamId, rot2[1]);
	streamWriteFloat32(streamId, rot3[2]);
end;

function FoerderBandLoad:readStream(streamId, connection)
    local ModeTable = {[0] = nil,[1]=false,[2]=true};
	local Mode = streamReadInt8(streamId);
	local rot1x = streamReadFloat32(streamId);
	local rot2x = streamReadFloat32(streamId);
	local rot3y = streamReadFloat32(streamId);
	
	self.TransportMode = ModeTable[Mode];
	self.LastTransportMode = self.TransportMode;
	
	local rot1 = {getRotation(self.Foerderer.node)}
	local rot2 = {getRotation(self.Traeger.node)}
	local rot3 = {getRotation(self.FoerderK.node)}
	local rot3 = {getRotation(self.FoerderK.node)}
	local rot4 = {getRotation(self.Trichter.nodeR)}
	local trans = {getRotation(self.Trichter.nodeT)}
	
	rot1[1] = rot1x
	rot2[1] = rot2x
	rot3[2] = rot3y
	rot4[1] = self.Trichter.maxRot[1]
	trans[3] = self.Trichter.maxTrans[3]
	
	setRotation(self.Foerderer.node, unpack(rot1));
	setRotation(self.Traeger.node, unpack(rot2));
	setRotation(self.FoerderK.node, unpack(rot3));
	setRotation(self.Trichter.nodeR, unpack(rot4));
	setTranslation(self.Trichter.nodeT, unpack(trans));
	
	for i=1, table.getn(self.movingTools) do
		local tool = self.movingTools[i]
		Cylindered.updateComponentJoints(self, tool, true);
		Cylindered.setDirty(self, tool);
	end
	
	self.Initialize = true;
	self.InitializeTimer = 1;
	
	if connection:getIsServer() then
    end;
end;

function FoerderBandLoad:writeUpdateStream(streamId, connection, dirtyMask)
	if bitAND(dirtyMask, self.FoerderBandDirtyFlag) ~= 0 and (connection.getIsServer(connection) or connection ~= self.getOwner(self)) then
		
		local rot1 = {getRotation(self.Foerderer.node)}
		local rot2 = {getRotation(self.Traeger.node)}
		local rot3 = {getRotation(self.FoerderK.node)}
		local Mode = 0
		if self.TransportMode ~= nil then
			Mode = self.TransportMode and 2 or 1
		end
		
		streamWriteBool(streamId, true);
		streamWriteInt8(streamId, Mode);
		streamWriteFloat32(streamId, rot1[1]);
		streamWriteFloat32(streamId, rot2[1]);
		streamWriteFloat32(streamId, rot3[2]);
	
	else
		streamWriteBool(streamId, false);
    end
end;

function FoerderBandLoad:readUpdateStream(streamId, timestamp, connection)
	local hasUpdate = streamReadBool(streamId);
	if hasUpdate then
		
		local ModeTable = {[0] = nil,[1]=false,[2]=true};
		local Mode = streamReadInt8(streamId);
		local rot1x = streamReadFloat32(streamId);
		local rot2x = streamReadFloat32(streamId);
		local rot3y = streamReadFloat32(streamId);
		
		self.TransportMode = ModeTable[Mode];
		self.LastTransportMode = self.TransportMode;
		
		local rot1 = {getRotation(self.Foerderer.node)}
		local rot2 = {getRotation(self.Traeger.node)}
		local rot3 = {getRotation(self.FoerderK.node)}
		local rot4 = {getRotation(self.Trichter.nodeR)}
		local trans = {getRotation(self.Trichter.nodeT)}
		
		rot1[1] = rot1x
		rot2[1] = rot2x
		rot3[2] = rot3y
		rot4[1] = self.Trichter.maxRot[1]
		trans[3] = self.Trichter.maxTrans[3]
		
		setRotation(self.Foerderer.node, unpack(rot1));
		setRotation(self.Traeger.node, unpack(rot2));
		setRotation(self.FoerderK.node, unpack(rot3));
		--setRotation(self.Trichter.nodeR, unpack(rot4));
		--setTranslation(self.Trichter.nodeT, unpack(trans));
		
		for i=1, table.getn(self.movingTools) do
			local tool = self.movingTools[i]
			Cylindered.updateComponentJoints(self, tool, true);
			Cylindered.setDirty(self, tool);
		end
		
		if connection:getIsServer() then
			
		end
		if not connection:getIsServer() then
			-- we are on the server, write the data to the clients
		   self:raiseDirtyFlags(self.FoerderBandDirtyFlag);
		end;
	end;
end;

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

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

local function CheckNeedPartUpdate(part)
    local refX,refY,refZ;
    local dirX, dirY, dirZ = 0,0,0;
    if part.referencePoint ~= nil then
        refX,refY,refZ = getWorldTranslation(part.referencePoint);
        if part.referenceDistance == 0 then
            if part.useLocalOffset then
                local lx, ly, lz = worldToLocal(part.node, refX, refY, refZ);
                dirX, dirY, dirZ = localDirectionToWorld(part.node, lx-part.localReferencePoint[1], ly-part.localReferencePoint[2], lz);
            else
                local x,y,z = getWorldTranslation(part.node);
                dirX, dirY, dirZ = refX - x, refY-y, refZ-z;
            end
        else
            local r1 = part.localReferenceDistance;
            local r2 = part.referenceDistance;
            local lx, ly, lz = worldToLocal(part.node, refX, refY, refZ);
            local ix, iy, i2x, i2y = Utils.getCircleCircleIntersection(0,0, r1, ly, lz, r2);
	
            if ix ~= nil then
                if i2x ~= nil then
                    local side = ix*(lz-iy) - iy*(ly-ix);
                    if (side < 0) ~= (part.localReferenceAngleSide < 0) then
                        iy = i2y;
                        ix = i2x;
                    end
                end
                dirX, dirY, dirZ = localDirectionToWorld(part.node, 0, ix, iy)
            end;
        end;
    else
        dirX, dirY, dirZ = localDirectionToWorld(part.referenceFrame, 0, 0, 1)
    end
    if dirX ~= 0 or dirY ~= 0 or dirZ ~= 0 then
		 if part.invertZ then
            dirX = -dirX;
            dirY = -dirY;
			dirZ = -dirZ;
        end;
		if part.LdirX then
			if math.abs(part.LdirX - dirX) >= 0.1 or math.abs(part.LdirY - dirY) >= 0.1 or math.abs(part.LdirZ - dirZ) >= 0.1 then
				part.LdirX,part.LdirY,part.LdirZ = dirX, dirY, dirZ
				local t = math.abs(part.LdirX - dirX).." "..math.abs(part.LdirY - dirY) .." ".. math.abs(part.LdirZ - dirZ)
				return true;
			else
				return false;
			end
		else
			part.LdirX,part.LdirY,part.LdirZ = dirX, dirY, dirZ;
			return true;
		end
	end
	
	return false;
end;

function FoerderBandLoad:updateInitialize(dt)
	if self.loaded then
		self.loaded = nil
		self:setOn(false)
	end
	if self.loadAttri or self.InitializeTimer then
		self.loadAttri = nil
		if self.InitializeTimer and self.InitializeTimer > 0 then  
			self.InitializeTimer = self.InitializeTimer -dt;
		else
			self.InitializeTimer = nil;
		end
		for i, part in ipairs(self.movingParts) do
	        Cylindered.updateMovingPart(self, part, true);
	        if CheckNeedPartUpdate(part) then
				self.loadAttri = true;
				self.InitializeTimer = 1000;
			end;
	    end
	end
	if self.loadAttri or self.InitializeTimer then 
		return true;
	end
	return;
end

function FoerderBandLoad:update(dt)
	
	if self.Initialize then self.Initialize = self:updateInitialize(dt) end;
	
	if self:getIsActiveForInput() then
		if InputBinding.hasEvent(InputBinding.FoerderBand_ONOFF) then
			self:setOn(not self.IsOn)
		end
		if InputBinding.isPressed(InputBinding.FoerderBand_RAUF)  then
			if self.TransportMode == true then
				self.TransportMode = false
				self:raiseDirtyFlags(self.FoerderBandDirtyFlag);
			elseif self.TransportMode == nil then
				self:UpDown(true,dt)
			end
		elseif InputBinding.isPressed(InputBinding.FoerderBand_RUNTER) then
			local rot = {getRotation(self.Foerderer.node)}
			if rot[1] - self.Foerderer.maxRot[1] >= -0.001 then
				if self.fillLevel <= 0 then
					self.TransportMode = true;
					self.LastTransportMode = nil;
					self:setOn(false)
					self:raiseDirtyFlags(self.FoerderBandDirtyFlag);
				end
			elseif self.TransportMode == nil then
				self:UpDown(false,dt)
			end;		
		end;
		if self.TransportMode == nil then
			if InputBinding.isPressed(InputBinding.FoerderBand_LINKS) then
				self:LeftRight(true,dt)
			elseif InputBinding.isPressed(InputBinding.FoerderBand_RECHTS) then
				self:LeftRight(false,dt)
			end;
		end
	end
	
	if self.TransportMode ~= self.LastTransportMode then
		self:transport(not self.TransportMode,dt)
	end
	
end;

function FoerderBandLoad:updateTick(dt)
	if self.isServer then
		local old_inRange = self.inRange;
		self.inRange = false; 
		if self.IsOn then
			if self.triggerBackup then self:updateTriggerBackup(dt) end
			
			if self.currentFillType ~= Fillable.FILLTYPE_UNKNOWN and self.fillLevel > self.minFillLvlToUnload then
				self.minFillLvlToUnload = 0;
				
				if self:findTrailer() then
					if self.trailerFound or self.objectFound then
										
						local deltaLevel = self.literPerSecond*dt/1000.0;
						deltaLevel = math.min(self.fillLevel, deltaLevel);
						
						local x,y,z = getWorldTranslation(self.fillVolumeDischargeInfo.node)
						local d1x,d1y,d1z = localDirectionToWorld(self.fillVolumeDischargeInfo.node,self.fillVolumeDischargeInfo.width,0,0)
						local d2x,d2y,d2z = localDirectionToWorld(self.fillVolumeDischargeInfo.node,0,0,self.fillVolumeDischargeInfo.length)
						
						if self.trailerFound then
							deltaLevel = math.min(deltaLevel, self.trailerFound.capacity - self.trailerFound.fillLevel);
							self.trailerFound:setFillLevel(self.trailerFound.fillLevel + deltaLevel, self.currentFillType,false,{x=x,y=y,z=z,d1x=d1x,d1y=d1y,d1z=d1z,d2x=d2x,d2y=d2y,d2z=d2z});
						else
							deltaLevel = math.min(deltaLevel, self.objectFound.bunkerCapacity - self.objectFound.bunkerFillLevel);
							deltaLevel = (self.objectFound:addShovelFillLevel(self, deltaLevel, self.currentFillType)) or 0;
							self.bgalevel = (self.bgalevel or 0) + deltaLevel
						end
											
						self:setFillLevel(self.fillLevel-deltaLevel, self.currentFillType,true,{x=x,y=y,z=z,d1x=d1x,d1y=d1y,d1z=d1z,d2x=d2x,d2y=d2y,d2z=d2z});
										
						self.inRange = true; 
				
					end;
					
					if self.fillLevel < 0.00001 and self.fillLevel > 0 then
						for i = 1, table.getn(self.fillVolumes) do
							for j = 1,3 do
								self.fillVolumes[i].uvPosition[j] = 0
							end
						end
						self:setFillLevel(0, Fillable.FILLTYPE_UNKNOWN);
					end
				end;
			elseif self.minFillLvlToUnload == 0 then
				self.minFillLvlToUnload = self.capacity
			elseif self.fillLevel > 0 then
				self.minFillLvlToUnload = math.max(0,self.minFillLvlToUnload-dt)
			end;
			
			
		end;
		if old_inRange ~= self.inRange then
			self.SendEvent = true;
		end
		if self.TrailerFindLight_Time then
			if self.TrailerFindLightVisible ~= true then
				self.TrailerFindLightVisible = true
				self.SendEvent = true;
			end
			self.TrailerFindLight_Time = self.TrailerFindLight_Time - dt;
			if self.TrailerFindLight_Time <= 0 then
				self.TrailerFindLight_Time = nil;
			end
		elseif self.TrailerFindLightVisible == true then
			self.TrailerFindLightVisible = nil;
			self.SendEvent = true;
		end;
		if self.fillLevelChange then
			if self.moveBelts == nil then
				FoerderBandMoveBeltEvent.sendEvent(self,true)
			end
			self.moveBelts = true
		elseif self.moveBelts ~= nil then
			if self.moveBelts == false then
				self.moveBelts = nil;
				FoerderBandMoveBeltEvent.sendEvent(self,false)
			else
				self.moveBelts = false 
			end
		end
	end;
	
	if self.isClient then	
		if self.moveBelts then self:updateBelts(dt) end
		if self.inRange and not self.turnOn then
			self.turnOn = true;
			for i = 1,table.getn(self.BandEffect.effectNodes) do
				local mat = Fillable.getFillMaterial(self.currentFillType , self.BandEffect.effectNodes[i].materialType , self.BandEffect.effectNodes[i].materialTypeId)
				setMaterial(self.BandEffect.effectNodes[i].node,mat,0)	
			end
			EffectManager:startEffect(self.BandEffect)					
			playSample(self.workSound, 0, 1, 0);
			setVisibility(self.workSound, true);
			setVisibility(self.SignalLamps[2], true);
		elseif not self.inRange and self.turnOn then 
			self.turnOn = false; 
			
			EffectManager:stopEffect(self.BandEffect)	

			setVisibility(self.workSound, false);
			setVisibility(self.SignalLamps[2], false);
		end;
		if self.TrailerFindLight_Time ~= nil and getVisibility(self.TrailerFindLight) ~= true then
			setVisibility(self.TrailerFindLight,true)
		elseif self.TrailerFindLight_Time == nil and getVisibility(self.TrailerFindLight) == true then
			setVisibility(self.TrailerFindLight,false)
		end
	end;
	
	if self.SendEvent then
		self.SendEvent = nil
		FoerderBandStatusEvent.sendEvent(self)
	end
end

function FoerderBandLoad:draw()
	if self:getIsActiveForInput() then
		g_currentMission:addHelpButtonText(g_i18n:getText("FoerderBand_RAUF"), InputBinding.FoerderBand_RAUF);
		g_currentMission:addHelpButtonText(g_i18n:getText("FoerderBand_RUNTER"), InputBinding.FoerderBand_RUNTER);
		if self.TransportMode == nil then
			g_currentMission:addHelpButtonText(g_i18n:getText("FoerderBand_LINKS"), InputBinding.FoerderBand_LINKS);
			g_currentMission:addHelpButtonText(g_i18n:getText("FoerderBand_RECHTS"), InputBinding.FoerderBand_RECHTS);
			if self.IsOn then
				g_currentMission:addHelpButtonText(g_i18n:getText("FoerderBandAus"), InputBinding.FoerderBand_ONOFF);
			else
				g_currentMission:addHelpButtonText(g_i18n:getText("FoerderBandAn"), InputBinding.FoerderBand_ONOFF);
			end
		end
	end
end;

function FoerderBandLoad:onAttach(attacherVehicle, jointDescIndex)
	if self.attacherJoint.jointType == Vehicle.JOINTTYPE_TRAILERLOW then
		self:setDrawbar(false)
	end
end; 

function FoerderBandLoad:onDetach(attacherVehicle, jointDescIndex)
	self:setDrawbar(true)
end;

function FoerderBandLoad:setFillLevel(org_Funktion, fillLevel, fillType, force, ...)
	if not self.IsOn then fillLevel = self.fillLevel end;
	local old_fillLevel = self.fillLevel
	local r = {org_Funktion(self, fillLevel, fillType, force, ...)}
	local delta = self:getFillLevel(fillType) - old_fillLevel;
	if math.abs(delta) > 0 then
		self.fillLevelChange = true;
	end
	return unpack(r)
end

function FoerderBandLoad:fillShovelFromTrigger(org_Funktion, shovelTrigger, ...)
	local r = {org_Funktion(self, shovelTrigger, ...)}
	self.triggerBackup = shovelTrigger
	return unpack(r)
end

function FoerderBandLoad:getTipInfoForTrailer(org_Funktion, ...)
	if self.fillable.IsOn ~= true then
		return true, math.huge;
	end
	return org_Funktion(self, ...)
end

function FoerderBandLoad:updateTrailerTipping(org_Funktion, trailer, fillDelta, fillType)
	local soll_fillLevel = self.fillable.fillLevel-fillDelta
	local r = {org_Funktion(self, trailer, fillDelta, fillType)}
	local diff = soll_fillLevel-self.fillable.fillLevel
	trailer:setFillLevel(trailer.fillLevel + diff, fillType);
	return unpack(r)
end

function FoerderBandLoad:findTrailer()

    local x,y,z = getWorldTranslation(self.TrailerFindNode);
	local ox,oy,oz = worldToLocal(self.TrailerFindNode, x,y-1,z);
    local dx,dy,dz = localDirectionToWorld(self.TrailerFindNode, ox,oy,oz);
	
	-- local x2 = x + (dx * 7);
	-- local y2 = y + (dy * 7);
	-- local z2 = z + (dz * 7);
	-- drawDebugLine(x, y, z, 1, 0, 0, x2, y2, z2, 1, 0, 0);
		
	self.TrailerFindLight_Time = 2000;
	
    self.trailerFound = nil;
	self.objectFound = nil;
    raycastAll(x, y, z, dx,dy,dz, "TrailerRaycast", 7, self);

	if self.trailerFound then
		if self.trailerFoundSupported == false or self.trailerFound.capacity <= self.trailerFound.fillLevel then
			return false;
		end
	elseif self.objectFound then
		if self.objectFoundSupported == false or not self.objectFound:isa(Bga) or self.objectFound.bunkerCapacity <= self.objectFound.bunkerFillLevel then
			return false;
		end
	else
		return false;
	end

    return true;
end;

function FoerderBandLoad:TrailerRaycast(transformId, x, y, z, distance)

	local trailer = g_currentMission.objectToTrailer[transformId];
    if trailer ~= nil and trailer ~= self then
         if trailer:allowFillType(self.currentFillType) and trailer.getAllowFillFromAir ~= nil and trailer:getAllowFillFromAir() then
             self.trailerFound = trailer;
             self.trailerFoundSupported = true;
         else
             if self.trailerFound == nil then
                 self.trailerFound = trailer;
                 self.trailerFoundSupported = false;
              end
          end
         return false;
      end;
      local object = g_currentMission:getNodeObject(transformId);
      if object ~= nil and object ~= self and object.addShovelFillLevel ~= nil and object.getAllowShovelFillType ~= nil then
         if object:getAllowShovelFillType(self.currentFillType) then
            self.objectFound = object;
            self.objectFoundSupported = true;
            return false;
         else
            if self.objectFound == nil then
                self.objectFound = object;
                self.objectFoundSupported = false;
            end
        end
    end;
  
    return true;

end;

function FoerderBandLoad:updateTriggerBackup(dt)
	if not self.triggerBackup.currentShovel then
		if self.fillLevel < self.capacity then
			local shovelNode = self.components[1]
			if self.shovelNodes then
				for k,v in pairs(self.shovelNodes) do
						shovelNode = k
					break;
				end
			end
			local sx, sy, sz = getWorldTranslation(shovelNode); --shovel
			local nearestDistance = 10;
			local nearestPlane = nil 
			
			if self.triggerBackup.bunkerSilo ~= nil then
				for i,movingPlane in pairs(self.triggerBackup.bunkerSilo.movingPlanes) do
					if movingPlane.fillLevel > 0 then
						local px,py,pz = getWorldTranslation(movingPlane.nodeId); --Plane
						local distance = Utils.vector3Length(sx-px, sy-py, sz-pz);
						if distance < nearestDistance then
							nearestDistance = distance
							nearestPlane = i
						end
					end
				end
				if nearestPlane ~= nil then
					self.triggerBackup.bunkerSilo.movingPlanes[nearestPlane].shovelTrigger:fillShovel(self, dt)
				else
					self.triggerBackup = nil
				end
			elseif self.triggerBackup.fillShovel ~= nil then
				if self.triggerBackup.triggerId then
					local px,py,pz = getWorldTranslation(self.triggerBackup.triggerId); 
					local distance = Utils.vector3Length(sx-px, sy-py, sz-pz);
					if distance < nearestDistance then
						local old_fillLevel = self.fillLevel
						self.triggerBackup:fillShovel(self, dt)
						if old_fillLevel == self.fillLevel then
							self.triggerBackup = nil
						end
					else
						self.triggerBackup = nil
					end
				end
			else
				self.triggerBackup = nil
			end
		end
	end
end;

function FoerderBandLoad:updateBelts(dt)
	self.fillLevelChange = nil
	for i = 1, table.getn(self.fillVolumes) do
		for j = 1,3 do
			self.fillVolumes[i].uvPosition[j] = self.fillVolumes[i].uvPosition[j] - (self.fillVolumes[i].scrollSpeedDischarge[j]*dt)
		end
		setShaderParameter(self.fillVolumes[i].volume, "uvOffset", self.fillVolumes[i].uvPosition[1],self.fillVolumes[i].uvPosition[2],self.fillVolumes[i].uvPosition[3],1,false);
	end
	
	for i=1,table.getn(self.Belts) do
		self.Belts[i].scroll[self.Belts[i].Achse] = self.Belts[i].scroll[self.Belts[i].Achse] + (self.Belts[i].scrollSpeed * dt /1000)
		--if math.abs(self.Belt3.scroll) > self.Belt3.scrollLength * 2 then self.Belt3.scroll = self.Belt3.scroll - (self.Belt3.scrollLength*2) end
		setShaderParameter(self.Belts[i].node, self.Belts[i].Parameter,self.Belts[i].scroll[1],self.Belts[i].scroll[2],self.Belts[i].scroll[3],0,false)	
	end	
end

function FoerderBandLoad:UpDown(dir,dt)
	
	local rotTime = 10 * 1000
	if self.loadAttri then rotTime = rotTime/10 end
	local rot1 = {getRotation(self.Foerderer.node)}
	local rot2 = {getRotation(self.Traeger.node)}
	local newRot1 = Utils.getMovedLimitedValues(rot1, self.Foerderer.maxRot, self.Foerderer.minRot, 3, rotTime, dt, dir);
	local newRot2 = Utils.getMovedLimitedValues(rot2, self.Traeger.maxRot, self.Traeger.minRot, 3, rotTime, dt, dir);
	setRotation(self.Foerderer.node, unpack(newRot1));
	setRotation(self.Traeger.node, unpack(newRot2));
	for i=1, table.getn(self.movingTools) do
		local tool = self.movingTools[i]
		Cylindered.setDirty(self, tool);
		--self:raiseDirtyFlags(self.cylinderedDirtyFlag);
	end
	self:raiseDirtyFlags(self.FoerderBandDirtyFlag);
	
end
function FoerderBandLoad:LeftRight(dir,dt)
		
	local rotTime = 10 * 1000
	if self.loadAttri then rotTime = rotTime/10 end
	local rot1 = {getRotation(self.FoerderK.node)}
	
	local newRot1 = Utils.getMovedLimitedValues(rot1, self.FoerderK.maxRot, self.FoerderK.minRot, 3, rotTime, dt, dir);

	setRotation(self.FoerderK.node, unpack(newRot1));
		
	for i=1, table.getn(self.movingTools) do
		local tool = self.movingTools[i]
		Cylindered.setDirty(self, tool);
		--self:raiseDirtyFlags(self.cylinderedDirtyFlag);
	end
	self:raiseDirtyFlags(self.FoerderBandDirtyFlag);
	
end
function FoerderBandLoad:transport(dir,dt)
	
	
	local rot1 = {getRotation(self.FoerderK.node)}
	local rot3 = {getRotation(self.Trichter.nodeR)}
	--Oberes Band Center
	if dir == false and ((rot1[2] > self.FoerderK.transRot[2] + math.rad(.5)) or (rot1[2] < self.FoerderK.transRot[2] - math.rad(.5))) then
		local rotTime = 5 * 1000
		if self.loadAttri then rotTime = rotTime/10 end
		local tempRot 
		if rot1[2] > self.FoerderK.transRot[2] then
			tempRot = self.FoerderK.minRot
		else
			tempRot = self.FoerderK.maxRot
		end;
		local newRot1 = Utils.getMovedLimitedValues(rot1, self.FoerderK.transRot, tempRot, 3, rotTime, dt, dir);
		setRotation(self.FoerderK.node, unpack(newRot1));
	--Trichter Blech flach	
	elseif dir == false and	math.abs(self.Trichter.minRot[1] - rot3[1]) >= 0.0001 then
		local rotTime = 0.5 * 1000
		if self.loadAttri then rotTime = rotTime/10 end
		local rot3 = {getRotation(self.Trichter.nodeR)}
		local newRot3 = Utils.getMovedLimitedValues(rot3, self.Trichter.minRot, self.Trichter.maxRot, 3, rotTime, dt, dir);
		setRotation(self.Trichter.nodeR, unpack(newRot3));
		local trans = {getTranslation(self.Trichter.nodeT)}
		local newTrans = Utils.getMovedLimitedValues(trans, self.Trichter.minTrans, self.Trichter.maxTrans, 3, rotTime, dt, dir);
		setTranslation(self.Trichter.nodeT, unpack(newTrans));
	else -- Oberes Band Klappen
		local rotTime = 10 * 1000
		if self.loadAttri then rotTime = rotTime/10 end
		
		local Band1Rot = {getRotation(self.Foerderer.node)}
		local Band1newRot = Utils.getMovedLimitedValues(Band1Rot, self.Foerderer.TransportRot, self.Foerderer.maxRot, 3, rotTime, dt, dir);
		setRotation(self.Foerderer.node, unpack(Band1newRot));
		
		local rot2 = {getRotation(self.Traeger.node)}
		local newRot2 = Utils.getMovedLimitedValues(rot2, self.Traeger.transRot, self.Traeger.maxRot, 3, rotTime, dt, dir);
		setRotation(self.Traeger.node, unpack(newRot2));
		
		if math.abs(newRot2[1] - rot2[1]) <= 0.0001 then
			local rotTime = 0.5 * 1000
			if self.loadAttri then rotTime = rotTime/10 end
			local rot3 = {getRotation(self.Trichter.nodeR)}
			local newRot3 = Utils.getMovedLimitedValues(rot3, self.Trichter.minRot, self.Trichter.maxRot, 3, rotTime, dt, dir);
			setRotation(self.Trichter.nodeR, unpack(newRot3));
			local trans = {getTranslation(self.Trichter.nodeT)}
			local newTrans = Utils.getMovedLimitedValues(trans, self.Trichter.minTrans, self.Trichter.maxTrans, 3, rotTime, dt, dir);
			setTranslation(self.Trichter.nodeT, unpack(newTrans));
			
			if math.abs(newRot3[1] - rot3[1]) <= 0.0001 then
				if self.TransportMode == false then
					self.TransportMode = nil;
				end
				self.LastTransportMode = self.TransportMode;
			end
		end
	end;
	
	for i=1, table.getn(self.movingTools) do
		local tool = self.movingTools[i]
		Cylindered.setDirty(self, tool);
		--self:raiseDirtyFlags(self.cylinderedDirtyFlag);
	end	
	self:raiseDirtyFlags(self.FoerderBandDirtyFlag);	
end;

function FoerderBandLoad:setDrawbar(aktiv)
	local rotFoerderer = {getRotation(self.Foerderer.node)}
	if math.deg(rotFoerderer[1]) >= -20 then aktiv = false end
	if self.isServer then
		local rotMinLimit,rotLimit = -0,0
		for i=1,3 do
			if aktiv then
				rotMinLimit = self.Drawbar.Joint.rotMinLimit[i]
				rotLimit = self.Drawbar.Joint.rotLimit[i]
			end
			setJointRotationLimit(self.Drawbar.Joint.jointIndex, i-1, true, rotMinLimit, rotLimit);
		end;	
	end
	setVisibility(self.Drawbar.rootNode,aktiv)
end

function FoerderBandLoad:setOn(on, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if self.TransportMode ~= nil then on = false end;
		self.SendEvent = true;
	end
	self.IsOn = on
	setVisibility(self.SignalLamps[4], self.IsOn);
end
