Joystick = {};

Joystick.LEFT = "LEFT";
Joystick.RIGHT = "RIGHT";

function Joystick.initSpecialization(specializations)
    Vehicle.registerJointType("joystick");
end;

function Joystick.prerequisitesPresent(specializations)
    return true;
end;

function Joystick:load(xmlFile)

	self.balancier = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.balancier"), 1);
	self.tourelle = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.tourelle"), 1);
	self.fleche = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.fleche"), 1);
	self.godet = Utils.getNoNil(getXMLFloat(xmlFile, "vehicle.godet"), 1);

	self.updateDirtyObject = SpecializationUtil.callSpecializationsFunction("updateDirtyObject");
	
	self.joysticks = {};
	self.joysticks["LIMIT"] = Utils.degToRad(getXMLFloat(xmlFile, "vehicle.joystick.joysticks#rotLimit"));
	
	self.joysticks["RIGHT"] = {};
	self.joysticks["RIGHT"].node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.joystick.joysticks#right"));
	self.joysticks["RIGHT"].startRot = {getRotation(self.joysticks["RIGHT"].node)};
	self.joysticks["RIGHT"].lastRot = {0, 0};
	
	self.joysticks["LEFT"] = {};
	self.joysticks["LEFT"].node = Utils.indexToObject(self.components, getXMLString(xmlFile, "vehicle.joystick.joysticks#left"));
	self.joysticks["LEFT"].startRot = {getRotation(self.joysticks["LEFT"].node)};
	self.joysticks["LEFT"].lastRot = {0, 0};
	
	self.rightStickDirtyFlag = self:getNextDirtyFlag();
	self.leftStickDirtyFlag = self:getNextDirtyFlag();
end;

function Joystick:delete()
end;

function Joystick:readStream(streamId, connection)
end;

function Joystick:writeStream(streamId, connection)
end;

function Joystick:readUpdateStream(streamId, timestamp, connection)
	if streamReadBool(streamId) then
		self.joysticks["LEFT"].lastRot[1] = streamReadFloat32(streamId);
		self.joysticks["LEFT"].lastRot[2] = streamReadFloat32(streamId);
		self:updateDirtyObject(Joystick.LEFT, self.joysticks["LEFT"].lastRot[1], self.joysticks["LEFT"].lastRot[2]);
		
		if not connection:getIsServer() then
			self:raiseDirtyFlags(self.leftStickDirtyFlag);
		end;
	end;
	
	if streamReadBool(streamId) then
		self.joysticks["RIGHT"].lastRot[1] = streamReadFloat32(streamId);
		self.joysticks["RIGHT"].lastRot[2] = streamReadFloat32(streamId);
		self:updateDirtyObject(Joystick.RIGHT, self.joysticks["RIGHT"].lastRot[1], self.joysticks["RIGHT"].lastRot[2]);
		
		if not connection:getIsServer() then
			self:raiseDirtyFlags(self.rightStickDirtyFlag);
		end;
	end;
end;
   
function Joystick:writeUpdateStream(streamId, connection, dirtyMask)

	local s = (connection:getIsServer() or connection ~= self.owner); -- either we are on the client, or the target connection is not the owner
	
	if bitAND(dirtyMask, self.leftStickDirtyFlag) ~= 0 and s then
		streamWriteBool(streamId, true);
		streamWriteFloat32(streamId, self.joysticks["LEFT"].lastRot[1]);
		streamWriteFloat32(streamId, self.joysticks["LEFT"].lastRot[2]);
	else
		streamWriteBool(streamId, false);
	end;
	
	if bitAND(dirtyMask, self.rightStickDirtyFlag) ~= 0 and s then
		streamWriteBool(streamId, true);
		streamWriteFloat32(streamId, self.joysticks["RIGHT"].lastRot[1]);
		streamWriteFloat32(streamId, self.joysticks["RIGHT"].lastRot[2]);
	else
		streamWriteBool(streamId, false);
	end;
end;

function Joystick:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
end;

function Joystick:getSaveAttributesAndNodes(nodeIdent)
end;

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

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

function Joystick:update(dt)

	if self:getIsActive() then		
		if self:getIsActiveForInput(false) and self.isClient then
		
			local armL, armTypeL = InputBinding.getInputAxis(self.movingTools[self.balancier].axisActionIndex);
			local toolL, toolTypeL = InputBinding.getInputAxis(self.movingTools[self.tourelle].axisActionIndex);
			armL = -armL;
			if armTypeL == InputBinding.INPUTTYPE_MOUSE_AXIS then
				armL = math.max(math.min(armL, 1), -1);
			end;
			if toolTypeL == InputBinding.INPUTTYPE_MOUSE_AXIS then
				toolL = math.max(math.min(toolL, 1), -1);
			end;
			local newArmRot = self.joysticks["LEFT"].startRot[1] + (self.joysticks["LIMIT"] * -armL);
			local newToolRot = self.joysticks["LEFT"].startRot[3] + (self.joysticks["LIMIT"] * toolL);
			if (self.joysticks["LEFT"].lastRot[1] ~= newArmRot or self.joysticks["LEFT"].lastRot[2] ~= newToolRot) then
				self.joysticks["LEFT"].lastRot[1] = newArmRot;
				self.joysticks["LEFT"].lastRot[2] = newToolRot;
				
				self:updateDirtyObject(Joystick.LEFT, self.joysticks["LEFT"].lastRot[1], self.joysticks["LEFT"].lastRot[2]);
				self:raiseDirtyFlags(self.leftStickDirtyFlag); -- update server
			end;

			local armR, armTypeR = InputBinding.getInputAxis(self.movingTools[self.fleche].axisActionIndex);
			local toolR, toolTypeR = InputBinding.getInputAxis(self.movingTools[self.godet].axisActionIndex);
			armR = -armR;
			if armTypeR == InputBinding.INPUTTYPE_MOUSE_AXIS then
				armR = math.max(math.min(armR, 1), -1);
			end;
			if toolTypeR == InputBinding.INPUTTYPE_MOUSE_AXIS then
				toolR = math.max(math.min(toolR, 1), -1);
			end;
			local newArmRot = self.joysticks["RIGHT"].startRot[1] + (self.joysticks["LIMIT"] * armR);
			local newToolRot = self.joysticks["RIGHT"].startRot[3] + (self.joysticks["LIMIT"] * toolR);
			if (self.joysticks["RIGHT"].lastRot[1] ~= newArmRot or self.joysticks["RIGHT"].lastRot[2] ~= newToolRot) then
				self.joysticks["RIGHT"].lastRot[1] = newArmRot;
				self.joysticks["RIGHT"].lastRot[2] = newToolRot;
				
				self:updateDirtyObject(Joystick.RIGHT, self.joysticks["RIGHT"].lastRot[1], self.joysticks["RIGHT"].lastRot[2]);
				self:raiseDirtyFlags(self.rightStickDirtyFlag); -- update server
			end;
		end;
	end;
end;

function Joystick:updateTick(dt)
end;

function Joystick:draw()
end;

function Joystick:onEnter()
end;

function Joystick:onLeave()
end;

function Joystick:attachImplement()
end;

function Joystick:detachImplement()
end;

function Joystick:updateDirtyObject(t, x, z)
	if t == Joystick.RIGHT then
		self.ikChainsById["rightArm"].isDirty = true;
		self.ikChainsById["rubberRight"].isDirty = true;
	else -- LEFT
		self.ikChainsById["leftArm"].isDirty = true;
		self.ikChainsById["rubberLeft"].isDirty = true;
	end;
	
	setRotation(self.joysticks[t].node, x, 0, z);
end;

function Joystick:quickHitchAnimation(dir)
end;

function Joystick:getPtoRpm(oldFunc)
end;

function Joystick:getDoConsumePtoPower(oldFunc)
end;



