-- Wald_Kranzange
-- Specialization for Wald_Kranzange mod
--
-- @author  Tobias F. (John Deere 6930, 1. LS-Modschmiede)

Wald_Kranzange = {};

function Wald_Kranzange.prerequisitesPresent(specializations)
    return SpecializationUtil.hasSpecialization(Attachable, specializations);
end;

function Wald_Kranzange:load(xmlFile)

	local Collision1 = {};
	Collision1.collision = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.collision1#collision"));
	Collision1.collisionAttacher = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.collision1#collsionAttacher"));
	Collision1.armAttacher = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.collision1#armAttacher"));
	Collision1.index = 0;
	self.Collision1Base = Collision1;
	
	local Collision2 = {};
	Collision2.collision = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.collision2#collision"));
	Collision2.collisionAttacher = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.collision2#collsionAttacher"));
	Collision2.armAttacher = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.collision2#armAttacher"));
	Collision2.index = 0;
	self.Collision2Base = Collision2;

	self.collisions = true;


	local Rot1Node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.Rot1#index"));
    if Rot1Node ~= nil then
        self.Rot1 = {};
        self.Rot1.node = Rot1Node;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Rot1#minRot"));
        self.Rot1.minRot = {};
        self.Rot1.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.Rot1.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.Rot1.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

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

        self.Rot1.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Rot1#rotTime"), 2)*1000;
    end;
	local Rot2Node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.Rot2#index"));
    if Rot2Node ~= nil then
        self.Rot2 = {};
        self.Rot2.node = Rot2Node;
        local x, y, z = Utils.getVectorFromString(getXMLString(xmlFile, "vehicle.Rot2#minRot"));
        self.Rot2.minRot = {};
        self.Rot2.minRot[1] = Utils.degToRad(Utils.getNoNil(x, 0));
        self.Rot2.minRot[2] = Utils.degToRad(Utils.getNoNil(y, 0));
        self.Rot2.minRot[3] = Utils.degToRad(Utils.getNoNil(z, 0));

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

        self.Rot2.rotTime = Utils.getNoNil(getXMLString(xmlFile, "vehicle.Rot2#rotTime"), 2)*1000;
    end;
	self.hydraulic = {};
	self.hydraulic.node = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.hydraulic#indexHydraulic"));
	self.hydraulic.punch = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.hydraulic#indexPunch"));
	self.hydraulic.translationPunch = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.hydraulic#translationPunch"));
	local ax, ay, az = getWorldTranslation(self.hydraulic.punch);
    local bx, by, bz = getWorldTranslation(self.hydraulic.translationPunch);
    self.hydraulic.punchDistance = Utils.vector3Length(ax-bx, ay-by, az-bz);
	self.hydraulicPoint = Utils.indexToObject(self.rootNode, getXMLString(xmlFile, "vehicle.hydraulic#hydraulicPoint"));
	self.keys = {};
	self.keysDesc = {};
    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.keysDesc[inputName] = getXMLString(xmlFile, baseName.. "#keyDesc");
        i = i+1;
    end;
end;

function Wald_Kranzange:delete()
end;

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

function Wald_Kranzange:keyEvent(unicode, sym, modifier, isDown)
end;

function Wald_Kranzange:update(dt)
		local CollisionBase1 = self.Collision1Base;
		setJointFrame(CollisionBase1.index, 0, CollisionBase1.armAttacher);
		local CollisionBase2 = self.Collision2Base;
		setJointFrame(CollisionBase2.index, 0, CollisionBase2.armAttacher);

	    if self.collisions then
			self.collisions = false;
			local constr = JointConstructor:new();
			constr:setActors(self.rootNode, self.Collision1Base.collision);
			constr:setJointTransforms(self.Collision1Base.armAttacher, self.Collision1Base.collisionAttacher);
			for i=1, 3 do
				constr:setRotationLimit(i-1, 0, 0, 0);
				constr:setTranslationLimit(i-1, true, 0, 0);
			end;
			self.Collision1Base.index = constr:finalize();

			local constr2 = JointConstructor:new();
			constr2:setActors(self.rootNode, self.Collision2Base.collision);
			constr2:setJointTransforms(self.Collision2Base.armAttacher, self.Collision2Base.collisionAttacher);
			for i=1, 3 do
				constr2:setRotationLimit(i-1, 0, 0, 0);
				constr2:setTranslationLimit(i-1, true, 0, 0);
			end;
			self.Collision2Base.index = constr2:finalize();
		end;

	if self.attacherVehicle ~= nil then
	    if self:getIsActiveForInput() then
			if Input.isKeyPressed(self.keys.OPEN_PLIERS) then
				local x, y, z = getRotation(self.Rot1.node);
		        local rot = {x,y,z};
		        local newRot = Utils.getMovedLimitedValues(rot, self.Rot1.maxRot, self.Rot1.minRot, 3, self.Rot1.rotTime*2, dt, true);
			    setRotation(self.Rot1.node, unpack(newRot));
				local x, y, z = getRotation(self.Rot2.node);
		        local rot = {x,y,z};
		        local newRot = Utils.getMovedLimitedValues(rot, self.Rot2.maxRot, self.Rot2.minRot, 3, self.Rot2.rotTime*2, dt, true);
			    setRotation(self.Rot2.node, unpack(newRot));
		    end;

			if Input.isKeyPressed(self.keys.CLOSE_PLIERS) then
				local x, y, z = getRotation(self.Rot1.node);
		        local rot = {x,y,z};
		        local newRot = Utils.getMovedLimitedValues(rot, self.Rot1.maxRot, self.Rot1.minRot, 3, self.Rot1.rotTime*2, dt, false);
			    setRotation(self.Rot1.node, unpack(newRot));
				local x, y, z = getRotation(self.Rot2.node);
		        local rot = {x,y,z};
		        local newRot = Utils.getMovedLimitedValues(rot, self.Rot2.maxRot, self.Rot2.minRot, 3, self.Rot2.rotTime*2, dt, false);
			    setRotation(self.Rot2.node, unpack(newRot));
		    end;
		end;
	end;
	if self.hydraulic ~= nil then
		local ax, ay, az = getWorldTranslation(self.hydraulic.node);
		local bx, by, bz = getWorldTranslation(self.hydraulicPoint);
		local x, y, z = worldDirectionToLocal(getParent(self.hydraulic.node), bx-ax, by-ay, bz-az);
		setDirection(self.hydraulic.node, x*-1, y*-1, z*-1, 0, 1, 0);
		if self.hydraulic.punch ~= nil then
			local distance = Utils.vector3Length(ax-bx, ay-by, az-bz);
			setTranslation(self.hydraulic.punch, 0, 0, (distance-self.hydraulic.punchDistance)*-1);
		end;
	end;
end;


function Wald_Kranzange:draw()
	g_currentMission:addExtraPrintText("Taste: " .. self.keysDesc.OPEN_PLIERS .. "Zange oeffnen");
	g_currentMission:addExtraPrintText("Taste: " .. self.keysDesc.CLOSE_PLIERS .. "Zange schliesen");
end;