Vehicle.registerJointType("attachableFrontloader");
 
Anims = {};
 
function Anims.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Motorized, specializations);
end;
 
function Anims:load(xmlFile)
        
    local rotationPartNodepedalgazu = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.pedal_gazu#index"));
    if rotationPartNodepedalgazu ~= nil then
		self.rotationPartpedalgazu = {};
        self.rotationPartpedalgazu.node = rotationPartNodepedalgazu;
 
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.pedal_gazu#minRot"));
        self.rotationPartpedalgazu.minRot = {};
        self.rotationPartpedalgazu.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartpedalgazu.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartpedalgazu.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
 
        x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.pedal_gazu#maxRot"));
        self.rotationPartpedalgazu.maxRot = {};
        self.rotationPartpedalgazu.maxRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.rotationPartpedalgazu.maxRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.rotationPartpedalgazu.maxRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));
 
        self.rotationPartpedalgazu.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.pedal_gazu#rotTime"), 2)*1000;
        self.rotationPartpedalgazu.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.pedal_gazu#touchRotLimit"), 10));
    end;
        
    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 xUp, yUp, zUp = Utils.getVectorFromString(Utils.getNoNil(getXMLString(xmlFile, hydraulicName .. "#upVectors"),"0 1 0"));
        self.hydraulics[i].upVectors = {xUp, yUp, zUp};
 
        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;
        if self.hydraulics[i].translationPunch ~= nil then
            local bx, by, bz = getWorldTranslation(self.hydraulics[i].translationPunch);
            self.hydraulics[i].punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
        end;
	end;
    self.setHydraulicTime = 30;
    self.setHydraulicDirection = SpecializationUtil.callSpecializationsFunction("setHydraulicDirection");
    self.otworz = false
    self.zamknij = false
        
        
    local rotationLifter = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.Lifter#index"));
    self.Lifter = {};
    self.Lifter.node = rotationLifter;
 
    local rotationLifterArm = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.LifterArm#index"));
    self.LifterArm = {};
    self.LifterArm.node = rotationLifterArm;
 
    local rotationLifterBottom = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.LifterBottom#index"));
    self.bottomArm2 = {};
    self.bottomArm2.node = rotationLifterBottom;

	self.rollNodes = {};

    local rollNode = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.roll#index"));
    if rollNode ~= nil then
        local speed = 0.003*3;
        table.insert(self.rollNodes, {node=rollNode, speed=speed});
    end;
    local i = 0;
    while true do
        local key = string.format("vehicle.rolls.roll(%d)", i);
        if not hasXMLProperty(xmlFile, key) then
            break;
        end;
        local rollNode = Utils.indexToObject(self.components, getXMLString(xmlFile, key.."#index"));
        local speed = Utils.getNoNil(getXMLFloat(xmlFile, key.."#speed"), 0.003);
        if rollNode ~= nil then
            table.insert(self.rollNodes, {node=rollNode, speed=speed});
        end;
        i = i + 1;
end;
end;
function Anims:delete()
end;
 
function Anims:mouseEvent(posX, posY, isDown, isUp, button)
end;
 
function Anims:keyEvent(unicode, sym, modifier, isDown) 
end;
 
function Anims:update(dt)       
	if self.isMotorStarted then
        if Input.isKeyPressed(Input.KEY_w) or Input.isKeyPressed(Input.KEY_s) then
            self.rotationMaxpedalgazu = true;
        else
            self.rotationMaxpedalgazu = false;
		end;
		if self.rotationPartpedalgazu ~= nil then
            local x, y, z = getRotation(self.rotationPartpedalgazu.node);
            local rot = {x,y,z};
            local newRot = Utils.getMovedLimitedValues(rot, self.rotationPartpedalgazu.maxRot, self.rotationPartpedalgazu.minRot, 3, self.rotationPartpedalgazu.rotTime, dt, not self.rotationMaxpedalgazu);
            setRotation(self.rotationPartpedalgazu.node, unpack(newRot));
		end;            
		end;    
	    if self.isMotorStarted then
          for _, rollNode in pairs(self.rollNodes) do
          rotate(rollNode.node, 0, 0, -dt*rollNode.speed);
          end;
  
		if self.Lifter.node ~= nil and self.bottomArm2.node ~= nil then
            rBBArmX, rBBArmY, rBBArmZ = getRotation(self.bottomArm2.node);
            setRotation(self.Lifter.node, rBBArmX*1.5, 0, 0);
        end;
        if self.LifterArm.node ~= nil and self.bottomArm2.node ~= nil then
            setRotation(self.LifterArm.node, 0.05-rBBArmX*1.5, 0, 0);
        end;
        
		if self:getIsActive() then
            self.setHydraulicTime = 30;
        end;
 
 
        if self.setHydraulicTime > 0 then
            for k,v in pairs(self.hydraulics) do
                self:setHydraulicDirection(k);
            end;
            self.setHydraulicTime = self.setHydraulicTime - 1;
        end;
end;	

function Anims:updateTick(dt)    
end;    

function Anims:onEnter()
end;

function Anims:draw() 
end;    

function Anims:onLeave()
end;

function Anims:setHydraulicDirection(index)
    local hydraulic = self.hydraulics[index];
 
    if hydraulic.fixPoint ~= nil then
        local ax, ay, az = getWorldTranslation(hydraulic.node);
        local bx, by, bz = getWorldTranslation(hydraulic.fixPoint);
        local x, y, z = worldDirectionToLocal(getParent(hydraulic.node), bx-ax, by-ay, bz-az);
        local xUp, yUp, zUp = unpack(hydraulic.upVectors);
        setDirection(hydraulic.node, x, y, z, xUp, yUp, zUp);
        if hydraulic.punch ~= nil then
            local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
            setTranslation(hydraulic.punch, 0, 0, distance-hydraulic.punchDistance);
        end;
    end;
end;
 
function Anims:updateTick(dt)
    if self.backHydraulic ~= nil then               
        local x, y, z = getRotation(self.attacherJoints[1].bottomArm.rotationNode);
        setRotation(self.backHydraulic.rootArm, x, y, z);       
    end;            
end;
end;