--
-- FlieglHakenLift NEW SCRIPT FOR LS2009
--
-- @Original-author Manuel L. (1.LS-Modschmiede)
-- @author Hoschiander (www.mein-ls.de)
-- @date 28/10/2009

FlieglHakenLift = {};

Vehicle.registerJointType("container");

function FlieglHakenLift.prerequisitesPresent(specializations)
	return SpecializationUtil.hasSpecialization(Motorized, specializations);
end;

function FlieglHakenLift:load(xmlFile)

-- ROOTPARTARM START --
	self.allowTipDischarge = false;
	local rootPart = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.rootArm#index"));
		if rootPart ~= nil then
			self.rootPartArm = {};
			self.rootPartArm.node = rootPart;
			
			local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rootArm#minRot"));
			self.rootPartArm.minRot = {};
			self.rootPartArm.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
			self.rootPartArm.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
			self.rootPartArm.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
	
			x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rootArm#maxRot"));
			self.rootPartArm.maxRot = {};
			self.rootPartArm.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
			self.rootPartArm.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
			self.rootPartArm.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
			
			self.rootPartArm.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rootArm#rotTime"), 2)*1000;
			self.rootPartArm.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rootArm#touchRotLimit"), 10));
			self.rootPartArm.locked = false;
		end;

-- ROOTPARTARM END --
-- CONTAINERATTACHERTURN START --

	local containerAttacher = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.containerAttacher#index"));
		if containerAttacher ~= nil then
		self.containerAttacherPart = {};
		self.containerAttacherPart.node = containerAttacher;

		local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.containerAttacherArm#minRot"));
		self.containerAttacherPart.minRot = {};
		self.containerAttacherPart.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
		self.containerAttacherPart.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
		self.containerAttacherPart.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.containerAttacher#maxRot"));
		self.containerAttacherPart.maxRot = {};
		self.containerAttacherPart.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
		self.containerAttacherPart.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
		self.containerAttacherPart.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

		self.containerAttacherPart.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.containerAttacher#rotTime"), 2) *1000;
		self.containerAttacherPart.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.containerAttacher#touchRotLimit"), 10));
		self.containerAttacherPartturn = false;
	end;
  
-- CONTAINERATTACHERTURN END --
-- MAINPARTARM START --
		
	local mainPart = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.mainArm#index"));
		if mainPart ~= nil then 
			self.mainPartArm = {};
			self.mainPartArm.node = mainPart;
			
			local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.mainArm#minRot"));
			self.mainPartArm.minRot = {};
			self.mainPartArm.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
			self.mainPartArm.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
			self.mainPartArm.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
			
			x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.mainArm#maxRot"));
			self.mainPartArm.maxRot = {};
			self.mainPartArm.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
			self.mainPartArm.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
			self.mainPartArm.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
			
			self.mainPartArm.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.mainArm#rotTime"), 2)*1000;
			self.mainPartArm.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.mainArm#touchRotLimit"), 10));
			self.mainPartArm.hydraulicPoint = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.mainArm#hydraulicPoint"));
		end;

-- MAINPARTARM END --
-- WORKINGPARTARM START --
		
	local workingPart = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.workingArm#index"));
		if workingPart ~= nil then 
			self.workingPartArm = {};
			self.workingPartArm.node = workingPart;
			
			local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.workingArm#minTrans"));
			self.workingPartArm.minTrans = {};
			self.workingPartArm.minTrans[1] = Utils.getNoNil(x, 0);
			self.workingPartArm.minTrans[2] = Utils.getNoNil(y, 0);
			self.workingPartArm.minTrans[3] = Utils.getNoNil(z, 0);
			
			x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.workingArm#maxTrans"));
			self.workingPartArm.maxTrans = {};
			self.workingPartArm.maxTrans[1] = Utils.getNoNil(x, 0);
			self.workingPartArm.maxTrans[2] = Utils.getNoNil(y, 0);
			self.workingPartArm.maxTrans[3] = Utils.getNoNil(z, 0);
			
			self.workingPartArm.transTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.workingArm#moveTime"), 2)*1000;
			self.workingPartArm.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.workingArm#touchTransLimit"), 10));
		end;

-- WORKINGPARTARM END --
-- OBJECTLOCK START --
		
	local objectPart = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.objectLock#index"));
		if objectPart ~= nil then 
			self.objectPartArm = {};
			self.objectPartArm.node = objectPart;
			
			local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.objectLock#minRot"));
			self.objectPartArm.minRot = {};
			self.objectPartArm.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
			self.objectPartArm.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
			self.objectPartArm.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
			     
			x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.objectLock#maxRot"));
			self.objectPartArm.maxRot = {};
			self.objectPartArm.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
			self.objectPartArm.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
			self.objectPartArm.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
			
			self.objectPartArm.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.objectLock#rotTime"), 2)*1000;
			self.objectPartArm.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.objectLock#touchRotLimit"), 10));
		end;

-- OBJECTLOCK END --

-- HYDRAULIC START --

	self.hydraulic = {};
	self.hydraulic.node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.hydraulic#indexHydraulic"));
	self.hydraulic.punch = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.hydraulic#indexPunch"));
	self.hydraulic.translationPunch = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.hydraulic#translationPunch"));
	local ax, ay, az = getWorldTranslation(self.hydraulic.punch);
    local bx, by, bz = getWorldTranslation(self.hydraulic.translationPunch);
    self.hydraulic.punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
    
-- HYDRAULIC END --

-- MOVESTICK START --

	local moveStick1Node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.moveStick#index1"));
	local moveStick2Node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.moveStick#index2"));
	local moveStick3Node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.moveStick#index3"));
	local moveStick4Node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.moveStick#index4"));
	if moveStick1Node ~= nil and moveStick2Node ~= nil and moveStick3Node ~= nil and moveStick4Node ~= nil then
		self.moveStick = {};
		self.moveStick1 = {};
		self.moveStick1.node = moveStick1Node;
		self.moveStick2 = {};
		self.moveStick2.node = moveStick2Node;
		self.moveStick3 = {};
		self.moveStick3.node = moveStick3Node;
		self.moveStick4 = {};
		self.moveStick4.node = moveStick4Node;
		
		local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.moveStick#minRot"));
		self.moveStick.minRot = {};
		self.moveStick.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
		self.moveStick.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
		self.moveStick.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		
		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.moveStick#maxRotu"));
		self.moveStick.maxRotUp = {};
		self.moveStick.maxRotUp[1] = Utils.degToRad(Utils.getNoNil(x, 0));
		self.moveStick.maxRotUp[2] = Utils.degToRad(Utils.getNoNil(y, 0));
		self.moveStick.maxRotUp[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		
		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.moveStick#maxRotd"));
		self.moveStick.maxRotDown = {};
		self.moveStick.maxRotDown[1] = Utils.degToRad(Utils.getNoNil(x, 0));
		self.moveStick.maxRotDown[2] = Utils.degToRad(Utils.getNoNil(y, 0));
		self.moveStick.maxRotDown[3] = Utils.degToRad(Utils.getNoNil(z, 0));

		self.moveStick1.isup = false;
		self.moveStick1.iscenter = true;
		self.moveStick1.isdown = false;
		self.moveStick2.isup = false;
		self.moveStick2.iscenter = true;
		self.moveStick2.isdown = false;
		self.moveStick3.isup = false;
		self.moveStick3.iscenter = true;
		self.moveStick3.isdown = false;
		self.moveStick4.isup = false;
		self.moveStick4.iscenter = true;
		self.moveStick4.isdown = false;

	end;
	
	self.move = {};
	self.move.waituntillup = false;
	self.move.waituntilldown = false;
	self.move.waituntillmup = false;
	self.move.waituntillmdown = false;	
	self.move.waituntillretracted = false;
	self.move.waituntillextracted = false;
	self.move.stickcenter2up = false;
	self.move.stickcenter2down = false;
	self.move.stick2 = false;
	self.move.stick2center2up = false;
	self.move.stick2center2down = false;
	self.move.stick3 = false;
	self.move.stick3center2up = false;
	self.move.stick3center2down = false;
	self.move.stickcheck = false;
	self.move.type = 0;

-- FROM FASTCOUPLER --
	local objectAttacher = {};
	local jointTypeStr = getXMLString(xmlFile,"vehicle.attacherJoints.attacherJoint#jointType");
	objectAttacher.joint = getXMLString(xmlFile,"vehicle.attacherJoints.attacherJoint#index");
	objectAttacher.index = 0;
	self.object = objectAttacher;
	if jointTypeStr ~= nil then
		local jointType = Vehicle.jointTypeNameToInt[jointTypeStr];

		if jointType == nil then
      		Vehicle.registerJointType(jointTypeStr);
			print("register Jointtype: " .. jointTypeStr);
			jointType = Vehicle.jointTypeNameToInt[jointTypeStr];
		end;

		if jointType ~= nil then
			self.attacherJoints[1].jointType = jointType;
		end;
	end;

	self.attacherVehicleCopy = nil;

 	self.maxRotLimit = Utils.degToRad(Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.rotationMax#xRot"),0));
	self.changingAngle = Utils.degToRad(-64.215);
	self.nullAngle = Utils.degToRad(-60);
    
	self.connectCollisions = SpecializationUtil.callSpecializationsFunction("connectCollisions");
	self.anim = SpecializationUtil.callSpecializationsFunction("anim");
  	self.charId = {};
	self.clipIndex = {};
	self.Go = {};
	self.Done = {};
	self.CheckDone = {};
	self.collisionArm = {};
	self.moveColli = {};
	local count = getXMLInt(xmlFile, "vehicle.animParts#count");
    self.animParts = {}
	local part = self.animParts;
    for i=1, count do
		part[i] = {};
        local partname = string.format("vehicle.animParts.part".."%d", i);
	    local nameR = getXMLString(xmlFile, partname.."#name");
		self.charId[nameR] = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, partname.."#rootNode"));
		self.clipIndex[nameR] = getXMLString(xmlFile, partname.."#animationClip");
		self.CheckDone[nameR] = false;

		self.moveColli[nameR] = getXMLString(xmlFile, partname.."#moveColli");
		if self.moveColli[nameR] ~= nil then
			local Collision = {};
			Collision.collision = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, partname.."#collision"));
			Collision.collisionAttacher = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, partname.."#collsionAttacher"));
			Collision.armAttacher = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, partname.. "#armAttacher"));
			Collision.index = 0;
			self.collisionArm[nameR] = Collision;
			self:connectCollisions(nameR);
		end;
	end;
	
	local hydraulicmSound = getXMLString(xmlFile, "vehicle.hydraulicSound#file");
		if hydraulicmSound ~= nil and hydraulicmSound ~= "" then
			hydraulicmSound = Utils.getFilename(hydraulicmSound, self.baseDirectory);
			self.hydraulicmSound = createSample("hydraulicSound");
			loadSample(self.hydraulicmSound, hydraulicmSound, false);
			self.hydraulicmPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hydraulicSound#pitchOffset"), 0);
			self.hydraulicmSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hydraulic#volume"), 1.0);
			self.hydraulicmSoundEnabled = false;
		end;
    
	self.hudInfoBasePosXh = 0.73;
    self.hudInfoBaseWidthh = 0.35;
    self.hudInfoBasePosYh = 0.2775;
    self.hudInfoBaseHeighth = 0.58;
    self.infoPanelPathh = Utils.getFilename("Textur/HakenliftInfo.png", self.baseDirectory);
	self.hudInfoBaseOverlayh = Overlay:new("hudInfoBaseOverlay", self.infoPanelPathh, self.hudInfoBasePosXh, self.hudInfoBasePosYh, self.hudInfoBaseWidthh, self.hudInfoBaseHeighth);
    self.showHudInfoBaseh = false;
		
end;

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


function FlieglHakenLift:update(dt)

	if self:getIsActiveForInput() then
    	if (not self.workingPartArm.locked or self.rootPartArm.locked) and not self.lockedbycontainer then
			if InputBinding.hasEvent(InputBinding.LOWER_ARM_TRUCK) then
				local x, y, z = getRotation(self.moveStick2.node)
				local x1, y1, z1 = getRotation(self.moveStick3.node)
				if z > self.moveStick.minRot[3] then
					self.moveStick2.isup = true;
					self.moveStick2.iscenter = false;
					self.moveStick2.isdown = false;
				elseif z < self.moveStick.minRot[3] then
					self.moveStick2.isup = false;
					self.moveStick2.iscenter = false;
					self.moveStick2.isdown = true;
				elseif z == self.moveStick.minRot[3] then
					self.moveStick2.isup = false;
					self.moveStick2.iscenter = true;
					self.moveStick2.isdown = false;
				end;
				if z1 > self.moveStick.minRot[3] then
					self.moveStick3.isup = true;
					self.moveStick3.iscenter = false;
					self.moveStick3.isdown = false;
				elseif z1 < self.moveStick.minRot[3] then
					self.moveStick3.isup = false;
					self.moveStick3.iscenter = false;
					self.moveStick3.isdown = true;
				elseif z1 == self.moveStick.minRot[3] then
					self.moveStick3.isup = false;
					self.moveStick3.iscenter = true;
					self.moveStick3.isdown = false;
				end;
				if not self.workingPartArmmove and self.workingPartArm.extended and not self.workingPartArm.retracted and self.mainPartArm.down and not self.mainPartArm.lifted then
					if self.moveStick2.iscenter then
						self.Go.arm2u = not self.Go.arm2u;
						self.Done.arm2u = true;
					end;
					self.move.waituntillextended = false;
					self.move.waituntillretracted = true;
					self.move.waituntillmup = true;
					self.move.waituntillmdown = false;
					self.move.type = 1;
				elseif self.workingPartArmmove and not self.workingPartArm.extended and not self.workingPartArm.retracted and self.mainPartArm.down and not self.mainPartArm.lifted then
					if self.moveStick2.isup then
						self.Go.arm2u = not self.Go.arm2u;
						self.Done.arm2u = true;
					end;
					self.move.waituntillextended = true;
					self.move.waituntillretracted = false;
					self.move.waituntillmup = false;
					self.move.waituntillmdown = false;					
					self.move.type = 2;
					self.move.stick2 = true;
				elseif self.workingPartArmmove and not self.workingPartArm.extended and self.workingPartArm.retracted and not self.mainPartArm.down and not self.mainPartArm.lifted then					
					if self.moveStick3.isup then
						self.Go.arm3u = not self.Go.arm3u;
						self.Done.arm3u = true;
					end;
					self.move.waituntillextended = true;
					self.move.waituntillretracted = false;
					self.move.waituntillmup = false;
					self.move.waituntillmdown = true;
					self.move.type = 3;
					self.move.stick3 = true;
				elseif self.workingPartArmmove and not self.workingPartArm.extended and self.workingPartArm.retracted and not self.mainPartArm.down and self.mainPartArm.lifted then
					if self.moveStick3.iscenter then
						self.Go.arm3d = not self.Go.arm3d;
						self.Done.arm3d = true;
					end;
					self.move.waituntillextended = true;
					self.move.waituntillretracted = false;
					self.move.waituntillmup = false;
					self.move.waituntillmdown = true;					
					self.move.type = 4;
				elseif not self.workingPartArmmove and not self.workingPartArm.extended and self.workingPartArm.retracted and not self.mainPartArm.down and not self.mainPartArm.lifted then
					if self.moveStick3.isdown then
						self.Go.arm3d = not self.Go.arm3d;
						self.Done.arm3d = true;
					end;
					self.move.waituntillextended = false;
					self.move.waituntillretracted = false;
					self.move.waituntillmup = true;
					self.move.waituntillmdown = false;					
					self.move.type = 5;
					self.move.stick3 = true;
				elseif not self.workingPartArmmove and not self.workingPartArm.extended and not self.workingPartArm.retracted and self.mainPartArm.down and not self.mainPartArm.lifted then
					if self.moveStick2.isdown then
						self.Go.arm2d = not self.Go.arm2d;
						self.Done.arm2d = true;
					end;
					self.move.waituntillextended = false;
					self.move.waituntillretracted = true;
					self.move.waituntillmup = true;
					self.move.waituntillmdown = false;					
					self.move.type = 6;
					self.move.stick2 = true;
				end;
								
				
		    	self.mainPartArmturn = not self.mainPartArmturn;
    			self.workingPartArmmove = not self.workingPartArmmove;
	    		self.containerAttacherPartturn = not self.containerAttacherPartturn;
				self.move.stickcheck = true;	    		
			end;
		end;
		
		if not self.rootPartArm.locked and not self.lockedbycontainer then
			if InputBinding.hasEvent(InputBinding.LIFT_ARM_TRUCK) then
            	local x, y, z = getRotation(self.moveStick1.node);
            	if z > self.moveStick.minRot[3] and not self.rootPartArm.down and not self.rootPartArm.retracted then
            		self.moveStick1.isup = true;
            		self.moveStick1.isdown = false;
            		self.moveStick1.iscenter = false;
            		self.Go.arm1u = not self.Go.arm1u;
            		self.Done.arm1u = true;
            		self.move.waitstickup2center = true;
            		self.move.waitstickdown2center = false;
            	elseif z < self.moveStick.minRot[3] and not self.rootPartArm.down and not self.rootPartArm.lifted then
            		self.moveStick1.isdown = true;
            		self.moveStick1.isup = false;
            		self.moveStick1.iscenter = false;
            		self.Go.arm1d = not self.Go.arm1d;
            		self.Done.arm1d = true;
            		self.move.waitstickup2center = false;
            		self.move.waitstickdown2center = true;
            	elseif z == self.moveStick.minRot[3] and (self.rootPartArm.down or self.rootPartArm.lifted) then
            		self.moveStick1.iscenter = true;
            		self.moveStick1.isup = false;
            		self.moveStick1.isdown = false;
            		if not self.rootPartArmturn then
            			self.Go.arm1u = not self.Go.arm1u;
            			self.Done.arm1u = true;
            			self.move.waituntillup = true;
            			self.move.waituntilldown = false;
            		elseif self.rootPartArmturn then
						self.Go.arm1d = not self.Go.arm1d;
            			self.Done.arm1d = true;
            			self.move.waituntillup = false;
            			self.move.waituntilldown = true;
            		end;
            		self.move.waitstickup2center = false;
            		self.move.waitstickdown2center = false;
            	end;
            	self.rootPartArmturn = not self.rootPartArmturn;
			end;
		end;
	end;

	if (not self.rootPartArm.down and not self.rootPartArm.lifted) or (not self.mainPartArm.down and not self.mainPartArm.lifted) or (not self.workingPartArm.extended and not self.workingPartArm.retracted) then
		if self.hydraulicmSound ~= nil and not self.hydraulicmSoundEnabled then
			if self:getIsActiveForSound() then
   				setSamplePitch(self.hydraulicmSound, self.hydraulicmSoundPitchOffset);
				playSample(self.hydraulicmSound, 0, self.hydraulicmSoundVolume, 0);
				self.hydraulicmSoundEnabled = true;
			end;
		end;
	else
		stopSample(self.hydraulicmSound);
		self.hydraulicmSoundEnabled = false;
	end;

	if self.attachedImplements[1] ~= nil then
   	    self.objectPartArmturn = true;
	else
       	self.objectPartArmturn = false;
 	end;
	
	-- Lock Container --
		local x, y, z = getRotation(self.objectPartArm.node);
    	local rot = {x,y,z};
	    local newRot = Utils.getMovedLimitedValues(rot, self.objectPartArm.maxRot, self.objectPartArm.minRot, 3, self.objectPartArm.rotTime, dt, not self.objectPartArmturn);
	    setRotation(self.objectPartArm.node, unpack(newRot));

	if not self.mainPartArm.locked then 
    	if self.mainPartArm ~=nil then
		    local x, y, z = getRotation(self.mainPartArm.node);
		    if x < self.mainPartArm.minRot[1] then
		    	self.workingPartArm.locked = true;
		    	self.workingPartArm.down = true;
		    else
		    	self.workingPartArm.locked = false;
		    	self.workingPartArm.down = false;
		    end;
		    if x > self.mainPartArm.maxRot[1] then
				self.workingPartArm.lifted = true;
			else
				self.workingPartArm.lifted = false;
			end;
		    self.currentAngle = x;
		    local rot = {x,y,z};
	    	local newRot = Utils.getMovedLimitedValues(rot, self.mainPartArm.maxRot, self.mainPartArm.minRot, 3, self.mainPartArm.rotTime, dt, not self.mainPartArmturn);
		    setRotation(self.mainPartArm.node, unpack(newRot));
		end;
	end;
  	
	if not self.rootPartArm.locked then
		if self.rootPartArm ~=nil then
			local x, y, z = getRotation(self.rootPartArm.node);
			if x < self.rootPartArm.minRot[1] then
				self.workingPartArm.locked = true;
			else 
				self.workingPartArm.locked = false;
			end;
	    	local rot = {x,y,z};
		    local newRot = Utils.getMovedLimitedValues(rot, self.rootPartArm.maxRot, self.rootPartArm.minRot, 3, self.rootPartArm.rotTime, dt, not self.rootPartArmturn);
	    	setRotation(self.rootPartArm.node, unpack(newRot));
		end;   
	end;
	
	if not self.workingPartArm.locked then
		if self.workingPartArm ~= nil then
			local x, y, z = getTranslation(self.workingPartArm.node);
			if z > self.workingPartArm.maxTrans[3] then
				self.mainPartArm.locked = true;
			else 
				self.mainPartArm.locked = false;
			end;
			if z < self.workingPartArm.minTrans[3] then
				self.rootPartArm.locked = true;
			else
				self.rootPartArm.locked = false;
			end;
			local trans = {x,y,z};
			local newTrans = Utils.getMovedLimitedValues(trans, self.workingPartArm.maxTrans, self.workingPartArm.minTrans, 3, self.workingPartArm.transTime, dt, not self.workingPartArmmove);
			setTranslation(self.workingPartArm.node, unpack(newTrans));
		end;
	end;

	if self.hydraulic ~= nil and self.mainPartArm ~= nil then
		local ax, ay, az = getWorldTranslation(self.hydraulic.node);
		local bx, by, bz = getWorldTranslation(self.mainPartArm.hydraulicPoint);
		local x, y, z = worldDirectionToLocal(getParent(self.hydraulic.node), bx-ax, by-ay, bz-az);
		setDirection(self.hydraulic.node, x*-1, y*-1, z*-1, 0, 1, 0);
		if self.hydraulic.punch ~= nil then
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(self.hydraulic.punch, 0, 0, (distance-self.hydraulic.punchDistance)*-1);
		end;
	end;
	
	if self.object ~= nil then
		local localObject = self.object;
		localObject.index = self.attacherJoints[1].jointIndex;
		if self.mainPartArm.locked then
			setJointRotationLimit(localObject.index, 0, true, Utils.degToRad(0), Utils.degToRad(0));
			setJointRotationLimit(localObject.index, 1, true, Utils.degToRad(0), Utils.degToRad(0));
			setJointRotationLimit(localObject.index, 2, true, Utils.degToRad(0), Utils.degToRad(0));
		else
			-- This calculates current joint angleRegulation
			local x, y, z = getRotation(self.mainPartArm.node);
			self.valuefromx = x;
			self.valuefromy = y;
			self.valuefromz = z;
			local angleRelation = ((x / self.changingAngle) * self.maxRotLimit);
			local ax, ay, az = getRotation(self.containerAttacherPart.node);
			setRotation(self.containerAttacherPart.node, ax, ay, angleRelation);

			if x < self.changingAngle then
				-- This calculates the current rotationlimit depending on the current mainArm rotation
				local angle = (x - self.changingAngle)/(self.mainPartArm.maxRot[1] - self.changingAngle)*Utils.degToRad(50);
				setJointRotationLimit(localObject.index, 0, true, Utils.degToRad(-179), Utils.degToRad(179));
				setJointRotationLimit(localObject.index, 1, true, angle*-1, angle);
				setJointRotationLimit(localObject.index, 2, true, Utils.degToRad(-179), Utils.degToRad(80));
			elseif x >= self.changingAngle and x < self.nullAngle then
				-- This calculates the current rotationlimit depending on the current mainArm rotation (required for a floating loading action)
				local angle = (x - self.nullAngle)/(self.changingAngle - self.nullAngle)*Utils.degToRad(5);
				setJointRotationLimit(localObject.index, 2, true, Utils.degToRad(0), angle);					
			else
				setJointRotationLimit(localObject.index, 2, true, Utils.degToRad(0), Utils.degToRad(0));
				setJointRotationLimit(localObject.index, 0, true, Utils.degToRad(0), Utils.degToRad(0));
				setJointRotationLimit(localObject.index, 1, true, Utils.degToRad(0), Utils.degToRad(0)); --neu
			end;			
		end;
		setJointFrame(localObject.index, 0, localObject.joint);
	end;

-- CHECK FINAL POSITION OF ARMS --

	-- ROOTPARTARM --
	local x, y, z = getRotation(self.rootPartArm.node);
	if x == self.rootPartArm.minRot[1] then
		self.rootPartArm.down = true;
	else
		self.rootPartArm.down = false;
	end;
	if x < self.rootPartArm.maxRot[1] + 0.01 then
		self.rootPartArm.lifted = true;
	else
		self.rootPartArm.lifted = false;
	end;
	
	-- MAINPARTARM --
	local x, y, z = getRotation(self.mainPartArm.node);
	if x == self.mainPartArm.minRot[1] then
		self.mainPartArm.down = true;
	else
		self.mainPartArm.down = false;
	end;
	if x < self.mainPartArm.maxRot[1] + 0.001 then
		self.mainPartArm.lifted = true;
	else
		self.mainPartArm.lifted = false;
	end;
	
	-- WORKINGPARTARM --
	local x, y, z = getTranslation(self.workingPartArm.node);
	if z > self.workingPartArm.minTrans[3] -0.001 then
		self.workingPartArm.extended = true;
	else
		self.workingPartArm.extended = false;
	end;
	if z == self.workingPartArm.maxTrans[3] then
		self.workingPartArm.retracted = true;
	else
		self.workingPartArm.retracted = false;
	end;

-- MOVE STICKS --

	if self.move.waitstickup2center then
		local x, y, z = getRotation(self.moveStick1.node);
		if z == self.moveStick.minRot[3] then
			self.move.waitstickup2center = false;
			self.Go.arm1d = not self.Go.arm1d
			self.Done.arm1d = true;
			self.move.waituntillup = false;
			self.move.waituntilldown = true;
		end;
	end;
	
	if self.move.waitstickdown2center then
		local x, y, z = getRotation(self.moveStick1.node);
		if z == self.moveStick.minRot[3] then
			self.move.waitstickdown2center = false;
			self.Go.arm1u = not self.Go.arm1u
			self.Done.arm1u = true;
			self.move.waituntillup = true;
			self.move.waituntilldown = false;
		end;
	end;	

	if (self.move.waituntillup and self.rootPartArm.lifted and not self.move.waitstickup2center) or self.move.stickcenter2up then
		self.Go.arm1u = not self.Go.arm1u;
		self.Done.arm1u = true;
		self.move.waituntillup = false;
		self.move.stickcenter2up = false;
	end;
	if (self.move.waituntilldown and self.rootPartArm.down and not self.move.waitstickdown2center) or self.movestickcenter2down then
		self.Go.arm1d = not self.Go.arm1d;
		self.Done.arm1d = true;
		self.move.waituntilldown = false;
		self.move.stickcenter2down = false;
	end;

-- STICK 2 UND 3 --

	if self.move.type == 1 and (self.move.waituntillretracted or self.move.waituntillmup) then
		if self.workingPartArm.retracted and self.move.waituntillretracted then
			self.Go.arm2u = not self.Go.arm2u;
			self.Done.arm2u = true;
			self.Go.arm3u = not self.Go.arm3u;
			self.Done.arm3u = true;
			self.move.waituntillretracted = false;
		end;
		if self.mainPartArm.lifted and self.move.waituntillmup then
			self.Go.arm3u = not self.Go.arm3u;
			self.Done.arm3u = true;
			self.move.waituntillmup = false;
		end;
	end;
	if self.move.type == 2 and self.move.waituntillextended then
		local x, y, z = getRotation(self.moveStick2.node);
		if z == self.moveStick.minRot[3] then
			self.Go.arm2d = not self.Go.arm2d;
			self.Done.arm2d = true;
		end;
		if self.workingPartArm.extended and self.move.waituntillextended then
			self.Go.arm2d = not self.Go.arm2d;
			self.Done.arm2d = true;
			self.move.waituntillextended = false;
		end;
	end;
	if self.move.type == 3 and (self.move.waituntillextended or self.move.waituntillmdown) then
		local x, y, z = getRotation(self.moveStick3.node);
		if z == self.moveStick.minRot[3] and self.move.stick3 then
			self.Go.arm3d = not self.Go.arm3d;
			self.Done.arm3d = true;
			self.move.stick3 = false;
		end;
		if self.mainPartArm.down and self.move.waituntillmdown then
			self.Go.arm3d = not self.Go.arm3d;
			self.Done.arm3d = true;
			self.Go.arm2d = not self.Go.arm2d;
			self.Done.arm2d = true;
			self.move.waituntillmdown = false;
		end;
		if self.workingPartArm.extended and self.move.waituntillextended then
			self.Go.arm2d = not self.Go.arm2d;
			self.Done.arm2d = true;
			self.move.waituntillextended = false;
		end;
	end;
	if self.move.type == 4 and (self.move.waituntillextended or self.move.waituntillmdown) then
		if self.mainPartArm.down and self.move.waituntillmdown then
			self.Go.arm3d = not self.Go.arm3d;
			self.Done.arm3d = true;
			self.Go.arm2d = not self.Go.arm2d;
			self.Done.arm2d = true;
			self.move.waituntillmdown = false;
		end;
		if self.workingPartArm.extended and self.move.waituntillextended then
			self.Go.arm2d = not self.Go.arm2d;
			self.Done.arm2d = true;
			self.move.waituntillextended = false;
		end;
	end;
	if self.move.type == 5 and self.move.waituntillmup then
		local x, y, z = getRotation(self.moveStick3.node);
		if z == self.moveStick.minRot[3] and self.move.stick3 then
			self.Go.arm3u = not self.Go.arm3u;
			self.Done.arm3u = true;
			self.move.stick3 = false;
		end;
		if self.mainPartArm.lifted and self.move.waituntillmup then
			self.Go.arm3u = not self.Go.arm3u;
			self.Done.arm3u = true;
			self.move.waituntillmup = false;
		end;
	end;
	if self.move.type == 6 and (self.move.waituntillretracted or self.move.waituntillmup) then
		local x, y, z = getRotation(self.moveStick2.node);
		if z == self.moveStick.minRot[3] and self.move.stick2 then
			self.Go.arm2u = not self.Go.arm2u;
			self.Done.arm2u = true;
			self.move.stick2 = false;
		end;
		if self.workingPartArm.retracted and self.move.waituntillretracted then
			self.Go.arm2u = not self.Go.arm2u;
			self.Done.arm2u = true;
			self.Go.arm3u = not self.Go.arm3u;
			self.Done.arm3u = true;
			self.move.waituntillretracted = false;
		end;
		if self.mainPartArm.lifted and self.move.waituntillmup then
			self.Go.arm3u = not self.Go.arm3u;
			self.Done.arm3u = true;
			self.move.waituntillmup = false;
		end;
	end;

-- PLAY ANIMATIONS --

	if self.Go.pillar ~= nil and self.Done.pillar ~= false then
		self:anim("pillar", false);
	end;
	if self.Go.arm1u ~= nil and self.Done.arm1u ~= false then
		self:anim("arm1u", false);
	end;
	if self.Go.arm1d ~= nil and self.Done.arm1d ~= false then
		self:anim("arm1d", false);
	end;
	if self.Go.arm2u ~= nil and self.Done.arm2u ~= false then
		self:anim("arm2u", false);
	end;
	if self.Go.arm2d ~= nil and self.Done.arm2d ~= false then
		self:anim("arm2d", false);
	end;
	if self.Go.arm3u ~= nil and self.Done.arm3u ~= false then
		self:anim("arm3u", false);
	end;
	if self.Go.arm3d ~= nil and self.Done.arm3d ~= false then
		self:anim("arm3d", false);
	end;
	if self.Go.arm4u ~= nil and self.Done.arm4u ~= false then
		self:anim("arm4u", false);
	end;
	if self.Go.arm4d ~= nil and self.Done.arm4d ~= false then
		self:anim("arm4d", false);
	end;

   	if self.attachedImplements[1] ~= nil then
		if self.attachedImplements[1].object.lockable ~= nil then
			if self.attachedImplements[1].object.lockable then
				self.lockedbycontainer = true;
			else
				self.lockedbycontainer = false;
			end;
		end;
	else
		self.lockedbycontainer = false;
	end;
		
end;

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

function FlieglHakenLift:draw()
	
	if InputBinding.hasEvent(InputBinding.SHOWHKLHUD) then
		self.showHudInfoBaseh = not self.showHudInfoBaseh;
	end;

	if self.showHudInfoBaseh then
		if InputBinding.getButtonKeyName(InputBinding.LOWER_ARM_TRUCK) == "Z" then
			self.lowerArmreplacey = "Y";
		elseif InputBinding.getButtonKeyName(InputBinding.LOWER_ARM_TRUCK) == 'Y' then
			self.lowerArmreplacey = "Z";
		else 
			self.lowerArmreplacey = InputBinding.getButtonKeyName(InputBinding.LOWER_ARM_TRUCK);
		end;
		if InputBinding.getButtonKeyName(InputBinding.LIFT_ARM_TRUCK) == "Z" then
			self.liftArmreplacey = "Y";
		elseif InputBinding.getButtonKeyName(InputBinding.LIFT_ARM_TRUCK) == 'Y' then
			self.liftArmreplacey = "Z";
		else 
			self.liftArmreplacey = InputBinding.getButtonKeyName(InputBinding.LIFT_ARM_TRUCK);
		end;
		if not self.lockedbycontainer then
			self.hudInfoBaseOverlayh:render();
			if not self.rootPartArm.locked and not self.workingPartArm.locked and self.workingPartArm.extended then
				renderText(0.88, 0.58, 0.02, string.format("%s\n%s", g_i18n:getText("TurnHKLArmback"), self.lowerArmreplacey));
				renderText(0.88, 0.54, 0.02, string.format("%s\n%s", g_i18n:getText("LiftHKLArm"), self.liftArmreplacey));
			elseif self.rootPartArm.locked and self.workingPartArm.locked and self.mainPartArm.lifted then
				renderText(0.88, 0.58, 0.02, string.format("%s\n%s", g_i18n:getText("TurnHKLArmforward"), self.lowerArmreplacey));
				renderText(0.88, 0.54, 0.02, string.format("-"));
			elseif not self.rootPartArm.locked and self.workingPartArm.locked and self.rootPartArm.lifted then
				renderText(0.88, 0.58, 0.02, string.format("-"));
				renderText(0.88, 0.54, 0.02, string.format("%s\n%s", g_i18n:getText("LowerHKLArm"), self.liftArmreplacey));
			else
				renderText(0.88, 0.56, 0.02, string.format("..."));
			end;
		end;
		renderText(0.81, 0.23, 0.02, string.format("%s - %s", g_i18n:getText("hideInfo"), InputBinding.getButtonKeyName(InputBinding.SHOWHKLHUD)));
	else
		renderText(0.81, 0.23, 0.02, string.format("%s - %s", g_i18n:getText("displayInfo"), InputBinding.getButtonKeyName(InputBinding.SHOWHKLHUD)));
	end;	
end;

function FlieglHakenLift:delete()

	if self.hydraulicmSound ~= nil then
        delete(self.hydraulicmSound);
    end;
    
	if self.hudInfoBaseOverlayh ~= nil then
		self.hudInfoBaseOverlayh:delete();
	end;    
end;

function FlieglHakenLift:onAttach(attacherVehicle)

	self.Go.pillar = not self.Go.pillar;
	self.Done.pillar = true;

end;

function FlieglHakenLift:onDetach()

	self.Go.pillar = not self.Go.pillar;
	self.Done.pillar = true;
	
end;

function FlieglHakenLift:getCorrectKey(key)
	if key < 256 then
		return string.upper(string.char(key));
	elseif key > 255 and key < 266 then
		return string.upper("KP"..string.char(key-208));
	else
		return "n/a";
	end;
end;

function FlieglHakenLift:validateAttacherJoint(container, jointDesc, dt)
    return true;
end;

function FlieglHakenLift:anim(varName, loopCheck)
	if self.moveColli[varName] ~= nil then
		local Collision = self.collisionArm[varName];
		setJointFrame(Collision.index, 0, Collision.armAttacher);
	end;

	if self.Go[varName] == true and self.Done[varName] ~= false then
		local charId = getAnimCharacterSet(self.charId[varName]);
		local clipIndex = getAnimClipIndex(charId, self.clipIndex[varName]);
		assignAnimTrackClip(charId , 0, clipIndex);
		setAnimTrackLoopState(charId, 0, loopCheck);
		setAnimTrackSpeedScale(charId, 0, 1);
		enableAnimTrack(charId, 0);
		if getAnimTrackTime(charId, 0) >= getAnimClipDuration(charId, clipIndex) and loopCheck == false then
			disableAnimTrack(charId, 0);
			self.Done[varName] = false;
			self.CheckDone[varName] = true;
		end;
	elseif self.Go[varName] == false and self.Done[varName] ~= false then
		local charId = getAnimCharacterSet(self.charId[varName]);
		local clipIndex = getAnimClipIndex(charId, self.clipIndex[varName]);
		if loopCheck == true then
			disableAnimTrack(charId, 0);
			self.Done[varName] = false;
		end;
		assignAnimTrackClip(charId , 0, clipIndex);
		setAnimTrackLoopState(charId, 0, loopCheck);
		setAnimTrackSpeedScale(charId, 0, -1);
		enableAnimTrack(charId, 0);
		if getAnimTrackTime(charId, 0) <= 0 then
			disableAnimTrack(charId, 0);
			self.Done[varName] = false;
			self.CheckDone[varName] = false;
		end;
	end;
end;

function FlieglHakenLift:connectCollisions(varName)
	local Collision = self.collisionArm[varName];
	local constr = JointConstructor:new();
	constr:setActors(self.rootNode, Collision.collision);
	constr:setJointTransforms(Collision.armAttacher, Collision.collisionAttacher);
	for i=1, 3 do
		constr:setRotationLimit(i-1, 0, 0, 0);
		constr:setTranslationLimit(i-1, true, 0, 0);
	end;
	Collision.index = constr:finalize();
end;