Bull = {};

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

function Bull:load(xmlFile)



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.ripper3.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.ripper3#rotTime"), 2)*1000;
        self.ripper3.pivotverin = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.ripper3#pivotverin"));
    end;
    
        local translationPartNode11 = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.translationPart11#index"));
    if translationPartNode11 ~= nil then
        self.translationPart11 = {};
        self.translationPart11.node = translationPartNode11;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.translationPart11#minTrans"));
        self.translationPart11.minTrans = {};
        self.translationPart11.minTrans[1] = Utils.getNoNil(x, 0);
        self.translationPart11.minTrans[2] = Utils.getNoNil(y, 0);
        self.translationPart11.minTrans[3] = Utils.getNoNil(z, 0);

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

        self.translationPart11.transTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.translationPart11#transTime"), 2)*1000;
        self.translationPart11.touchTransLimit = Utils.getNoNil(getXMLString(xmlFile, "vehicle.translationPart11#touchTransLimit"), 10);
    end;
    
    self.verinlame = {};
	self.verinlame.node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verinlame#indexverin"));
	self.verinlame.tige = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verinlame#indextige"));
	self.verinlame.translationtige = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verinlame#translationtige"));
	local ax, ay, az = getWorldTranslation(self.verinlame.tige);
    local bx, by, bz = getWorldTranslation(self.verinlame.translationtige);
    self.verinlame.tigeDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
    
        self.verinripper = {};
	self.verinripper.node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verinripper#indexverin"));
	self.verinripper.tige = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verinripper#indextige"));
	self.verinripper.translationtige = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.verinripper#translationtige"));
	local ax, ay, az = getWorldTranslation(self.verinripper.tige);
    local bx, by, bz = getWorldTranslation(self.verinripper.translationtige);
    self.verinripper.tigeDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
    
        self.portedent = {};
	self.portedent.node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.portedent#indexverin"));
	self.portedent.tige = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.portedent#indextige"));
	self.portedent.translationtige = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.portedent#translationtige"));
	local ax, ay, az = getWorldTranslation(self.portedent.tige);
    local bx, by, bz = getWorldTranslation(self.portedent.translationtige);
    self.portedent.tigeDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);





    self.jumWheelsActive = false;




        
end;
  
function Bull:delete()
end;
 

   
function Bull:mouseEvent(posX, posY, isDown, isUp, button)
   end;
 
function Bull:keyEvent(unicode, sym, modifier, isDown)
   


end;
 
function Bull:update(dt)

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

	
    local doTranslate = self.translationMax11 or self.translationMin11
		if self.translationMax11 ~= nil and doTranslate then
		local x, y, z = getTranslation(self.translationPart11.node);
        local trans = {x,y,z};
        local newTrans = Utils.getMovedLimitedValues(trans, self.translationPart11.maxTrans, self.translationPart11.minTrans, 3, self.translationPart11.transTime, dt, not self.translationMax11);
        setTranslation(self.translationPart11.node, unpack(newTrans));
	end;
	
	local doRotate = self.rotationMaxlame or self.rotationMinlame
    	if self.lame ~= nil and doRotate then
		local x, y, z = getRotation(self.lame.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.lame.maxRot, self.lame.minRot, 3, self.lame.rotTime, dt, not self.rotationMaxlame);
		setRotation(self.lame.node, unpack(newRot));
	end;
				local doRotate = self.rotationMaxrotverin or self.rotationMinrotverin
    	if self.rotverin ~= nil and doRotate then
		local x, y, z = getRotation(self.rotverin.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.rotverin.maxRot, self.rotverin.minRot, 3, self.rotverin.rotTime, dt, not self.rotationMaxrotverin);
		setRotation(self.rotverin.node, unpack(newRot));
	end;
	
			local doRotate = self.rotationMaxripper or self.rotationMinripper
    	if self.ripper ~= nil and doRotate then
		local x, y, z = getRotation(self.ripper.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.ripper.maxRot, self.ripper.minRot, 3, self.ripper.rotTime, dt, not self.rotationMaxripper);
		setRotation(self.ripper.node, unpack(newRot));
	end;
	local doRotate = self.rotationMaxripper2 or self.rotationMinripper2
    	if self.ripper2 ~= nil and doRotate then
		local x, y, z = getRotation(self.ripper2.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.ripper2.maxRot, self.ripper2.minRot, 3, self.ripper2.rotTime, dt, not self.rotationMaxripper2);
		setRotation(self.ripper2.node, unpack(newRot));
	end;
	local doRotate = self.rotationMaxripper3 or self.rotationMinripper3
    	if self.ripper3 ~= nil and doRotate then
		local x, y, z = getRotation(self.ripper3.node);
		local rot = {x,y,z};
		local newRot = Utils.getMovedLimitedValues(rot, self.ripper3.maxRot, self.ripper3.minRot, 3, self.ripper3.rotTime, dt, not self.rotationMaxripper3);
		setRotation(self.ripper3.node, unpack(newRot));
	end;
	
	     if self.verinlame ~= nil and self.lame ~= nil then
		local ax, ay, az = getWorldTranslation(self.verinlame.node);
		local bx, by, bz = getWorldTranslation(self.lame.pivotverin);
		local x, y, z = worldDirectionToLocal(getParent(self.verinlame.node), bx-ax, by-ay, bz-az);
		setDirection(self.verinlame.node, x*-1, y*-1, z*-1, 0, 1, 0);
		if self.verinlame.tige ~= nil then
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(self.verinlame.tige, 0, 0, (distance-self.verinlame.tigeDistance)*-1);
		end;
	end;
	
		
	     if self.verinripper ~= nil and self.ripper3 ~= nil then
		local ax, ay, az = getWorldTranslation(self.verinripper.node);
		local bx, by, bz = getWorldTranslation(self.ripper3.pivotverin);
		local x, y, z = worldDirectionToLocal(getParent(self.verinripper.node), bx-ax, by-ay, bz-az);
		setDirection(self.verinripper.node, x*-1, y*-1, z*-1, 0, 1, 0);
		if self.verinripper.tige ~= nil then
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(self.verinripper.tige, 0, 0, (distance-self.verinripper.tigeDistance)*-1);
		end;
	end;
	
		
	     if self.portedent ~= nil and self.ripper2 ~= nil then
		local ax, ay, az = getWorldTranslation(self.portedent.node);
		local bx, by, bz = getWorldTranslation(self.ripper2.pivotverin);
		local x, y, z = worldDirectionToLocal(getParent(self.portedent.node), bx-ax, by-ay, bz-az);
		setDirection(self.portedent.node, x*-1, y*-1, z*-1, 0, 1, 0);
		if self.portedent.tige ~= nil then
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(self.portedent.tige, 0, 0, (distance-self.portedent.tigeDistance)*-1);
		end;
	end;
   
   
   end;
 
function Bull:updateTick(dt)
end;
 
function Bull:draw()
end;
 

function Bull:onActivate()
end;


function Bull:onDeactivate()
end;
 
 
