-- xyzspain

TerragatorHakenlift = {};

function TerragatorHakenlift.prerequisitesPresent(specializations)
  -- return SpecializationUtil.hasSpecialization(Motorized, specializations);
 
   return true;
end;

function TerragatorHakenlift:load(xmlFile)
-- desplazamiento de conjuntos
	self.setHydraulicDirection = SpecializationUtil.callSpecializationsFunction("setHydraulicDirection");
	
	local hydraulicsCount = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.hydraulics#count"), 0);	
	self.hydraulics = {};	
	for i=1, hydraulicsCount do
		local hydraulicName = string.format("vehicle.hydraulics.hydraulic%d", i);		
		self.hydraulics[i] = {};		
		self.hydraulics[i].node = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#index"));
		self.hydraulics[i].punch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punch"));
		self.hydraulics[i].translationPunch = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#punchFixpoint"));
		self.hydraulics[i].fixPoint = Utils.indexToObject(self.components, getXMLString(xmlFile, hydraulicName .. "#fixpoint"));	
		local ax, ay, az;		
		if self.hydraulics[i].punch ~= nil then
			ax, ay, az = getWorldTranslation(self.hydraulics[i].punch);
		else
			ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
		end;
		local bx, by, bz = getWorldTranslation(self.hydraulics[i].translationPunch);		
		self.hydraulics[i].punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		self.hydraulics[i].doScale = Utils.getNoNil(getXMLBool(xmlFile, hydraulicName .. "#doScale"), false);
	end;
	-------------------
	 self.keys = {};
    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];
        i = i+1;
    end;
	
			-------------------------
		---------flashlights
	self.FlashLightLeft = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.indexl#index"));
    self.FlashLightRight = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.indexr#index"));	 
	
	
	
	
    self.flashLightLeftActive = false;
    self.flashLightRightActive = false;
    self.flash = false;
    self.flashRight = false;
    self.flashLeft = false;
    self.delayOnLeft = 0;
    self.delayOffLeft = 0;
    self.delayOnRight = 0;
    self.delayOffRight = 0;
    self.delayOn = 0;
    self.delayOff = 0;
   
    turnSoundFile = Utils.getFilename("turn.wav", self.baseDirectory);
    self.turnSoundId = createSample("turnSound");
    loadSample(self.turnSoundId, turnSoundFile, false);
	-------------------
	---brake light and sound
	self.lightsbrake = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.brake#index"));

	self.braking = false;
	local brakeSound = getXMLString(xmlFile, "vehicle.brakeSound#file");
    if brakeSound ~= nil and brakeSound ~= "" then
	brakeSound = Utils.getFilename(brakeSound, self.baseDirectory);
        self.brakeSound = createSample("brakeSound");
        loadSample(self.brakeSound, brakeSound, false);
    end;
	

	
	-------------	cardans------
	self.numCardans = Utils.getNoNil(getXMLInt(xmlFile, "vehicle.cardans#count"), 0); 
	self.cardans = {}; 
 for i=1, self.numCardans do 
     local partnamei = string.format("vehicle.cardans.part" .. "%d", i); 
     self.cardans[i] = {}; 
     self.cardans[i].index = Utils.indexToObject(self.components, getXMLString(xmlFile, partnamei.."#index")); 
   
 end;
			---emision de particulas ruedas

self.wheelParticleSystems = {};
    local psFile = getXMLString(xmlFile, "vehicle.wheelParticleSystems#file");
    if psFile ~= nil then
        local i=0;
        while true do
            local baseName = string.format("vehicle.wheelParticleSystems.wheelParticleSystem(%d)", i);
            local node = getXMLString(xmlFile, baseName.. "#node");
            if node == nil then
                break;
            end;
            node = Utils.indexToObject(self.components, node);
			self.wheelParticleSystems.node = node;
            if node ~= nil then
                local wheelParticleSystem = {};
                wheelParticleSystem.particleSystems = {};
                Utils.loadParticleSystem(xmlFile, wheelParticleSystem.particleSystems, "vehicle.wheelParticleSystems", node, false, nil, self.baseDirectory);
                table.insert(self.wheelParticleSystems, wheelParticleSystem);
            end;
            i = i+1;
        end;
    end;
	
 self.exhaustParticleLow = {};
    Utils.loadParticleSystem(xmlFile, self.exhaustParticleLow, "vehicle.exhaustParticleLow", self.components, false, nil, self.baseDirectory);
    self.exhaustParticleHigh = {};
    Utils.loadParticleSystem(xmlFile, self.exhaustParticleHigh, "vehicle.exhaustParticleHigh", self.components, false, nil, self.baseDirectory);
	
		-------------	height control
	local translationNode1 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.translation1#index"));
    if translationNode1 ~= nil then
        self.translation1 = {};
        self.translation1.node = translationNode1;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.translation1#minTrans"));
        self.translation1.minTrans = {};
        self.translation1.minTrans[1] = Utils.getNoNil(x, 0);
        self.translation1.minTrans[2] = Utils.getNoNil(y, 0);
        self.translation1.minTrans[3] = Utils.getNoNil(z, 0);

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

	    self.translation1.transTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.translation1#transTime"), 2)*1000;
      
    end;
			---libertad bloques
	self.setJointRotLimit = SpecializationUtil.callSpecializationsFunction("setJointRotLimit");
	self.firstDo = {};
	self.arm = {};
	-- self.low=true;
	---------------------------
		 local rotationPartNodeleftDoor = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.leftDoor#index"));
    if rotationPartNodeleftDoor ~= nil then
        self.rotationPartleftDoor = {};
        self.rotationPartleftDoor.node = rotationPartNodeleftDoor;

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

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

        self.rotationPartleftDoor.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.leftDoor#rotTime"), 2)*1000;
        self.rotationPartleftDoor.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.leftDoor#touchRotLimit"), 10));
    end;

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

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

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

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

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

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

        self.rotationPartClucth.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartClucth#rotTime"), 2)*1000;
        self.rotationPartClucth.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartClucth#touchRotLimit"), 10));
    end;
	
	---------------mirros with activation 
	local mirrorLeftNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.mirrorLeft#index"));
        self.mirrorLeft = {};
          self.mirrorLeft.node = mirrorLeftNode;


	local mirrorLeft1Node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.mirrorLeft1#index"));
        self.mirrorLeft1 = {};
          self.mirrorLeft1.node = mirrorLeft1Node;

	local mirrorRightNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.mirrorRight#index"));
        self.mirrorRight = {};
          self.mirrorRight.node = mirrorRightNode;
	
	local mirrorRight1Node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.mirrorRight1#index"));
        self.mirrorRight1 = {};
          self.mirrorRight1.node = mirrorRight1Node;
	
	local headSupportNode = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.headSupport#index"));
        self.headSupport = {};
          self.headSupport.node = headSupportNode;
local count = getXMLInt(xmlFile, "vehicle.rotationParts#count");
	if count ~= nil then
		self.rotationParts = {}
		local rotationPart = self.rotationParts;
		for i=1, count do
			local varName = string.format("rotationPart" .. "%d", i);
			rotationPart[varName] = {};
			local rotationPartname = string.format("vehicle.rotationParts.rotationPart" .. "%d", i);
			rotationPart[varName].index = Utils.indexToObject(self.components, getXMLString(xmlFile, rotationPartname .. "#index"));
			local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, rotationPartname .. "#minRot"));
			rotationPart[varName].minRot = {};
			rotationPart[varName].minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
			rotationPart[varName].minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
			rotationPart[varName].minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
			local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, rotationPartname .. "#maxRot"));
			rotationPart[varName].maxRot = {};
			rotationPart[varName].maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
			rotationPart[varName].maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
			rotationPart[varName].maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

			rotationPart[varName].rotTime = Utils.getNoNil(getXMLInt(xmlFile, rotationPartname .. "#rotTime"), 2)*1000;	
			rotationPart[varName].touchRotLimit = Utils.getNoNil(getXMLInt(xmlFile, rotationPartname .. "#touchRotLimit"), 1)/1000;	
		end;
	end;
	
	self.indoorCamIndex = 2;
	self.outdoorCamIndex = 1;
	--------------------
	-------------WIPER
	local rotationPartNodeWischer = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.rotationPartWischer#index"));
    if rotationPartNodeWischer ~= nil then
        self.rotationPartWischer = {};
        self.rotationPartWischer.node = rotationPartNodeWischer;

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

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

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

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

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

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

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

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

        self.rotationPartWischer1.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartWischer1#rotTime"), 2)*1000;
        self.rotationPartWischer1.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPartWischer1#touchRotLimit"), 10));
    end;
	  self.delayWischer1 = 0;
		self.delayWischer2 = 0;
		
	self.controlpath = Utils.getFilename("menu.png", self.baseDirectory);
   
    
    self.hudTerragatorHakenliftWidth = 0.526;
    self.hudTerragatorHakenliftHeight = 0.320;
    self.hudTerragatorHakenliftPoxX = 0;
    self.hudTerragatorHakenliftPoxY = 0;
    self.hudTerragatorHakenliftOverlay = Overlay:new("hudTerragatorHakenlift", self.controlpath, self.hudTerragatorHakenliftPoxX, self.hudTerragatorHakenliftPoxY, self.hudTerragatorHakenliftWidth, self.hudTerragatorHakenliftHeight);
     self.bcActive = false;
	
	-------------------	
		
		
		
		
		
		
	
	
end;
function TerragatorHakenlift:delete()
    Utils.deleteParticleSystem(self.exhaustParticleLow);
    Utils.deleteParticleSystem(self.exhaustParticleHigh);   
	
end;
function TerragatorHakenlift:mouseEvent(posX, posY, isDown, isUp, button)
end;


function TerragatorHakenlift:onLeave()
    
	 Utils.setEmittingState(self.exhaustParticleLow, false);
	 Utils.setEmittingState(self.exhaustParticleHigh, false);
end;
function TerragatorHakenlift:keyEvent(unicode, sym, modifier, isDown)
  -- if  sym == Input.KEY_KP_8 then
			-- self.translation1max = isDown;
	-- end;
	 -- if  sym == Input.KEY_KP_5 then
			-- self.translation1min = isDown;
	-- end;

end;
function TerragatorHakenlift:update(dt)
	
if self:getIsActive() then 
	


	
	
---flashlights
	
	if InputBinding.isPressed (InputBinding.FLASH_LEFT)  then
		self.flashLeft = not self.flashLeft;
		self.delayOnLeft = 10;
		self.flashRight = false;
		self.flash = false;
		self.flashLightRightActive = false;
	end;

	if InputBinding.isPressed (InputBinding.FLASH_RIGHT)  then
		self.flashRight = not self.flashRight;
		self.delayOnRight = 10;
		self.flashLeft = false;
		self.flash = false;
		self.flashLightLeftActive = false;
	end;
	if InputBinding.isPressed (InputBinding.WARNINGS) then
		self.flash = not self.flash;
		self.flashRight = false;
		self.flashLeft = false;
		self.delayOn = 20;
		self.flashLightRightActive = false;
		self.flashLightLeftActive = false;
	end;
	
	if self.FlashLightLeft ~= nil then
            if self.flashLightLeftActive then
            	setVisibility(self.FlashLightLeft, self.flashLightLeftActive);
			
	    else
            	setVisibility(self.FlashLightLeft, self.flashLightLeftActive);
			
	    end;
        end;

	if self.FlashLightRight ~= nil then
            if self.FlashLightRightActive then
            	setVisibility(self.FlashLightRight, self.flashLightRightActive);
				
	    else
            	setVisibility(self.FlashLightRight, self.flashLightRightActive);
				
	    end;
        end;

	if self.flashLeft then
		if self.delayOnLeft >= -1 then
			self.delayOnLeft = self.delayOnLeft -dt;
		end;
		if not self.flashLightLeftActive then
			if self.delayOnLeft < 0 then
				self.delayOffLeft = 200;
				self.flashLightLeftActive = true;
				playSample(self.turnSoundId, 1, 0.7, 0);
			end;
		end;
		if self.delayOffLeft >= 0 then
			self.delayOffLeft = self.delayOffLeft -dt;
		end;
		if self.flashLightLeftActive then
			if self.delayOffLeft < 0 then
				self.delayOnLeft = 200;
				self.flashLightLeftActive = false;
			end;
		end;
	end;

	if self.flashRight then
		if self.delayOnRight >= 0 then
			self.delayOnRight = self.delayOnRight -dt;
		end;
		if not self.flashLightRightActive then
			if self.delayOnRight < 0 then
				self.delayOffRight = 200;
				self.flashLightRightActive = true;
				playSample(self.turnSoundId, 1, 0.7, 0);
			end;
		end;
		if self.delayOffRight >= 0 then
			self.delayOffRight = self.delayOffRight -dt;
		end;
		if self.flashLightRightActive then
			if self.delayOffRight < 0 then
				self.delayOnRight = 200;
				self.flashLightRightActive = false;
			end;
		end;
	end;

	if self.flash then
		if self.delayOn >= 0 then
			self.delayOn = self.delayOn -dt;
		end;
		if not self.flashLightRightActive then
			if self.delayOn < 0 then
				self.delayOff = 200;
				self.flashLightRightActive = true;
				self.flashLightLeftActive = true;
				playSample(self.turnSoundId, 1, 0.7, 0);
			end;
		end;
		if self.delayOff >= 0 then
			self.delayOff = self.delayOff -dt;
		end;
		if self.flashLightRightActive then
			if self.delayOff < 0 then
				self.delayOn = 200;
				self.flashLightLeftActive = false;
				self.flashLightRightActive = false;
			end;
		end;
	end;

	if not self.flashLeft and not self.flashRight then
		if not self.flash then
			self.flashLightRightActive = false;
			self.flashLightLeftActive = false;
		end;
	end;
		
	if not self.flash and not self.flashLeft then
		if not self.flashRight then
			self.flashLightRightActive = false;
		end;
	end;

	if not self.flash and not self.flashRight then
		if not self.flashLeft then
			self.flashLightLeftActive = false;
		end;
	end;
	
	
	--------------------brake------------------------
   inputAxis_2 = InputBinding.getAnalogInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE);

        if InputBinding.isAxisZero(inputAxisY) then
        inputAxis_2 = InputBinding.getDigitalInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE);
        end;
	
		if (self.movingDirection*self.lastSpeed*(-inputAxis_2)) < -0.001 then
			setVisibility(self.lightsbrake, true);
			
			-- if not self.brakeSoundRunning then
					-- playSample(self.brakeSound, 1, 1, 0);
					-- self.brakeSoundRunning = true;
					
				-- end;
			self.braking = true;
			
			self.rotationMaxBrake=true;
		else
		     setVisibility(self.lightsbrake, false);
			self.rotationMaxBrake=false;
	
			self.braking = false;
			self.brakeSoundRunning = false;	
		
		end;
-----  cardans ----
		local zRot = (self.lastSpeed*self.movingDirection*1000)/2
				for i=1, self.numCardans do 
				rotate(self.cardans[i].index,0, 0, zRot);
				end; 
	---particulas ruedas

	local dens = 0; local dens1; local dens2; local dens3;
		 local x,y,z = getWorldTranslation(self.wheels[1].repr);
		 local x1,y1,z1 = getWorldTranslation(self.wheels[2].repr);
		 local x2,y2,z2 = getWorldTranslation(self.wheels[3].repr);
		local id = g_currentMission.terrainDetailId;
		local xx, zz, widthX, widthZ, heightX, heightZ = Utils.getXZWidthAndHeight(id, x, z, x1, z1, x2, z2);
		dens1 = getDensityParallelogram(id, xx, zz, widthX, widthZ, heightX, heightZ, g_currentMission.cultivatorChannel, 1);
		dens2 = getDensityParallelogram(id, xx, zz, widthX, widthZ, heightX, heightZ, g_currentMission.sowingChannel, 1);
		dens3 = getDensityParallelogram(id, xx, zz, widthX, widthZ, heightX, heightZ, g_currentMission.ploughChannel, 1);
		if g_currentMission.environment.lastRainScale <= 0.1 and g_currentMission.environment.timeSinceLastRain > 30 then
			dens = dens1+dens2+dens3;
		end;
		if dens > 0 and self.lastSpeed*self.speedDisplayScale*3600 > 4 then
			
			
			for k=1, 5 do
				Utils.setEmittingState(self.wheelParticleSystems[k].particleSystems, self.wheels[k].hasGroundContact);
			end;
		else
			for i=1, table.getn(self.wheelParticleSystems) do
				Utils.setEmittingState(self.wheelParticleSystems[i].particleSystems, false);
			end;
		
		end;
		
		 -- if self.isMotorStarted then
		if self.motor.lastMotorRpm > 200 and self.motor.lastMotorRpm < 1200 then
			Utils.setEmittingState(self.exhaustParticleLow, true);
        	Utils.setEmittingState(self.exhaustParticleHigh, false);
		else
			Utils.setEmittingState(self.exhaustParticleLow, false);
        	Utils.setEmittingState(self.exhaustParticleHigh, true);			
		end;
		if self.motor.lastMotorRpm > 1300 and not self.braking then
			Utils.setEmittingState(self.exhaustParticleLow, false);
        	Utils.setEmittingState(self.exhaustParticleHigh, true); 		
		elseif self.motor.lastMotorRpm < 1300 or self.braking then
			Utils.setEmittingState(self.exhaustParticleLow, true);
        	Utils.setEmittingState(self.exhaustParticleHigh, false); 
		end;
    -- else 
        -- Utils.setEmittingState(self.exhaustParticleLow, false);
        -- Utils.setEmittingState(self.exhaustParticleHigh, false); 
    -- end;
			
		if InputBinding.isPressed (InputBinding.INFOHUD) then
				self.bcActive = not self.bcActive;
			end;
		
	----height control
		if InputBinding.isPressed(InputBinding.HEIGHT_CONTROL_UP) and InputBinding.isPressed(InputBinding.ACTIVATION) then
			self.heightUp = not  self.heightUp;
		end;
		if  InputBinding.isPressed(InputBinding.HEIGHT_CONTROL_DOWN) and InputBinding.isPressed(InputBinding.ACTIVATION) then
			self.heightDown = not  self.heightDown;
		end;

			local x, y, z = getTranslation(self.translation1.node)
				if y >-0.15 then
				self.low=true;
				elseif y<-0.18 then
				self.low=false;
				end;
	
		--------left door
	
	if InputBinding.isPressed (InputBinding.LEFT_DOOR) and InputBinding.isPressed(InputBinding.ACTIVATION) then
		self.rotationMaxleftDoor = not self.rotationMaxleftDoor;	
	end;	
	
	--- clucth
	if InputBinding.isPressed (InputBinding.SPEED_LEVEL1) or InputBinding.isPressed(InputBinding.SPEED_LEVEL2) or InputBinding.isPressed(InputBinding.SPEED_LEVEL3) or InputBinding.isPressed(InputBinding.SPEED_LEVEL4) then
		self.rotationMaxClucth=true;
	else
		self.rotationMaxClucth=false;
	end;

-----------------mirrors
			if InputBinding.isPressed (InputBinding.MIRRORS_UP) and InputBinding.isPressed(InputBinding.ACTIVATION_MIRRORS) then
				self.down=not self.down;
			end;
			if InputBinding.isPressed (InputBinding.MIRRORS_DOWN) and InputBinding.isPressed(InputBinding.ACTIVATION_MIRRORS) then
				self.up=not self.up;
			end;
			if InputBinding.isPressed (InputBinding.MIRRORS_LEFT) and InputBinding.isPressed(InputBinding.ACTIVATION_MIRRORS) then
				self.left=not self.left;
			end;
			if InputBinding.isPressed (InputBinding.MIRRORS_RIGHT) and InputBinding.isPressed(InputBinding.ACTIVATION_MIRRORS) then
				self.right=not self.right;
			end;
			if InputBinding.isPressed (InputBinding.MIRRORS_LEFT1) and InputBinding.isPressed(InputBinding.ACTIVATION_MIRRORS) then
				self.left1=not self.left1;
			end;
			if InputBinding.isPressed (InputBinding.MIRRORS_RIGHT1) and InputBinding.isPressed(InputBinding.ACTIVATION_MIRRORS) then
				self.right1=not self.right1;
			end;
	
			-- if InputBinding.isPressed (InputBinding.MIRRORS_ON) and InputBinding.isPressed(InputBinding.ACTIVATION_MIRRORS) then
				-- self.mirror=not self.mirror;
			-- end;
	if self.camIndex == self.indoorCamIndex or self.camIndex == self.outdoorCamIndex then
				local indoorCam = self.cameras[self.indoorCamIndex];
				local outdoorCam = self.cameras[self.outdoorCamIndex];
		if self.camIndex == self.indoorCamIndex then
		self.mirror=true
		elseif self.camIndex == self.outdoorCamIndex then
		self.mirror=false
		end;
		
			setVisibility(self.mirrorLeft.node, self.mirror);
			setVisibility(self.mirrorRight.node, self.mirror);
			setVisibility(self.mirrorLeft1.node, self.mirror);
			setVisibility(self.mirrorRight1.node, self.mirror);
			setVisibility(self.headSupport.node, not self.mirror);
	end;
	
	---- wiper
	if g_currentMission.environment.lastRainScale <= 0.1 and g_currentMission.environment.timeSinceLastRain > 30 then
			self.rainWarning = false;
		else
			self.rainWarning = true;
		end;
		
		if self.rainWarning and self.isMotorStarted then
			if self.delayWischer1 >= 0 then
				self.delayWischer1 = self.delayWischer1 -dt;
			end;
			if self.delayWischer2 >= 0 then
				self.delayWischer2 = self.delayWischer2 -dt;
			end;
			if not self.rotationMaxWischer then
				if self.delayWischer1 < 0 then
					self.delayWischer2 = 1000;
					self.rotationMaxWischer = true;
					self.rotationMaxWischer1 = true;
					self.rotationMaxWischerblatt = true;
				end;
			end;
			if self.rotationMaxWischer then
				if self.delayWischer2 < 0 then
					self.delayWischer1 = 1000;
					self.rotationMaxWischer = false;
					self.rotationMaxWischer1 = false;
					self.rotationMaxWischerblatt = false;
				end;
			end;
		else
			self.rotationMaxWischer = false;
			self.rotationMaxWischer1 = false;
			self.rotationMaxWischerblatt = false;
		end;
	
end;

	if self.rotationPartWischer ~= nil then
		local x, y, z = getRotation(self.rotationPartWischer.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartWischer.maxRot, self.rotationPartWischer.minRot, 3, self.rotationPartWischer.rotTime, dt, not self.rotationMaxWischer);
		setRotation(self.rotationPartWischer.node, unpack(newRot));
	end;  
    if self.rotationPartWischerblatt ~= nil then
		local x, y, z = getRotation(self.rotationPartWischerblatt.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartWischerblatt.maxRot, self.rotationPartWischerblatt.minRot, 3, self.rotationPartWischerblatt.rotTime, dt, not self.rotationMaxWischerblatt);
		setRotation(self.rotationPartWischerblatt.node, unpack(newRot));
	end;
	if self.rotationPartWischer1 ~= nil then
		local x, y, z = getRotation(self.rotationPartWischer1.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartWischer1.maxRot, self.rotationPartWischer1.minRot, 3, self.rotationPartWischer1.rotTime, dt, not self.rotationMaxWischer1);
		setRotation(self.rotationPartWischer1.node, unpack(newRot));
	end;  

		if self.down then
			local rotationPart = self.rotationParts.rotationPart5;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, true);
			setRotation(rotationPart.index, unpack(newRot));
			local rotationPart = self.rotationParts.rotationPart6;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, true);
			setRotation(rotationPart.index, unpack(newRot));
			
	    end;		
		if self.up then
			local rotationPart = self.rotationParts.rotationPart5;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, false);
			setRotation(rotationPart.index, unpack(newRot));
			local rotationPart = self.rotationParts.rotationPart6;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, false);
			setRotation(rotationPart.index, unpack(newRot));
			
	    end;  		

		if self.left then
			local rotationPart = self.rotationParts.rotationPart3;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, true);
			setRotation(rotationPart.index, unpack(newRot));
			local rotationPart = self.rotationParts.rotationPart4;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, true);
			setRotation(rotationPart.index, unpack(newRot));
			
	    end;		
		if self.right then
			local rotationPart = self.rotationParts.rotationPart3;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, false);
			setRotation(rotationPart.index, unpack(newRot));
			local rotationPart = self.rotationParts.rotationPart4;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, false);
			setRotation(rotationPart.index, unpack(newRot));
			
	    end;  		
			if self.left1 then
			local rotationPart = self.rotationParts.rotationPart1;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, true);
			setRotation(rotationPart.index, unpack(newRot));
			local rotationPart = self.rotationParts.rotationPart2;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, true);
			setRotation(rotationPart.index, unpack(newRot));
			
	    end;		
		if self.right1 then
			local rotationPart = self.rotationParts.rotationPart1;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, false);
			setRotation(rotationPart.index, unpack(newRot));
			local rotationPart = self.rotationParts.rotationPart2;
			local rot = {getRotation(rotationPart.index)};
			local newRot = Utils.getMovedLimitedValues(rot, rotationPart.maxRot, rotationPart.minRot, 3, rotationPart.rotTime, dt, false);
			setRotation(rotationPart.index, unpack(newRot));
			
	    end;  		






		if self.rotationPartClucth ~= nil then
			local x, y, z = getRotation(self.rotationPartClucth.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartClucth.maxRot, self.rotationPartClucth.minRot, 3, self.rotationPartClucth.rotTime, dt, not self.rotationMaxClucth);
			setRotation(self.rotationPartClucth.node, unpack(newRot));
		end;
	if self.rotationPartBrake ~= nil then
			local x, y, z = getRotation(self.rotationPartBrake.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartBrake.maxRot, self.rotationPartBrake.minRot, 3, self.rotationPartBrake.rotTime, dt, not self.rotationMaxBrake);
			setRotation(self.rotationPartBrake.node, unpack(newRot));
		end;
		
	   if self.rotationPartleftDoor ~= nil then
		   local x, y, z = getRotation(self.rotationPartleftDoor.node);
		   local rot = {x,y,z};
		   local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartleftDoor.maxRot, self.rotationPartleftDoor.minRot, 3, self.rotationPartleftDoor.rotTime, dt, not self.rotationMaxleftDoor);
		   setRotation(self.rotationPartleftDoor.node, unpack(newRot));
        end;
	if self.heightUp	then
		if self.translation1 ~= nil  then 
			local x, y, z = getTranslation(self.translation1.node); 
			local trans = {x,y,z}; 
			local newTrans = Utils.getMovedLimitedValues(trans, self.translation1.maxTrans, self.translation1.minTrans, 3, self.translation1.transTime, dt, true); 
			setTranslation(self.translation1.node, unpack(newTrans)); 
		end;	
	end;
		if self.heightDown	then
		if self.translation1 ~= nil  then 
			local x, y, z = getTranslation(self.translation1.node); 
			local trans = {x,y,z}; 
			local newTrans = Utils.getMovedLimitedValues(trans, self.translation1.maxTrans, self.translation1.minTrans, 3, self.translation1.transTime, dt, false); 
			setTranslation(self.translation1.node, unpack(newTrans)); 
		end;	
	end;	
-- local doTranslate = self.translation1max or self.translation1min 
	-- if self.translation1 ~= nil and doTranslate then 
		-- local x, y, z = getTranslation(self.translation1.node); 
		-- local trans = {x,y,z}; 
		-- local newTrans = Utils.getMovedLimitedValues(trans, self.translation1.maxTrans, self.translation1.minTrans, 3, self.translation1.transTime, dt, not self.translation1max); 
		-- setTranslation(self.translation1.node, unpack(newTrans)); 
	-- end; 
			--- asignacion de ejes de libertad  de rotacion segun condiciones de emsamblage  0 x, 2 z ,1 y 
		
		
	self:setJointRotLimit(self.componentJoints[2],12, 20, 1000,self.low==true , 0,dt);	
	self:setJointRotLimit(self.componentJoints[3],12, 20, 1000,self.low==true , 0,dt);	

	-- juntas

			for i, jointDesc in pairs(self.componentJoints) do
	   setJointFrame(self.componentJoints[i].jointIndex, 0, self.componentJoints[i].jointNode);
	end;
		self:setHydraulicDirection();



end;
function TerragatorHakenlift:draw()
 if self.hudTerragatorHakenliftOverlay ~= nil then
  if self.bcActive then
    self.hudTerragatorHakenliftOverlay:render();
  end;
end;
		if self.bcActive then	
			g_currentMission:addExtraPrintText("play 0: INFO ON");
		else
			g_currentMission:addExtraPrintText("play 0: INFO Off");
		end;  
end;
function TerragatorHakenlift:setHydraulicDirection()
		for i=1, table.getn(self.hydraulics) do
		local ax, ay, az = getWorldTranslation(self.hydraulics[i].node);
		local bx, by, bz = getWorldTranslation(self.hydraulics[i].fixPoint);
		local x, y, z = worldDirectionToLocal(getParent(self.hydraulics[i].node), bx-ax, by-ay, bz-az);
		
		setDirection(self.hydraulics[i].node, x, y, z, 0, 1, 0);
		local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
		if self.hydraulics[i].doScale then
			local xScale, yScale, zScale = getScale(self.hydraulics[i].node);
			local newScale = yScale * (distance / self.hydraulics[i].punchDistance);
			setScale(self.hydraulics[i].node, 1, 1, newScale);
		else
			if self.hydraulics[i].punch ~= nil then
				setTranslation(self.hydraulics[i].punch, 0, 0, distance-self.hydraulics[i].punchDistance);
			end;
		end;
	
	end;
end;
function TerragatorHakenlift:setJointRotLimit(nodei, up, down, speed, value, axle, dt)

	if not self.firstDo[nodei] then
		self.firstDo[nodei] = true;
		self.arm[nodei] = {0}; 
	end; 
	x, y, z = getRotation(nodei);
	rot = {x,y,z};	
	newRotLimit = {}; 
	newRotLimit[nodei] = {0,0,0};
	newRotLimit[nodei] = Utils.getMovedLimitedValues(self.arm[nodei], {down}, {up}, 1, speed * 2, dt, value);
	if math.abs(newRotLimit[nodei][1] - self.arm[nodei][1]) > 0.001 then
		local joint = nodei;
		setJointRotationLimit(joint.jointIndex, axle, true, Utils.degToRad(-newRotLimit[nodei][1]), Utils.degToRad(newRotLimit[nodei][1]));
	end;
	self.arm[nodei] = newRotLimit[nodei];			
end;
function key_convert(key)
    if key ~= nil then 
	    local keyname = "";
	    if key > 32 and key < 123 then
	    	keyname = string.upper(string.char(key));
	    elseif key > 255 and key < 266 then
	    	keyname = "NUM "..string.char(key-208);
	    else 
	    	keyname = "";
	    end;
	    return(keyname);
	  end;
end;