liebherr = {}

function liebherr.prerequisitesPresent(specializations)
     Vehicle.registerJointType("shovel");
    return SpecializationUtil.hasSpecialization(Motorized, specializations);
end;

function liebherr:load(xmlFile)
 self.frontlight = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.frontlight#index"));
    setVisibility(self.frontlight, false);

 self.braslight = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.braslight#index"));
    setVisibility(self.braslight, false);

 self.backlight = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.backlight#index"));
    setVisibility(self.backlight, false); 

 self.codelight = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.codelight#index"));
    setVisibility(self.codelight, false);


 self.doRotate = SpecializationUtil.callSpecializationsFunction("doRotate");
     self.rotatingParts = {};
    local rotatingPartsCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.rotatingParts#count"), 0);	
	for i=1, rotatingPartsCount do
		local namei = string.format("vehicle.rotatingParts.rotatingPart%d", i);
		local rotatingPart = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, namei .. "#index"));
		
		self.rotatingParts[i] = {};
		self.rotatingParts[i].node = rotatingPart;
		
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, namei .. "#minRot"));
        self.rotatingParts[i].minRot = {};
        self.rotatingParts[i].minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotatingParts[i].minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotatingParts[i].minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		
		x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, namei .. "#maxRot"));
		self.rotatingParts[i].maxRot = {};
        self.rotatingParts[i].maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotatingParts[i].maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotatingParts[i].maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
		
		self.rotatingParts[i].rotTime = Utils.getNoNil(getXMLString(xmlFile, namei .. "#rotTime"), 2)*1000;
	end;
	
	self.isLeftDoorOpen = false;

  local numexhaustParticleSystems = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.exhaustParticleSystems#count"), 0);
    self.exhaustParticleSystems = {};
    for i=1, numexhaustParticleSystems do
        local namei = string.format("vehicle.exhaustParticleSystems.exhaustParticle%d", i);
		local nodei = Utils.indexToObject(self.components, getXMLString(xmlFile, namei .. "#index"));
        Utils.loadParticleSystem(xmlFile, self.exhaustParticleSystems, namei, nodei, false, nil, self.baseDirectory)		
        setVisibility(self.exhaustParticleSystems[i], false);
    end;

self.rpms = {};
    local rpm1, rpm2, rpm3, rpm4, rpm5, rpm6, rpm7, rpm8  = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.rpms#motor"));
	self.rpms[1] = {};
    self.rpms[1] = {rpm1, rpm2, rpm3, rpm4, rpm5, rpm6, rpm7, rpm8};
   
	self.rpmNum = 1;
  
   self.keys = {};
	self.keysName = {};
    local i=0;
    while true do
        local baseName = string.format("vehicle.keys.input(%d)", i);
        local inputName = getXMLString(xmlFile, baseName.. "#name");
        if inputName == nil then
            break;
        end;
        local inputKey = getXMLString(xmlFile, baseName.. "#key");
        if Input[inputKey] == nil then
            print("Error: invalid key '" .. inputKey .. "'  for input event '" .. inputName .. "'");
            break;
        end;
        self.keys[inputName] = Input[inputKey];
		self.keysName[inputName] = Utils.getNoNil(getXMLString(xmlFile, baseName.."#keyname"),"Touche ?");
        i = i+1;
    end;
	  
    local jointDesc = {};

   local shovelAttacher = {};
	local jointTypeStr = getXMLString(xmlFile,"vehicle.attacherJoints.attacherJoint#jointType");
	shovelAttacher.joint = getXMLString(xmlFile,"vehicle.attacherJoints.attacherJoint#index");
	shovelAttacher.index = 0;
	self.shovel = shovelAttacher;
	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.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.. "#legAttacher"));
			Collision.index = 0;
			self.collisionArm[nameR] = Collision;
			self:connectCollisions(nameR);
		end;
	end;

   
    self.rundumleuchtenAnz = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.rundumleuchten#count"),0);
    self.rundumleuchtenKey = getXMLString(xmlFile, "vehicle.rundumleuchten#key");
    self.rundumleuchtenAn = false;
    self.rundumleuchten = {};
    for i=1, self.rundumleuchtenAnz do
        local objname = string.format("vehicle.rundumleuchten.light" .. "%d",i);
        self.rundumleuchten[i] = {};
        self.rundumleuchten[i].rotNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, objname .. "#rotNode"));
        self.rundumleuchten[i].light = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, objname .. "#light"));
        self.rundumleuchten[i].source = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, objname .. "#lightsource"));
        self.rundumleuchten[i].speed = Utils.getNoNil(getXMLInt(xmlFile,  objname .. "#rotSpeed"), 1)/1000;
        self.rundumleuchten[i].emit = Utils.getNoNil(getXMLBool(xmlFile, objname .. "#emitLight"), true);
        if not self.rundumleuchten[i].emit and self.rundumleuchten[i].source ~= nil then
           setVisibility(self.rundumleuchten[i].source, false);
        end;
    end;
     local hidraulicSound = getXMLString(xmlFile, "vehicle.hidraulicSound#file");
    if hidraulicSound ~= nil and hidraulicSound ~= "" then
        hidraulicSound = Utils.getFilename(hidraulicSound, self.baseDirectory); 
        self.hidraulicSound = createSample("hidraulicSound");
        loadSample(self.hidraulicSound, hidraulicSound, false);
        self.hidraulicSoundPitchOffset = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hidraulicSound#pitchOffset"), 1);
        self.hidraulicSoundPitchScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hidraulicSound#pitchScale"), 0);
        self.hidraulicSoundPitchMax = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.hidraulicSound#pitchMax"), 2.0);
    end;
   
 
    
    local workingArmNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.workingArm#index"));
    if workingArmNode ~= nil then
        self.workingArm = {};
        self.workingArm.node = workingArmNode;
        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"));
    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));


		self.transformer.rotTime = self.workingArm.rotTime;


		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 rotationPartNodetourelle = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.tourelle#index"));
    if rotationPartNodetourelle ~= nil then
        self.tourelle = {};
        self.tourelle.node = rotationPartNodetourelle;

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

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

        self.tourelle.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.tourelle#rotTime"), 2)*1000;
        self.tourelle.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.tourelle#touchRotLimit"), 10))
    end;
  
    
    local rotationPartNodebras2 = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.bras2#index"));
    if rotationPartNodebras2 ~= nil then
        self.bras2 = {};
        self.bras2.node = rotationPartNodebras2;

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

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

        self.bras2.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.bras2#rotTime"), 2)*1000;
     
     
	    self.bras2.pivotverin = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.bras2#pivotverin"));
    end;
    
    local rotationPartNodebras1 = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.bras1#index"));
    if rotationPartNodebras1 ~= nil then
        self.bras1 = {};
        self.bras1.node = rotationPartNodebras1;

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

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

        self.bras1.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.bras1#rotTime"), 2)*1000;
     
     
	    self.bras1.pivotverin = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.bras1#pivotverin"));
    end;
    

    
   
	
    self.verin2 = {};
	self.verin2.node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verin2#indexverin"));
	self.verin2.tige = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verin2#indextige"));
	self.verin2.translationtige = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verin2#translationtige"));
	local ax, ay, az = getWorldTranslation(self.verin2.tige);
    local bx, by, bz = getWorldTranslation(self.verin2.translationtige);
    self.verin2.tigeDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
    
    self.verin1 = {};
	self.verin1.node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verin1#indexverin"));
	self.verin1.tige = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verin1#indextige"));
	self.verin1.translationtige = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verin1#translationtige"));
	local ax, ay, az = getWorldTranslation(self.verin1.tige);
    local bx, by, bz = getWorldTranslation(self.verin1.translationtige);
    self.verin1.tigeDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
    
  
    
    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);
    
	local objectAttacher = {};
	objectAttacher.joint = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.anchor#index"));
	objectAttacher.index = 0;
	self.object = objectAttacher;
	self.attachedObject = nil;
	self.objectAttachable = false;
	self.objectInRange = nil;
	
    

	
    self.fillScale = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fillScale#value"), 1);
	self.name = Utils.getNoNil(getXMLString(xmlFile, "vehicle.name."..g_languageShort), "Objekt");
	
	
	
        self.frontlightActive = false;
        self.braslightActive = false;
        self.backlightActive = false;   
        self.codelightActive = false;   
	
end;

function liebherr:delete()
   if self.hidraulicSound ~= nil then
        delete(self.hidraulicSound);
    end;
end;

function liebherr:readStream(streamId, connection)
      if self.workingArmNode ~= nil then
          local x = streamReadFloat32(streamId);
          local y = streamReadFloat32(streamId);
          local z = streamReadFloat32(streamId);
         setRotation(self.workingArmNode.node, x, y, z);
      end;
     if self.transformer ~= nil then
          local x = streamReadFloat32(streamId);
          local y = streamReadFloat32(streamId);
          local z = streamReadFloat32(streamId);
         setRotation(self.transformer.node, x, y, z);
      end;

    if self.tourelle ~= nil then
          local x = streamReadFloat32(streamId);
          local y = streamReadFloat32(streamId);
          local z = streamReadFloat32(streamId);
         setRotation(self.tourelle.node, x, y, z);
      end;

   if self.bras2 ~= nil then
          local x = streamReadFloat32(streamId);
          local y = streamReadFloat32(streamId);
          local z = streamReadFloat32(streamId);
         setRotation(self.bras2.node, x, y, z);
      end;
   if self.bras1 ~= nil then
          local x = streamReadFloat32(streamId);
          local y = streamReadFloat32(streamId);
          local z = streamReadFloat32(streamId);
         setRotation(self.bras1.node, x, y, z);
      end;
end;
  
function liebherr:writeStream(streamId, connection)
     
     if self.workingArmNode ~= nil then
          local x, y, z = getRotation(self.workingArmNode.node);
          streamWriteFloat32(streamId, x);
          streamWriteFloat32(streamId, y);
          streamWriteFloat32(streamId, z);
      end;
      if self.transformer ~= nil then
          local x, y, z = getRotation(self.transformer.node);
          streamWriteFloat32(streamId, x);
          streamWriteFloat32(streamId, y);
          streamWriteFloat32(streamId, z);
      end;
      if self.tourelle ~= nil then
          local x, y, z = getRotation(self.tourelle.node);
          streamWriteFloat32(streamId, x);
          streamWriteFloat32(streamId, y);
          streamWriteFloat32(streamId, z);
      end;
      if self.bras2 ~= nil then
          local x, y, z = getRotation(self.bras2.node);
          streamWriteFloat32(streamId, x);
          streamWriteFloat32(streamId, y);
          streamWriteFloat32(streamId, z);
      end;
      if self.bras1 ~= nil then
          local x, y, z = getRotation(self.bras1.node);
          streamWriteFloat32(streamId, x);
          streamWriteFloat32(streamId, y);
          streamWriteFloat32(streamId, z);
      end;
end;



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

function liebherr:keyEvent(unicode, sym, modifier, isDown)    

	if self.isEntered and self.isMotorStarted then
	if sym == Input.KEY_KP_7 then
		self.rotationMinbras2 = isDown;
                self.playHidraulic = not self.playHidraulic;            
       end;
	
	if sym == Input.KEY_KP_4 then
		self.rotationMaxbras2 = isDown;
                self.playHidraulic1 = not self.playHidraulic1;
	 end;
	if sym == Input.KEY_KP_8 then
		self.rotationMinbras1 = isDown;
                self.playHidraulic2 = not self.playHidraulic2;	 
         end;
	if sym == Input.KEY_KP_5 then
		self.rotationMaxbras1 = isDown;
	 self.playHidraulic3 = not self.playHidraulic3;
        end;
	if sym == Input.KEY_m then
		self.rotationMintourelle = isDown;
	self.playHidraulic4 = not self.playHidraulic4;
         end;
	if sym == Input.KEY_n then
		self.rotationMaxtourelle = isDown;
	self.playHidraulic5 = not self.playHidraulic5;
        end;
	if sym == Input.KEY_KP_6 then
		self.rotationMaxworkingArm = isDown;
	self.playHidraulic6 = not self.playHidraulic6;
        end;
	if sym == Input.KEY_KP_9 then
		self.rotationMinworkingArm = isDown;
	 self.playHidraulic7 = not self.playHidraulic7;
        end;

       if isDown and sym == Input.KEY_k then		
               self.Go.gpied = not self.Go.gpied;
		self.Done.gpied = true;
                 self.Go.dpied = not self.Go.dpied;
		self.Done.dpied = true;
                self.Go.dpatin = not self.Go.dpatin;
		self.Done.dpatin = true;
                self.Go.gpatin = not self.Go.gpatin;
		self.Done.gpatin = true;	
	end;
		
	if isDown and sym == Input.KEY_k then
		self.Go.lame = not self.Go.lame;	
		self.Done.lame = true;
                self.Go.verrin = not self.Go.verrin;	
		self.Done.verrin = true;    
                self.Go.verrinrot = not self.Go.verrinrot;	
		self.Done.verrinrot = true;                	
	end;

         if sym == self.keys.maxrpm and self.rpmNum < 8 then
		       self.rpmNum = self.rpmNum + 1;
		    elseif sym == self.keys.minrpm and self.rpmNum > 1 then 
		        self.rpmNum = self.rpmNum - 1;
	        end;
  end;
  
end;
function liebherr:update(dt)
if self:getIsActive() and self.isClient then
    if self.isEntered and self.isMotorStarted then
       if self.playHidraulic or self.playHidraulic1 or self.playHidraulic2 or self.playHidraulic3 or self.playHidraulic4 or self.playHidraulic5 or self.playHidraulic6 or self.playHidraulic7 then
            if self.hidraulicSound ~= nil and not self.hidraulicSoundEnabled then
                if self:getIsActiveForSound() then
                    setSamplePitch(self.hidraulicSound, self.hidraulicSoundPitchOffset);
                    playSample(self.hidraulicSound, 0, 0.5, 0);
                    self.hidraulicSoundEnabled = true;
                end;
            end;
     
	
        else
            if self.hidraulicSound ~= nil and self.hidraulicSoundEnabled then
                stopSample(self.hidraulicSound);
                self.hidraulicSoundEnabled = false;
            end;
     
	end;
   end;

        if self.frontlightActive then			
				local frontlights = self.frontlight;
				setVisibility(frontlights, self.frontlightActive);			
		    else
     			local frontlights = self.frontlight;
				setVisibility(frontlights, self.frontlightActive, false);			
	end;
 
     if self.braslightActive then			
				local braslights = self.braslight;
				setVisibility(braslights, self.braslightActive);			
		    else
     			local braslights = self.braslight;
				setVisibility(braslights, self.braslightActive, false);			
	end;
  
    if self.backlightActive then			
				local backlights = self.backlight;
				setVisibility(backlights, self.backlightActive);			
		    else
     			local backlights = self.backlight;
				setVisibility(backlights, self.backlightActive, false);			
	end;

   if self.codelightActive then			
				local codelights = self.codelight;
				setVisibility(codelights, self.codelightActive);			
		    else
     			local codelights = self.codelight;
				setVisibility(codelights, self.codelightActive, false);			
	end;

    if self.isEntered and not self.rundumleuchtenAn then
        if InputBinding.hasEvent(InputBinding.LIEWORKLIGHT) then            
                 self.frontlightActive = not self.frontlightActive;
                 self.braslightActive = not self.braslightActive;
                 self.backlightActive = not self.backlightActive;
                 self.codelightActive = false;                 
       elseif InputBinding.hasEvent(InputBinding.LIEWORKLIGHT) then
       self.codelightActive = true;               
       end;     
    end;

      if self.isEntered then
        if InputBinding.hasEvent(InputBinding.LIECODELIGHT) then            
                  self.codelightActive = not self.codelightActive;
        end;               
    end;

      if self.isEntered then
                      if self.rundumleuchtenKey ~= nil then
                         if InputBinding.hasEvent(InputBinding.LIEGIRO) then
                           self.rundumleuchtenAn = not self.rundumleuchtenAn;
                           for i=1, self.rundumleuchtenAnz do
                             setVisibility(self.rundumleuchten[i].light, self.rundumleuchtenAn);
                           end;
                         end;
                      end;
                    end;

                     if self.rundumleuchtenAnz > 0 then
                       if self.rundumleuchtenAn then
                          for i=1, self.rundumleuchtenAnz do
                              rotate(self.rundumleuchten[i].rotNode, 0, dt*self.rundumleuchten[i].speed, 0);
                          end;
                        end;
                      end;
       
        if self.isMotorStarted and self.motorSound ~= nil and self.playMotorSoundTime <= self.time and self:getIsActiveForSound() then
		setSamplePitch(self.motorSound, math.min(self.motorSoundPitchOffset + self.motorSoundPitchScale*math.abs(self.rpms[1][self.rpmNum] / 90), self.motorSoundPitchMax));
		if self.playMotorSound then
			playSample(self.motorSound, 0, self.motorSoundVolume, 0);
			self.playMotorSound = false;
		end;
	end;



        if self.isEntered == nil then
	        stopSample(self.motorMBSound);
	end;

	if self.Go.lame ~= nil and self.Done.lame ~= false then
		self:anim("lame", false);
	end;
	if self.Go.verrin ~= nil and self.Done.verrin ~= false then
		self:anim("verrin", false);
	end;
        if self.Go.verrinrot ~= nil and self.Done.verrinrot ~= false then
		self:anim("verrinrot", false);
	end;		
	if self.Go.dpied ~= nil and self.Done.dpied ~= false then
		self:anim("dpied", false);
        end;

        if self.Go.gpied ~= nil and self.Done.gpied ~= false then
		self:anim("gpied", false);
	end;

	if self.Go.dpatin ~= nil and self.Done.dpatin ~= false then
		self:anim("dpatin", false);
	end;	
	
	if self.Go.gpatin ~= nil and self.Done.gpatin ~= false then
		self:anim("gpatin", false);
	end;

   



    self.lameMoving = 0;
    self.bras2Moving = 0; 
	self.bras1Moving = 0;   
    self.workingArmMoving = 0;
    if self.isEntered then
       if self.rotatingParts[1] ~= nil then
			if InputBinding.hasEvent(InputBinding.LIEDOOR) then
				self.isLeftDoorOpen = not self.isLeftDoorOpen;
			end;
			
			self:doRotate(1, self.isLeftDoorOpen, dt);	
   		    end;
     end;
	local doRotate = self.rotationMaxtourelle or self.rotationMintourelle
    	if self.tourelle ~= nil and doRotate then
		local x, y, z = getRotation(self.tourelle.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.tourelle.maxRot, self.tourelle.minRot, 3, self.tourelle.rotTime, dt, not self.rotationMaxtourelle);
		setRotation(self.tourelle.node, unpack(newRot));		
	end;
	
   
	
   	local doRotate = self.rotationMaxbras2 or self.rotationMinbras2
    	if self.bras2 ~= nil and doRotate then
		local x, y, z = getRotation(self.bras2.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.bras2.maxRot, self.bras2.minRot, 3, self.bras2.rotTime, dt, not self.rotationMaxbras2);
		setRotation(self.bras2.node, unpack(newRot));
		
	end;
	
   	local doRotate = self.rotationMaxbras1 or self.rotationMinbras1
    	if self.bras1 ~= nil and doRotate then
		local x, y, z = getRotation(self.bras1.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.bras1.maxRot, self.bras1.minRot, 3, self.bras1.rotTime, dt, not self.rotationMaxbras1);
		setRotation(self.bras1.node, unpack(newRot));
		
	end;
	
    local doRotate = self.rotationMaxworkingArm or self.rotationMinworkingArm
	if self.workingArm ~= nil and doRotate then
		local x, y, z = getRotation(self.workingArm.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.workingArm.maxRot, self.workingArm.minRot, 3, self.workingArm.rotTime, dt, self.rotationMaxworkingArm);
		setRotation(self.workingArm.node, unpack(newRot));
		
	end;
	
	local doRotate = self.rotationMaxworkingArm or self.rotationMinworkingArm
	if self.transformer ~= nil and doRotate then
		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, self.rotationMaxworkingArm);
		setRotation(self.transformer.node, unpack(newRot));
		
	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;

    
	if self.verin2 ~= nil and self.bras2 ~= nil then
		local ax, ay, az = getWorldTranslation(self.verin2.node);
		local bx, by, bz = getWorldTranslation(self.bras2.pivotverin);
		local x, y, z = worldDirectionToLocal(getParent(self.verin2.node), bx-ax, by-ay, bz-az);
		setDirection(self.verin2.node, x*-1, y*-1, z*-1, 0, 1, 0);
		if self.verin2.tige ~= nil then
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(self.verin2.tige, 0, 0, (distance-self.verin2.tigeDistance)*-1);
		end;
	end;
	if self.verin1 ~= nil and self.bras1 ~= nil then
		local ax, ay, az = getWorldTranslation(self.verin1.node);
		local bx, by, bz = getWorldTranslation(self.bras1.pivotverin);
		local x, y, z = worldDirectionToLocal(getParent(self.verin1.node), bx-ax, by-ay, bz-az);
		setDirection(self.verin1.node, x*-1, y*-1, z*-1, 0, 1, 0);
		if self.verin1.tige ~= nil then
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(self.verin1.tige, 0, 0, (distance-self.verin1.tigeDistance)*-1);
		end;
	end;
	
  local joint = self.componentJoints[1];
		setJointFrame(joint.jointIndex, 0,joint.jointNode);
		local joint = self.componentJoints[2];
end;	
end;
      


function liebherr:draw()
  g_currentMission:addExtraPrintText("Taste N/M: Turm Drehen");
  g_currentMission:addExtraPrintText("Taste KP_7/KP_4: Hauptarm");
  g_currentMission:addExtraPrintText("Taste KP_8/KP_5: Vorderarm");
  g_currentMission:addExtraPrintText("Taste KP_9/KP_6: Schaufel");
  g_currentMission:addExtraPrintText("Taste K: Stuetzen");
  g_currentMission:addExtraPrintText("Taste L: Schild");
  g_currentMission:addExtraPrintText("Taste 7: Tuer");  
end;

function liebherr:onDeactivateSounds()
    if self.hidraulicSound ~= nil and self.hidraulicSoundEnabled then
        stopSample(self.hidraulicSound);
        self.hidraulicSoundEnabled = false;
    end; 
end;


function liebherr: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 liebherr: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 liebherr:validateAttacherJoint(implement, jointDesc, dt)
    return true;
end;

function liebherr:doRotate(index, boolean, dt)
	local x, y, z = getRotation(self.rotatingParts[index].node);
	local rot = {x,y,z};
	local newRot = Utils.getMovedLimitedValues(rot, self.rotatingParts[index].maxRot, self.rotatingParts[index].minRot, 3, self.rotatingParts[index].rotTime, dt, not boolean);
	setRotation(self.rotatingParts[index].node, unpack(newRot));
end;