-- Autor Lechu
-- fixes: Ziuta (17.04.2014)
 
Ursus914 = {};
 
function Ursus914.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Motorized, specializations);
end;
 
function Ursus914: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 rotationPartNode3 = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.rotationPart3#index"));
		if rotationPartNode3 ~= nil then
        self.rotationPart3 = {};
        self.rotationPart3.node = rotationPartNode3;

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

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

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

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

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

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

        self.rotationPart2.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPart2#rotTime"), 2)*1000;
        self.rotationPart2.touchRotLimit = Utils.degToRad(Utils.getNoNil(getXMLString(xmlFile, "vehicle.rotationPart2#touchRotLimit"), 10));
    end;
	self.rotationMax3Active = false;
	self.rotationMax2Active = false;  
		
    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");

    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 Ursus914:delete()
end;
 
function Ursus914:mouseEvent(posX, posY, isDown, isUp, button)
end;
 
function Ursus914:keyEvent(unicode, sym, modifier, isDown) 
end;
 
function Ursus914: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;
	end;	
	if self:getIsActive() then
		inputAxisY = InputBinding.getAnalogInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE);
		if InputBinding.isAxisZero(inputAxisY) then
			inputAxisY = InputBinding.getDigitalInputAxis(InputBinding.AXIS_MOVE_FORWARD_VEHICLE);
		end;
		if self.isEntered ~= nil then
			if (self.movingDirection*self.lastSpeed*(-inputAxisY)) < -0.001 then		
				self.rotationMax3Active = true;
				self.rotationMax2Active = true;
			else
				self.rotationMax3Active = false;
				self.rotationMax2Active = false;
			end;
		end;
		if self.rotationPart3 ~= nil then
			local x, y, z = getRotation(self.rotationPart3.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPart3.maxRot, self.rotationPart3.minRot, 3, self.rotationPart3.rotTime, dt, not self.rotationMax3Active);
			setRotation(self.rotationPart3.node, unpack(newRot));
		end;
		if self.rotationPart2 ~= nil then
			local x, y, z = getRotation(self.rotationPart2.node);
			local rot = {x,y,z};
			local newRot = Utils.getMovedLimitedValues(rot, self.rotationPart2.maxRot, self.rotationPart2.minRot, 3, self.rotationPart2.rotTime, dt, not self.rotationMax2Active);
			setRotation(self.rotationPart2.node, unpack(newRot));
		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;
		if self.isEntered then
			if InputBinding.hasEvent(InputBinding.drzwi_lewe) then
				if self.animationParts[1].clipEndTime then
					self:setAnimationTime(1, self.animationParts[1].offSet);
				elseif self.animationParts[1].clipStartTime then
						self:setAnimationTime(1, self.animationParts[1].animDuration);
					 end;
				end; 
				if InputBinding.hasEvent(InputBinding.drzwi_prawe) then
					if self.animationParts[2].clipEndTime then
						self:setAnimationTime(2, self.animationParts[2].offSet);
					 elseif self.animationParts[2].clipStartTime then
							self:setAnimationTime(2, self.animationParts[2].animDuration);
					end;
				end; 
				if InputBinding.isPressed(InputBinding.SZYBA_UP) then
					self:setAnimationTime(3, self.animationParts[3].currentPosition+(self.animationParts[3].offSet+dt), false);
				elseif InputBinding.isPressed(InputBinding.SZYBA_DOWN) then
					self:setAnimationTime(3, self.animationParts[3].currentPosition-(self.animationParts[3].offSet+dt), false);
				end;
				if InputBinding.isPressed(InputBinding.DACH_UP) then
					self:setAnimationTime(4, self.animationParts[4].currentPosition+(self.animationParts[3].offSet+dt), false);
				elseif InputBinding.isPressed(InputBinding.DACH_DOWN) then
					self:setAnimationTime(4, self.animationParts[4].currentPosition-(self.animationParts[3].offSet+dt), false);
				end;
			end;
		end
	end
	
function Ursus914:updateTick(dt)    
end;    

function Ursus914:onEnter()
end;

function Ursus914:draw() 
end;    

function Ursus914:onLeave()
end;

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