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

FlieglContainerCraneFW = {};

function FlieglContainerCraneFW.prerequisitesPresent(specializations)
	return SpecializationUtil.hasSpecialization(Attachable, specializations);
end;

function FlieglContainerCraneFW:load(xmlFile)

	self.armPos = {};

	self.workingArmMoving = 0;

	self.doTransportMove = false;
-- LEFT SUPPORT ARM START --

	local leftSupport = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.support1#index"));
		if leftSupport ~= nil then
			self.leftSupportArm = {};
			self.leftSupportArm.retracted = true;
			self.leftSupportArm.node = leftSupport;

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

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

			self.leftSupportArm.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.support1#rotTime"), 2)*1000;

			local x1, y1, z1 = getTranslation(self.leftSupportArm.node);
			self.leftSupportArm.minHeight = {};
			self.leftSupportArm.minHeight[1] = x1;
			self.leftSupportArm.minHeight[2] = y1;
			self.leftSupportArm.minHeight[3] = z1;

			x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.support1#maxTrans"));
			self.leftSupportArm.maxHeight = {};
			self.leftSupportArm.maxHeight[1] = x;
			self.leftSupportArm.maxHeight[2] = y1;
			self.leftSupportArm.maxHeight[3] = z1;
			
			self.leftSupportArm.transTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.support1#moveTime"), 2)*1000;

			self.leftSupportArm.feet = {};
			self.leftSupportArm.feet.node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.support1#feet"));

			x1, y1, z1 = getTranslation(self.leftSupportArm.feet.node);
			self.leftSupportArm.feet.minHeight = {};
			self.leftSupportArm.feet.minHeight[1] = x1;
			self.leftSupportArm.feet.minHeight[2] = y1;
			self.leftSupportArm.feet.minHeight[3] = z1;

			x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.support1#maxTransFeet"));
			self.leftSupportArm.feet.maxHeight = {};
			self.leftSupportArm.feet.maxHeight[1] = x1;
			self.leftSupportArm.feet.maxHeight[2] = Utils.getNoNil(y,0);
			self.leftSupportArm.feet.maxHeight[3] = z1;
			
			self.leftSupportArm.feet.transTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.support1#moveFeetTime"), 2)*1000;

		end;
		
--LEFT SUPPORT ARM END --

-- RIGHT SUPPORT ARM START --

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

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

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

		self.rightSupportArm.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.support2#rotTime"), 2)*1000;

		local x1, y1, z1 = getTranslation(self.rightSupportArm.node);
		self.rightSupportArm.minHeight = {};
		self.rightSupportArm.minHeight[1] = x1;
		self.rightSupportArm.minHeight[2] = y1;
		self.rightSupportArm.minHeight[3] = z1;

		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.support2#maxTrans"));
		self.rightSupportArm.maxHeight = {};
		self.rightSupportArm.maxHeight[1] = x;
		self.rightSupportArm.maxHeight[2] = y1;
		self.rightSupportArm.maxHeight[3] = z1;
		
		self.rightSupportArm.transTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.support2#moveTime"), 2)*1000;

		self.rightSupportArm.feet = {};
		self.rightSupportArm.feet.node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.support2#feet"));

		x1, y1, z1 = getTranslation(self.rightSupportArm.feet.node);
		self.rightSupportArm.feet.minHeight = {};
		self.rightSupportArm.feet.minHeight[1] = x1;
		self.rightSupportArm.feet.minHeight[2] = y1;
		self.rightSupportArm.feet.minHeight[3] = z1;

		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.support2#maxTransFeet"));
		self.rightSupportArm.feet.maxHeight = {};
		self.rightSupportArm.feet.maxHeight[1] = x1;
		self.rightSupportArm.feet.maxHeight[2] = Utils.getNoNil(y,0);
		self.rightSupportArm.feet.maxHeight[3] = z1;
		
		self.rightSupportArm.feet.transTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.support2#moveFeetTime"), 2)*1000;

	end;

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

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

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

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

		self.rootArm.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rootArm#rotTime"), 2)*1000;
		self.rootArm.zeroHomeSearch = false;
		self.rootArm.zeroMoveLeft = false;
		self.rootArm.zeroMoveRight = false;
	end;
	
	local mainArmNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.mainArm#index"));
	if mainArmNode ~= nil then
		self.mainArm = {};
		self.mainArm.node = mainArmNode;

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

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

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

		self.mainArm.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.mainArm#rotTime"), 2)*1000;
		self.mainArm.hydraulicPoint = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.mainArm#hydraulicPoint"));
		self.mainArm.zeroMoveDown = false;
		self.mainArm.zeroMoveUp = false;
		self.mainArm.zeroHomeSearch = false;
	end;
	
	local workingArm = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.workingArm#index"));
	if workingArm ~= nil then
		self.workingArm = {};
		self.workingArm.node = workingArm;

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

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

		self.workingArm.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.workingArm#rotTime"), 2)*1000;
		self.workingArm.fixPoint = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.workingArm#fixPoint"));
		self.workingArm.zeroMove = false;
	end;
	
	local extension1Arm = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.extension1#index"));
	if extension1Arm ~= nil then
		self.extension1Arm = {};
		self.extension1Arm.node = extension1Arm;

		local x1, y1, z1 = getTranslation(self.extension1Arm.node);
--		local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.extension1Arm#minTrans"));
		self.extension1Arm.minHeight = {};
		self.extension1Arm.minHeight[1] = x1;
		self.extension1Arm.minHeight[2] = y1;
		self.extension1Arm.minHeight[3] = z1;

		local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.extension1#maxTrans"));
		self.extension1Arm.maxHeight = {};
		self.extension1Arm.maxHeight[1] = x1;
		self.extension1Arm.maxHeight[2] = y1;
		self.extension1Arm.maxHeight[3] = Utils.degToRad(Utils.getNoNil(z, 0));

		self.extension1Arm.moveTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.extension1#moveTime"), 2)*1000;
		self.extension1Arm.zeroMove = false;
	end;
	
	local extension2Arm = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.extension2#index"));
	if extension2Arm ~= nil then
		self.extension2Arm = {};
		self.extension2Arm.node = extension2Arm;

		local x1, y1, z1 = getTranslation(self.extension2Arm.node);
		self.extension2Arm.minHeight = {};
		self.extension2Arm.minHeight[1] = x1;
		self.extension2Arm.minHeight[2] = y1;
		self.extension2Arm.minHeight[3] = z1;

		local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.extension2#maxTrans"));
		self.extension2Arm.maxHeight = {};
		self.extension2Arm.maxHeight[1] = x1;
		self.extension2Arm.maxHeight[2] = y1;
		self.extension2Arm.maxHeight[3] = Utils.degToRad(Utils.getNoNil(z, 0));

		self.extension2Arm.moveTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.extension2#moveTime"), 2)*1000;
	end;

	local transformer1Node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.transformer#index"));
    if transformer1Node ~= nil then
        self.transformer = {};
        self.transformer.node = transformer1Node;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.transformer#minRot"));
        self.transformer.minRot = {};
        self.transformer.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.transformer.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.transformer.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.transformer#maxRot"));
        self.transformer.maxRot = {};
        self.transformer.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.transformer.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.transformer.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
	    
		-- rotTime should be equal to workingArm rotTime for an floating action
		self.transformer.rotTime = self.workingArm.rotTime;
		
		-- Defines a fixpoint to align the hydraulic with this point
		self.transformer.fixPoint = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.transformer#fixPoint"));
		
		self.transformer.transform2 = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.transformer#index2"));
    end;
	
	local doorflNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.animParts.part3#rootNode"));
	local doorfrNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.animParts.part5#rootNode"));
	local doorblNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.animParts.part4#rootNode"));
	local doorbrNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.animParts.part6#rootNode"));
	local doorbNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.animParts.part7#rootNode"));
    if doorflNode ~= nil and doorfrNode ~= nil and doorblNode ~= nil and doorbrNode ~= nil and doorbNode ~= nil then
        self.door = {};
        self.door.front = {};
        self.door.back = {};
        self.door.flnode = doorflNode;
        self.door.frnode = doorfrNode;
        self.door.blnode = doorblNode;
        self.door.brnode = doorbrNode;
        self.door.bnode = doorbNode;

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

        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.doorLimits#maxRotf"));

        self.door.front.maxRot = {};
        self.door.front.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.door.front.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.door.front.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.doorLimits#maxRotb"));
        self.door.back.maxRot = {};
        self.door.back.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.door.back.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.door.back.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
        
        self.door.flup = true;
        self.door.frup = true;
        self.door.blup = true;
        self.door.brup = true;
        self.door.bup = true;
        
        self.door.fldown = true;
        self.door.frdown = true;
        self.door.bldown = true;
        self.door.brdown = true;
        self.door.bdown = true;

        self.door.closeall = false;
		self.door.openall = false;
		self.door.docheck = false;
        
	end;
	
	-- Defines attributes of hydraulic
	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);
	
	-- Defines attributes of mainarm - hydraulic
	self.hydraulicMainArm = {};
	self.hydraulicMainArm.node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.hydraulicMainArm#indexHydraulic"));
	self.hydraulicMainArm.punch = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.hydraulicMainArm#indexPunch"));
	self.hydraulicMainArm.translationPunch = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.hydraulicMainArm#translationPunch"));
	local ax, ay, az = getWorldTranslation(self.hydraulicMainArm.punch);
    local bx, by, bz = getWorldTranslation(self.hydraulicMainArm.translationPunch);
    self.hydraulicMainArm.punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);

	self.attacherVehicleCopy = nil;
	self.moveSupportArms = false;
	self.leftSupportArm.locked = false;
	self.rightSupportArm.locked = false;
	self.leftSupportArm.Tlocked = false;
	self.rightSupportArm.Tlocked = false;
	self.leftSupportArm.feet.locked = false;
	self.rightSupportArm.feet.locked = false;
	
	local jointTypeStr = getXMLString(xmlFile,"vehicle.attacherJoints.attacherJoint#jointType");
	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.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 = {}
    self.animParts.num = count;
	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 CraneSound = getXMLString(xmlFile, "vehicle.hydraulicSound#file");
		if CraneSound ~= nil and CraneSound ~= "" then
			CraneSound = Utils.getFilename(CraneSound, self.baseDirectory);
			self.CraneSound = createSample("CraneSound");
			loadSample(self.CraneSound, CraneSound, false);
			self.CranePitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hydraulicSound#pitchOffset"), 0);
			self.CraneSoundVolume = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hydraulic#volume"), 1.0);
			self.CraneSoundEnabled = false;
		end;
	
    self.hudInfoBasePosX = 0.73;
    self.hudInfoBaseWidth = 0.35;
    self.hudInfoBasePosY = 0.278;
    self.hudInfoBaseHeight = 0.58;
    self.infoPanelPath = Utils.getFilename("CraneInfo.png", self.baseDirectory);
	self.hudInfoBaseOverlay = Overlay:new("hudInfoBaseOverlay", self.infoPanelPath, self.hudInfoBasePosX, self.hudInfoBasePosY, self.hudInfoBaseWidth, self.hudInfoBaseHeight);
    self.showHudInfoBase = false;
	
    self.hudInfoBasePosXd = 0.73;
    self.hudInfoBaseWidthd = 0.35;
    self.hudInfoBasePosYd = 0.2775;
    self.hudInfoBaseHeightd = 0.58;
    self.infoPanelPathd = Utils.getFilename("CraneDoors.png", self.baseDirectory);
	self.hudInfoBaseOverlayd = Overlay:new("hudInfoBaseOverlay", self.infoPanelPathd, self.hudInfoBasePosXd, self.hudInfoBasePosYd, self.hudInfoBaseWidthd, self.hudInfoBaseHeightd);
    self.showHudInfoBased = true;

end;

function FlieglContainerCraneFW:keyEvent(unicode, sym, modifier, isDown)
	if self.leftSupportArm.islifted and not self.attacherVehicle.rootPartArm.locked and not self.attacherVehicle.workingPartArm.locked and self.attacherVehicle.workingPartArm.extended then
		if bitAND(modifier, Input.MOD_CTRL) > 0 and InputBinding.isPressed(InputBinding.OPENDOORALL) then
			self.door.closeall = true;
			self.door.docheck = true;
		elseif bitAND(modifier, Input.MOD_CTRL) == 0 and InputBinding.isPressed(InputBinding.OPENDOORALL) then
			self.door.openall = true;
			self.door.docheck = true;
		end;
	end;
end;

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

function FlieglContainerCraneFW:delete()

	if self.hudInfoBaseOverlay ~= nil then
		self.hudInfoBaseOverlay:delete();
	end;
	
	if self.hudInfoBaseOverlayd ~= nil then
		self.hudInfoBaseOverlayd:delete();
	end;

	if self.CraneSound ~= nil then
        delete(self.CraneSound);
    end;

end;

function FlieglContainerCraneFW:draw()

	if self.attacherVehicle ~= nil then
		self.showHudInfoBase = self.attacherVehicle.showHudInfoBaseh;
	end;

	if self.showHudInfoBase and not self.attacherVehicle.rootPartArm.locked and not self.attacherVehicle.workingPartArm.locked and self.attacherVehicle.workingPartArm.extended then
	setTextColor(1, 1, 1, 1);
    	if self.leftSupportArm.isdown then
			self.hudInfoBaseOverlay:render();
			renderText(0.83, 0.80, 0.02, string.format("%s\n%s", g_i18n:getText("doorMenuR1"), g_i18n:getText("doorMenuR2")));
			renderText(0.88, 0.72, 0.02, string.format("%s\n%s - %s", g_i18n:getText("DeactivateCraneR1"), g_i18n:getText("DeactivateCraneR2"), InputBinding.getButtonKeyName(InputBinding.ACTIVATECRANE)));
			if InputBinding.isPressed(InputBinding.LEFT_SPIN) then
				setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
			if InputBinding.getButtonKeyName(InputBinding.LEFT_SPIN) == "Z" then
				self.turnArmLeftreplacey = "Y";
			elseif InputBinding.getButtonKeyName(InputBinding.LEFT_SPIN) == 'Y' then
				self.turnArmLeftreplacey = "Z";
			else 
				self.turnArmLeftreplacey = InputBinding.getButtonKeyName(InputBinding.LEFT_SPIN);
			end;
			renderText(0.88, 0.64, 0.02, string.format("%s - %s", g_i18n:getText("turnArmLeft"), self.turnArmLeftreplacey));
			if InputBinding.isPressed(InputBinding.RIGHT_SPIN) then
				setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
			if InputBinding.getButtonKeyName(InputBinding.RIGHT_SPIN) == "Z" then
				self.turnArmRightreplacey = "Y";
			elseif InputBinding.getButtonKeyName(InputBinding.RIGHT_SPIN) == 'Y' then
				self.turnArmRightreplacey = "Z";
			else 
				self.turnArmRightreplacey = InputBinding.getButtonKeyName(InputBinding.RIGHT_SPIN);
			end;
			renderText(0.88, 0.62, 0.02, string.format("%s - %s", g_i18n:getText("turnArmRight"), self.turnArmRightreplacey));
			if InputBinding.isPressed(InputBinding.LIFT_MAINARM) then
				setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
			renderText(0.88, 0.56, 0.02, string.format("%s - %s", g_i18n:getText("LiftArm"), InputBinding.getButtonKeyName(InputBinding.LIFT_MAINARM)));
			if InputBinding.isPressed(InputBinding.LOWER_MAINARM) then
				setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
			renderText(0.88, 0.54, 0.02, string.format("%s - %s", g_i18n:getText("LowerArm"), InputBinding.getButtonKeyName(InputBinding.LOWER_MAINARM)));
			if InputBinding.isPressed(InputBinding.LIFT_WORKINGARM) then
				setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
			renderText(0.88, 0.48, 0.02, string.format("%s - %s", g_i18n:getText("LiftArm"), InputBinding.getButtonKeyName(InputBinding.LIFT_WORKINGARM)));
			if InputBinding.isPressed(InputBinding.LOWER_WORKINGARM) then
				setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
			renderText(0.88, 0.46, 0.02, string.format("%s - %s", g_i18n:getText("LowerArm"), InputBinding.getButtonKeyName(InputBinding.LOWER_WORKINGARM)));
			if InputBinding.isPressed(InputBinding.EXPAND_ARM) then
				setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
			renderText(0.88, 0.40, 0.02, string.format("%s - %s", g_i18n:getText("ExpandArm"), InputBinding.getButtonKeyName(InputBinding.EXPAND_ARM)));
			if InputBinding.isPressed(InputBinding.SHORTEN_ARM) then
				setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
			renderText(0.88, 0.38, 0.02, string.format("%s - %s", g_i18n:getText("RetractArm"), InputBinding.getButtonKeyName(InputBinding.SHORTEN_ARM)));
			setTextColor(1, 1, 1, 1);
			if self.attachedImplements[1] == nil then
				renderText(0.815, 0.32, 0.02, string.format("%s - %s", g_i18n:getText("TransportMove"), InputBinding.getButtonKeyName(InputBinding.TRANSPORT_POSITION)));
			end;
		elseif self.leftSupportArm.islifted then
		    self.hudInfoBaseOverlayd:render();
			renderText(0.815, 0.64, 0.02, string.format("%s\n%s", g_i18n:getText("craneMenuR1"), g_i18n:getText("craneMenuR2")));
   			renderText(0.815, 0.48, 0.02, string.format("%s:\n%s", g_i18n:getText("OpenAllDoors"), InputBinding.getButtonKeyName(InputBinding.OPENDOORALL)));
			renderText(0.815, 0.42, 0.02, string.format("%s:\nCTRL + %s", g_i18n:getText("CloseAllDoors"), InputBinding.getButtonKeyName(InputBinding.OPENDOORALL)));
			if self.Done.doorfl then
			    setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
			renderText(0.815, 0.82, 0.02, string.format("%s", InputBinding.getButtonKeyName(InputBinding.OPENDOORFL)));
			if self.Done.doorbl then
			    setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
		    renderText(0.815, 0.79, 0.02, string.format("%s", InputBinding.getButtonKeyName(InputBinding.OPENDOORBL)));
			if self.Done.doorfr then
			    setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
		    renderText(0.935, 0.82, 0.02, string.format("%s", InputBinding.getButtonKeyName(InputBinding.OPENDOORFR)));
			if self.Done.doorbr then
			    setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
		    renderText(0.935, 0.79, 0.02, string.format("%s", InputBinding.getButtonKeyName(InputBinding.OPENDOORBR)));
			if self.Done.doorb then
			    setTextColor(0, 1, 0, 1);
			else
			    setTextColor(1, 1, 1, 1);
			end;
		    renderText(0.875, 0.76, 0.02, string.format("%s", InputBinding.getButtonKeyName(InputBinding.OPENDOORB)));
			setTextColor(1, 1, 1, 1);
			renderText(0.88, 0.72, 0.02, string.format("%s\n%s - %s", g_i18n:getText("ActivateCraneR1"), g_i18n:getText("ActivateCraneR2"), InputBinding.getButtonKeyName(InputBinding.ACTIVATECRANE)));
		end;
	end;

end;

function FlieglContainerCraneFW:update(dt)

	if self:getIsActiveForInput() then
		if self.attacherVehicle ~= nil then
			if not self.attacherVehicle.rootPartArm.locked and not self.attacherVehicle.workingPartArm.locked and self.attacherVehicle.workingPartArm.extended then
				if InputBinding.hasEvent(InputBinding.ACTIVATECRANE) then
					self.moveSupportArms = not self.moveSupportArms;
					self.Go.pillar1 = not self.Go.pillar1;
					self.Done.pillar1 = true;
					self.Go.pillar2 = not self.Go.pillar2;
					self.Done.pillar2 = true;
				end;
			end;
		end;

		if self.leftSupportArm.isdown then
			if InputBinding.isPressed(InputBinding.LEFT_SPIN) or (self.doTransportMove and self.rootArm.zeroMoveLeft) then
				local leftSpin = self.rootArm;
				local rot = {getRotation(leftSpin.node)};
				local newRot = Utils.getMovedLimitedValues(rot, leftSpin.maxRot, leftSpin.minRot, 3, leftSpin.rotTime, dt, false);
				setRotation(leftSpin.node, unpack(newRot));
			end;

			if InputBinding.isPressed(InputBinding.RIGHT_SPIN) or (self.doTransportMove and self.rootArm.zeroMoveRight) then
				local rightSpin = self.rootArm;
				local rot = {getRotation(rightSpin.node)};
				local newRot = Utils.getMovedLimitedValues(rot, rightSpin.maxRot, rightSpin.minRot, 3, rightSpin.rotTime, dt, true);
				setRotation(rightSpin.node, unpack(newRot));
		    end;

			if InputBinding.isPressed(InputBinding.LOWER_MAINARM) or (self.doTransportMove and self.mainArm.zeroMoveDown) then
				local leftSpin = self.mainArm;
				local rot = {getRotation(leftSpin.node)};
				local newRot = Utils.getMovedLimitedValues(rot, leftSpin.maxRot, leftSpin.minRot, 3, leftSpin.rotTime, dt, false);
				setRotation(leftSpin.node, unpack(newRot));
			end;

			if InputBinding.isPressed(InputBinding.LIFT_MAINARM) or (self.doTransportMove and self.mainArm.zeroMoveUp) then
				local rightSpin = self.mainArm;
				local rot = {getRotation(rightSpin.node)};
				local newRot = Utils.getMovedLimitedValues(rot, rightSpin.maxRot, rightSpin.minRot, 3, rightSpin.rotTime, dt, true);
				setRotation(rightSpin.node, unpack(newRot));
		    end;
	    
			if InputBinding.isPressed(InputBinding.LOWER_WORKINGARM) then
				self.workingArmMoving = not self.workingArmMoving;
				local leftSpin = self.workingArm;
				local rot = {getRotation(leftSpin.node)};
				local newRot = Utils.getMovedLimitedValues(rot, leftSpin.maxRot, leftSpin.minRot, 3, leftSpin.rotTime, dt, false);
				setRotation(leftSpin.node, unpack(newRot));

				local x, y, z = getRotation(self.transformer.node);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.transformer.maxRot, self.transformer.minRot, 3, self.transformer.rotTime, dt, false);
				setRotation(self.transformer.node, unpack(newRot));
			end;

			if InputBinding.isPressed(InputBinding.LIFT_WORKINGARM) or (self.doTransportMove and self.workingArm.zeroMove) then
				self.workingArmMoving = not self.workingArmMoving;
				local rightSpin = self.workingArm;
				local rot = {getRotation(rightSpin.node)};
				local newRot = Utils.getMovedLimitedValues(rot, rightSpin.maxRot, rightSpin.minRot, 3, rightSpin.rotTime, dt, true);
				setRotation(rightSpin.node, unpack(newRot));
		
				local x, y, z = getRotation(self.transformer.node);
				local rot = {x,y,z};
				local newRot = Utils.getMovedLimitedValues(rot, self.transformer.maxRot, self.transformer.minRot, 3, self.transformer.rotTime, dt, true);
				setRotation(self.transformer.node, unpack(newRot));
	    	end;

			if InputBinding.isPressed(InputBinding.SHORTEN_ARM) or (self.doTransportMove and self.extension1Arm.zeroMove) then
				local revmove1 = self.extension1Arm;
				local trans = {getTranslation(revmove1.node)};
				local newTrans = Utils.getMovedLimitedValues(trans, revmove1.maxHeight, revmove1.minHeight, 3, revmove1.moveTime, dt, true);
				setTranslation(revmove1.node, unpack(newTrans));
			
				local revmove2 = self.extension2Arm;
				local trans = {getTranslation(revmove2.node)};
				local newTrans = Utils.getMovedLimitedValues(trans, revmove2.maxHeight, revmove2.minHeight, 3, revmove2.moveTime, dt, true);
				setTranslation(revmove2.node, unpack(newTrans));
			end;

			if InputBinding.isPressed(InputBinding.EXPAND_ARM) then
				local fwdmove1 = self.extension1Arm;
				local trans = {getTranslation(fwdmove1.node)};
				local newTrans = Utils.getMovedLimitedValues(trans, fwdmove1.maxHeight, fwdmove1.minHeight, 3, fwdmove1.moveTime, dt, false);
				setTranslation(fwdmove1.node, unpack(newTrans));
			
				local fwdmove2 = self.extension2Arm;
				local trans = {getTranslation(fwdmove2.node)};
				local newTrans = Utils.getMovedLimitedValues(trans, fwdmove2.maxHeight, fwdmove2.minHeight, 3, fwdmove2.moveTime, dt, false);
				setTranslation(fwdmove2.node, unpack(newTrans));
		    end;
		else
	    	if self.leftSupportArm.islifted and not self.attacherVehicle.rootPartArm.locked and not self.attacherVehicle.workingPartArm.locked and self.attacherVehicle.workingPartArm.extended then
				if InputBinding.hasEvent(InputBinding.OPENDOORFL) then
					self.Go.doorfl = not self.Go.doorfl;
					self.Done.doorfl = true;
				end;
				if InputBinding.hasEvent(InputBinding.OPENDOORBL) then
					self.Go.doorbl = not self.Go.doorbl;
					self.Done.doorbl = true;
				end;
					if InputBinding.hasEvent(InputBinding.OPENDOORFR) then
					self.Go.doorfr = not self.Go.doorfr;
					self.Done.doorfr = true;
				end;
				if InputBinding.hasEvent(InputBinding.OPENDOORBR) then
					self.Go.doorbr = not self.Go.doorbr;
					self.Done.doorbr = true;
				end;
				if InputBinding.hasEvent(InputBinding.OPENDOORB) then
					self.Go.doorb = not self.Go.doorb;
					self.Done.doorb = true;
				end;
			end;
		end;
	
		if InputBinding.hasEvent(InputBinding.TRANSPORT_POSITION) and self.attachedImplements[1] == nil and self.leftSupportArm.isdown then
			self.doTransportMove = true;
			self.mainArm.zeroHomeSearch = true;
			self.rootArm.zeroHomeSearch = true;
		end;
	
		if self.doTransportMove then
    	    local x, y, z = getRotation(self.rootArm.node);
        	local x1, y1, z1 = getRotation(self.mainArm.node);
        	local x2, y2, z2 = getRotation(self.workingArm.node);
	        local x3, y3, z3 = getTranslation(self.extension1Arm.node);
    	    if self.extension1Arm.minHeight[3] == z3 and self.workingArm.minRot[1] == x2 and self.mainArm.zeroRot[1] - 0.01 < x1 and self.mainArm.zeroRot[1] + 0.01 > x1 and self.rootArm.zeroRot[2] - 0.01 < y and self.rootArm.zeroRot[2] +0.01 > y then
				self.moveSupportArms = not self.moveSupportArms;
				self.Go.pillar1 = not self.Go.pillar1;
				self.Done.pillar1 = true;
				self.Go.pillar2 = not self.Go.pillar2;
				self.Done.pillar2 = true;
				self.door.closeall = true;
				self.door.docheck = true;
				self.doTransportMove = false;
        	end;
			if z3 < self.extension1Arm.minHeight[3] then
			    self.extension1Arm.zeroMove = true
			elseif z3 == self.extension1Arm.minHeight[3] then
		    	self.extension1Arm.zeroMove = false
			end;
			if x2 < self.workingArm.minRot[2] then
			    self.workingArm.zeroMove = true;
			elseif x2 == self.workingArm.minRot[2] then
		    	self.workingArm.zeroMove = false;
			end;
			if z3 == self.extension1Arm.minHeight[3] and x2 == self.workingArm.minRot[1] then
				self.extensionworkingArmhome = true;
			elseif z3 < self.extension1Arm.minHeight[3] or x2 < self.workingArm.minRot[1] then
				self.extensionworkingArmhome = false;
			end;
			if x1 > self.mainArm.zeroRot[1] - 0.01 and x1 < self.mainArm.zeroRot[1] + 0.01 then
				self.mainArm.zeroHomeSearch = false;
				self.mainArm.zeroMoveDown = false;
				self.mainArm.zeroMoveUp = false;
			end;
			if self.mainArm.zeroHomeSearch and x1 > self.mainArm.zeroRot[1] - 0.01 and x2 > self.workingArm.minRot[2] - 1.2 then
				self.mainArm.zeroMoveDown = true;
				self.mainArm.zeroMoveUp = false;
			elseif self.mainArm.zeroHomeSearch and x1 < self.mainArm.zeroRot[1] + 0.01 then
			    self.mainArm.zeroMoveUp = true;
			    self.mainArm.zeroMoveDown = false;
			end;
			if y > self.rootArm.zeroRot[2] - 0.01 and y < self.rootArm.zeroRot[2] + 0.01 then
				self.rootArm.Position = self.rootArm.zeroRot[2];
				self.rootArm.zeroHomeSearch = false;
				self.rootArm.zeroMoveLeft = false;
				self.rootArm.zeroMoveRight = false;
			end;
			if self.extensionworkingArmhome and not self.mainArm.zeroHomeSearch and self.rootArm.zeroHomeSearch and y > self.rootArm.zeroRot[2] - 0.01 then
				self.rootArm.zeroMoveLeft = true;
				self.rootArm.zeroMoveRight = false;
			elseif self.extensionworkingArmhome and not self.mainArm.zeroHomeSearch and self.rootArm.zeroHomeSearch and y < self.rootArm.zeroRot[2] + 0.01 then
				self.rootArm.zeroMoveLeft = false;
				self.rootArm.zeroMoveRight = true;
			end;
 		end;

		if self.door.docheck then
			local x, y, z = getRotation(self.door.flnode);
    	    local x1, y1, z1 = getRotation(self.door.frnode);
        	local x2, y2, z2 = getRotation(self.door.blnode);
	        local x3, y3, z3 = getRotation(self.door.brnode);
    	    local x4, y4, z4 = getRotation(self.door.bnode);
        	if z == self.door.minRot[3] then
	            self.door.flup = true;
    	        self.door.fldown= false;
			elseif z < self.door.front.maxRot[3] + 0.01 then
		    	self.door.flup = false;
			    self.door.fldown = true;
			else
			    self.door.flup = false;
				self.door.fldown = false;
			end;

			if z1 == self.door.minRot[3] then
        	    self.door.frup = true;
            	self.door.frdown= false;
			elseif z1 > self.door.front.maxRot[1] - 0.01 then
			    self.door.frup = false;
			    self.door.frdown = true;
			else
		    	self.door.frup = false;
				self.door.frdown = false;
			end;

	    	if z2 == self.door.minRot[3] then
            	self.door.blup = true;
	            self.door.bldown= false;
    	    elseif z2 < self.door.front.maxRot[3] + 0.01 then
			    self.door.blup = false;
		    	self.door.bldown = true;
			else
			    self.door.blup = false;
				self.door.bldown = false;
			end;

			if z3 == self.door.minRot[3] then
        	    self.door.brup = true;
            	self.door.brdown= false;
	        elseif z3 > self.door.front.maxRot[1] - 0.01 then
			    self.door.brup = false;
			    self.door.brdown = true;
			else
			    self.door.brup = false;
				self.door.brdown = false;
			end;

			if x4 == self.door.minRot[1] then
    	        self.door.bup = true;
        	    self.door.bdown= false;
	        elseif x4 < self.door.back.maxRot[1] + 0.01 then
			    self.door.bup = false;
			    self.door.bdown = true;
			else
			    self.door.bup = false;
				self.door.bdown = false;
			end;
		end;
	
		if self.door.closeall then
		    if self.door.fldown then
				self.Go.doorfl = not self.Go.doorfl;
				self.Done.doorfl = true;
			end;
			if self.door.frdown then
				self.Go.doorfr = not self.Go.doorfr;
				self.Done.doorfr = true;
			end;
			if self.door.bldown then
				self.Go.doorbl = not self.Go.doorbl;
				self.Done.doorbl = true;
			end;
			if self.door.brdown then
				self.Go.doorbr = not self.Go.doorbr;
				self.Done.doorbr = true;
			end;
			if self.door.bdown then
				self.Go.doorb = not self.Go.doorb;
				self.Done.doorb = true;
			end;
		self.door.closeall = false;
		self.door.docheck = false;
		end;
	
		if self.door.openall then
		    if self.door.flup then
				self.Go.doorfl = not self.Go.doorfl;
				self.Done.doorfl = true;
			end;
			if self.door.frup then
				self.Go.doorfr = not self.Go.doorfr;
				self.Done.doorfr = true;
			end;
			if self.door.blup then
				self.Go.doorbl = not self.Go.doorbl;
				self.Done.doorbl = true;
			end;
			if self.door.brup then
				self.Go.doorbr = not self.Go.doorbr;
				self.Done.doorbr = true;
			end;
			if self.door.bup then
				self.Go.doorb = not self.Go.doorb;
				self.Done.doorb = true;
			end;
			self.door.openall = false;
			self.door.docheck = false;
		end;

		if self.hydraulic ~= nil and self.mainArm ~= nil then
			local ax, ay, az = getWorldTranslation(self.hydraulic.node);
			local bx, by, bz = getWorldTranslation(self.mainArm.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.hydraulicMainArm ~= nil and self.transformer ~= nil then
			local ax, ay, az = getWorldTranslation(self.hydraulicMainArm.node);
			local bx, by, bz = getWorldTranslation(self.transformer.fixPoint);
			local x, y, z = worldDirectionToLocal(getParent(self.hydraulicMainArm.node), bx-ax, by-ay, bz-az);
			setDirection(self.hydraulicMainArm.node, x*-1, y*-1, z*-1, 0, 1, 0);
			if self.hydraulicMainArm.punch ~= nil then
				local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
				setTranslation(self.hydraulicMainArm.punch, 0, 0, (distance-self.hydraulicMainArm.punchDistance)*-1);
			end;
		end;

		if self.transformer ~= nil and self.workingArm ~= nil then
			local ax, ay, az = getWorldTranslation(self.transformer.transform2);
			local bx, by, bz = getWorldTranslation(self.workingArm.fixPoint);
			local x, y, z = worldDirectionToLocal(getParent(self.transformer.transform2), bx-ax, by-ay, bz-az);
			setDirection(self.transformer.transform2, x*-1, y*-1, z*-1, 0, 1, 0);
		end;
	end;

	if self.leftSupportArm.feet ~= nil then
		local x, y, z = getTranslation(self.leftSupportArm.feet.node);
		if y > self.leftSupportArm.feet.maxHeight[2] - 0.01 then
			self.leftSupportArm.isdown = true;
		else
			self.leftSupportArm.isdown = false;
		end;
	end;
	
	if self.leftSupportArm ~= nil then
		local x, y, z = getTranslation(self.leftSupportArm.node);
		if x < self.leftSupportArm.minHeight[1] + 0.01 then
			self.leftSupportArm.islifted = true;
		else
			self.leftSupportArm.islifted = false;
		end;
	end;

	if self.Go.pillar1 ~= nil and self.Done.pillar1 ~= false then
		self:anim("pillar1",false);
		self:anim("pillar2",false);
	end;
	if self.Go.doorfl ~= nil and self.Done.doorfl ~= false then
		self:anim("doorfl",false);
	end;
	if self.Go.doorbl ~= nil and self.Done.doorbl ~= false then
		self:anim("doorbl",false);
	end;
	if self.Go.doorfr ~= nil and self.Done.doorfr ~= false then
		self:anim("doorfr",false);
	end;
	if self.Go.doorbr ~= nil and self.Done.doorbr ~= false then
		self:anim("doorbr",false);
	end;
	if self.Go.doorb ~= nil and self.Done.doorb ~= false then
		self:anim("doorb",false);
	end;
	
	local x, y, z = getRotation(self.rootArm.node);
		self.armPos.rootArm = y;
	local x, y, z = getRotation(self.mainArm.node);
	    self.armPos.mainArm = x;
	local x, y, z = getRotation(self.workingArm.node);
		self.armPos.workingArm = x;
	local x, y, z = getTranslation(self.extension1Arm.node);
		self.armPos.ex1Arm = z;
	local x, y, z = getTranslation(self.extension2Arm.node);
		self.armPos.ex2Arm = z;

	if ((InputBinding.isPressed(InputBinding.LEFT_SPIN) or InputBinding.isPressed(InputBinding.RIGHT_SPIN) or InputBinding.isPressed(InputBinding.LIFT_MAINARM) or InputBinding.isPressed(InputBinding.LOWER_MAINARM) or InputBinding.isPressed(InputBinding.LIFT_WORKINGARM) or InputBinding.isPressed(InputBinding.LOWER_WORKINGARM) or InputBinding.isPressed(InputBinding.EXPAND_ARM) or InputBinding.isPressed(InputBinding.SHORTEN_ARM)) and self.leftSupportArm.isdown) or (not self.leftSupportArm.islifted and not self.leftSupportArm.isdown) or self.doTransportMove then
		if self.CraneSound ~= nil and not self.CraneSoundEnabled then
			if self:getIsActiveForSound() then
   				setSamplePitch(self.CraneSound, self.CraneSoundPitchOffset);
				playSample(self.CraneSound, 0, self.CraneSoundVolume, 0);
				self.CraneSoundEnabled = true;
			end;
		end;
	else
		stopSample(self.CraneSound);
		self.CraneSoundEnabled = false;
	end;

	if not self.leftSupportArm.islifted then
		self.lockable = true
	else
		self.lockable = false;
	end;
	
end;

function FlieglContainerCraneFW:validateAttacherJoint(craneimplement, jointDesc, dt)
    return true;
end;

function FlieglContainerCraneFW: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;

function FlieglContainerCraneFW: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; 	
