--
-- AloeConsole
-- Specialization for attachable Aloe console
--
-- @author  Stefan Maurus	
-- @date  2015-02-28

-- Copyright © MAurUS, www.stefanmaurus.de

AloeConsole = {};

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

function AloeConsole:load(xmlFile)
	self.attachConsole = SpecializationUtil.callSpecializationsFunction("attachConsole"); 
	self.detachConsole = SpecializationUtil.callSpecializationsFunction("detachConsole"); 
	self.addFrontloaderAttacherJoint = SpecializationUtil.callSpecializationsFunction("addFrontloaderAttacherJoint"); 
	self.setConsoleAttachMode = SpecializationUtil.callSpecializationsFunction("setConsoleAttachMode"); 
	
	self.readyToInstallConsole = false;
	self.readyToUninstallConsole = false;	
	
	self.consoleID = nil; -- self table of the console
	self.consoleID2 = -1; --id of console

	self.consoleInstalled = false; -- user pressed button
	self.consoleIsLinked = false; -- console linked
	self.consoleAttachMode = false; -- positionate console and lcs
	self.consolePositionated = false; -- position saved
	
	self.buttonIsPressed = 0; --witch button is currently pressed
	
	self.tractorID = 0;
	for i = 1, table.getn(g_currentMission.vehicles) do
		if SpecializationUtil.hasSpecialization(AloeConsole,  g_currentMission.vehicles[i].specializations) then
			self.tractorID = g_currentMission.vehicles[i].tractorID + 1;
		end;
	end;
	
	self.attachedFrontloader = -1;
end;

function AloeConsole:delete()
	self:detachConsole(true);
end;

function AloeConsole:mouseEvent(posX, posY, isDown, isUp, button)
	if isDown and self.consoleID ~= nil then
		for i = 1, table.getn(self.consoleID.controlButtons) do
			if posX > self.consoleID.controlButtons[i].x and posX < self.consoleID.controlButtons[i].x1 and posY > self.consoleID.controlButtons[i].y and posY < self.consoleID.controlButtons[i].y1 then
				self.buttonIsPressed = i;
			end;
		end;
		self.consoleID.mouseEvent(self.consoleID, posX, posY, isDown, isUp, button);
	else
		self.buttonIsPressed = 0;
	end;
	
	if self.consoleID ~= nil then
		self.consoleID.mouseEvent(self.consoleID, posX, posY, isDown, isUp, button);
	end;
end;

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

function AloeConsole:loadFromAttributesAndNodes(xmlFile, key, resetVehicles)
	self.tractorID = Utils.getNoNil(getXMLFloat(xmlFile, key.."#tractorID"), self.tractorID);
	self.attachedFrontloader = Utils.getNoNil(getXMLFloat(xmlFile, key.."#attachedFrontloader"), self.attachedFrontloader);
	
	return BaseMission.VEHICLE_LOAD_OK;
end;

function AloeConsole:getSaveAttributesAndNodes(nodeIdent)
	local attributes = 'tractorID="'..self.tractorID..'" attachedFrontloader="'..self.attachedFrontloader..'"';
	return attributes, nil;
end;

function AloeConsole:readStream(streamId, connection)
	self.attachedFrontloader = streamReadInt32(streamId);
	self.tractorID = streamReadInt32(streamId);
end;

function AloeConsole:writeStream(streamId, connection)
	streamWriteInt32(streamId, self.attachedFrontloader); 
	streamWriteInt32(streamId, self.tractorID); 
end;

function AloeConsole:detachImplement(implementIndex)
	if self.attachedImplements[implementIndex].object.frontloaderID ~= nil then
		self.attachedFrontloader = -1;
	end;
end;

function AloeConsole:attachImplement(implement)
	if implement.object.frontloaderID ~= nil then
		self.attachedFrontloader = implement.object.frontloaderID;
	end;
end;

function AloeConsole:setConsoleAttachMode(bool, cursor, noEventSend)
	self.consoleAttachMode = bool;
	if not bool and cursor then
		InputBinding.setShowMouseCursor(false);	
	end;
	SetConsoleAttachModeEvent.sendEvent(self, bool, noEventSend);
end;

function AloeConsole:attachConsole(consoleID, noEventSend)
	if consoleID == nil then
		self.consoleInstalled = true;
		self.readyToInstallConsole = false;
		self:setConsoleAttachMode(true, true);
		SetAttachConsoleEvent.sendEvent(self, noEventSend);
	else
		self.consoleID = consoleID;
		self.consoleInstalled = true;
		self.readyToInstallConsole = false;
		self:setConsoleAttachMode(false, false);		
		self.consoleIsLinked = true;
		self.consolePositionated = true;

		consoleID.consoleAttachedSelf = self;
		
		link(self.components[1].node, consoleID.aloeConsole.index);
		
		if self.removeWashableNode ~= nil then
			self:addWashableNode(self.consoleID.aloeConsole.index);
			consoleID:removeWashableNode(self.consoleID.aloeConsole.index);
		end;
		
		for i = 1, table.getn(self.attacherJoints) do
			if i <= table.getn(self.attacherJoints) then
				if self.attacherJoints[i].jointType == Vehicle.jointTypeNameToInt["attachableFrontloader"] then
					if self:getImplementIndexByJointDescIndex(i) ~= nil then
						self:detachImplement(self:getImplementIndexByJointDescIndex(i), noEventSend);
					end;
					
					table.remove(self.attacherJoints, i);
					i = i - 1;
				end;
			end;
		end;
		
		for i = 1, table.getn(self.schemaOverlay.attacherJoints) do
			if self.schemaOverlay.attacherJoints[i].y == 0.4 and self.schemaOverlay.attacherJoints[i].x == 0 and i == table.getn(self.schemaOverlay.attacherJoints) then
				table.remove(self.schemaOverlay.attacherJoints, i);	
				break;
			end;
		end;		
		
		setVisibility(self.consoleID.aloeConsole.index, true);
		setVisibility(self.consoleID.aloeConsole.indexDetached, false);		
		
		self.consoleID:setConsoleAttributes(consoleID.consolePositionY, consoleID.consolePositionZ, consoleID.consolePositionR, consoleID.lcsPositionX, consoleID.lcsPositionY, consoleID.lcsPositionZ, consoleID.lcsPositionR);

		self:addFrontloaderAttacherJoint(noEventSend);
	end;
	
end;

function AloeConsole:detachConsole(noEventSend)
	if self.consoleID ~= nil then
		for i = 1, table.getn(self.attacherJoints) do
			if i <= table.getn(self.attacherJoints) then
				if self.attacherJoints[i].jointType == Vehicle.jointTypeNameToInt["attachableFrontloader"] then
					if self:getImplementIndexByJointDescIndex(i) ~= nil then
						self:detachImplement(self:getImplementIndexByJointDescIndex(i), noEventSend);
					end;
					
					table.remove(self.attacherJoints, i);
					i = i - 1;
				end;
			end;
		end;
		
		for i = 1, table.getn(self.schemaOverlay.attacherJoints) do
			if self.schemaOverlay.attacherJoints[i].y == 0.4 and self.schemaOverlay.attacherJoints[i].x == 0 and i == table.getn(self.schemaOverlay.attacherJoints) then
				table.remove(self.schemaOverlay.attacherJoints, i);	
				break;
			end;
		end;
	
		self.consoleInstalled = false;
		self.readyToInstallConsole = true;
		self.readyToUninstallConsole = false;
		self:setConsoleAttachMode(false, false);		
		self.consoleIsLinked = false;
		self.consolePositionated = false;
		self.consoleID.consoleAttachedSelf = nil;
		
		link(self.consoleID.aloeConsole.detachNode, self.consoleID.aloeConsole.index);
		
		if self.removeWashableNode ~= nil then
			self.consoleID:addWashableNode(self.consoleID.aloeConsole.index);
			self:removeWashableNode(self.consoleID.aloeConsole.index);
		end;
		
		setTranslation(self.consoleID.aloeConsole.index, 0, 0, 0);
		setVisibility(self.consoleID.aloeConsole.index, false);
		setVisibility(self.consoleID.aloeConsole.indexDetached, true);
		setTranslation(self.consoleID.aloeConsole.LCS, 0, 0, 0);
		setRotation(self.consoleID.aloeConsole.LCS, 0, 0, 0);

		self.consoleID.consoleAttachedTo = -1;
		self.consoleID = nil;
		
		SetDetachConsoleEvent.sendEvent(self, noEventSend);	
	end;
end;

function AloeConsole:update(dt)	
	if self.attachedFrontloader > -1 and self.consolePositionated then
		local isAttached = false;
		for i, v in ipairs(self.attachedImplements) do
			if v.object.frontloaderID == self.attachedFrontloader then
				isAttached = true;
			end;
		end;
		
		if not isAttached then
			for i = 1, table.getn(g_currentMission.vehicles) do
				if g_currentMission.vehicles[i].frontloaderID == self.attachedFrontloader then
					self:attachImplement(g_currentMission.vehicles[i], 1, table.getn(self.attacherJoints), true);	
				end;
			end;
		end;
	end;

	if self.readyToInstallConsole and self.consoleID == nil then
		if self:getIsActiveForInput() then
			if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA2) then
				local allowsAttaching = true;
				for i = 1, table.getn(self.attacherJoints) do
					if self.attacherJoints[i].jointType == Vehicle.jointTypeNameToInt["attachableFrontloader"] then
						allowsAttaching = false;
					end;
				end;
				
				if allowsAttaching then
					self:attachConsole(nil);
				end;
			end;	
		end;
	end;
	
	if self.readyToUninstallConsole and self.consoleID ~= nil and table.getn(self.attachedImplements) == 0 then
		if self:getIsActiveForInput(false) then
			if InputBinding.hasEvent(InputBinding.CONSOLE_DETACH) then
				local allowsDetaching = false;
				for i = 1, table.getn(self.attacherJoints) do
					if self.attacherJoints[i].jointType == Vehicle.jointTypeNameToInt["attachableFrontloader"] then
						if self.attacherJoints[i].jointIndex == 0 then
							allowsDetaching = true;
						end;
					end;
				end;
				
				if allowsDetaching then
					self:detachConsole();
				end;
			end;	
		end;
	end;
	
	if self:getIsActiveForInput(true) then
		if InputBinding.isPressed(InputBinding.CROUCH) and self.consoleAttachMode then
			InputBinding.setShowMouseCursor(true);
		elseif not InputBinding.isPressed(InputBinding.CROUCH) and self.consoleAttachMode then
			InputBinding.setShowMouseCursor(false);
		end;	
	end;
	
	if self.consoleAttachMode and self.consoleID ~= nil then
		if InputBinding.hasEvent(InputBinding.IMPLEMENT_EXTRA) then
			if not getVisibility(self.consoleID.aloeConsole.helpMesh[1]) and not getVisibility(self.consoleID.aloeConsole.helpMesh[2]) then
				setVisibility(self.consoleID.aloeConsole.helpMesh[1], true);
				setVisibility(self.consoleID.aloeConsole.helpMesh[2], false);
			elseif getVisibility(self.consoleID.aloeConsole.helpMesh[1]) and not getVisibility(self.consoleID.aloeConsole.helpMesh[2]) then
				setVisibility(self.consoleID.aloeConsole.helpMesh[1], false);
				setVisibility(self.consoleID.aloeConsole.helpMesh[2], true);
			elseif not getVisibility(self.consoleID.aloeConsole.helpMesh[1]) and getVisibility(self.consoleID.aloeConsole.helpMesh[2]) then
				setVisibility(self.consoleID.aloeConsole.helpMesh[1], false);
				setVisibility(self.consoleID.aloeConsole.helpMesh[2], false);
			end;
		end;
	elseif self.consoleID ~= nil and not self.consoleAttachMode then
		setVisibility(self.consoleID.aloeConsole.helpMesh[1], false);
		setVisibility(self.consoleID.aloeConsole.helpMesh[2], false);
	end;
	
	
	if self.consoleAttachMode and not self.consoleIsLinked and self.consoleID ~= nil then
		link(self.components[1].node, self.consoleID.aloeConsole.index);
		setVisibility(self.consoleID.aloeConsole.index, true);
		setVisibility(self.consoleID.aloeConsole.indexDetached, false);			
		self.consoleID:setConsoleAttributes(self.consoleID.consolePositionY, self.consoleID.consolePositionZ, self.consoleID.consolePositionR, self.consoleID.lcsPositionX, self.consoleID.lcsPositionY, self.consoleID.lcsPositionZ, self.consoleID.lcsPositionR);
		self.consoleIsLinked = true;
	end;
	
	--set position of console
	if self.consoleAttachMode and self.consoleIsLinked and  self.consoleID ~= nil and not self.consolePositionated and self.isClient then
		local y, z, r = self.consoleID.consolePositionY, self.consoleID.consolePositionZ, self.consoleID.consolePositionR;
		local x1, y1, z1, n = self.consoleID.lcsPositionX, self.consoleID.lcsPositionY, self.consoleID.lcsPositionZ, self.consoleID.lcsPositionR;	

		if self.buttonIsPressed == 8 then
			y = y + dt / 3000;
		end;	

		if self.buttonIsPressed == 2 then
			y = y - dt / 3000;			
		end;	

		if self.buttonIsPressed == 1 then
			z = z + dt / 3000;
		end;	

		if self.buttonIsPressed == 3 then
			z = z - dt / 3000;
		end;	
		
		if self.buttonIsPressed == 5 then
			self.consolePositionated = true;
			self.buttonIsPressed = 0;
		end;	

		if InputBinding.hasEvent(InputBinding.CONSOLE_ROTATE180) then
			if r == 0 then
				r = 180;
			else
				r = 0;
			end;
		end;
		
		if self.buttonIsPressed > 0 or InputBinding.hasEvent(InputBinding.CONSOLE_ROTATE180) then
			self.consoleID:setConsoleAttributes(y, z, r, x1, y1, z1, n);
		end;
	end;
	
	--set position of lcs
	if self.consoleAttachMode and self.consoleIsLinked and  self.consoleID ~= nil and self.consolePositionated and self.isClient then
		local y1, z1, r = self.consoleID.consolePositionY, self.consoleID.consolePositionZ, self.consoleID.consolePositionR;
		local x, y, z, n = self.consoleID.lcsPositionX, self.consoleID.lcsPositionY, self.consoleID.lcsPositionZ, self.consoleID.lcsPositionR;	

		if self.buttonIsPressed == 4 then
			x = x + dt / 3000;
		end;	

		if self.buttonIsPressed == 6 then
			x = x - dt / 3000;
		end;	

		if self.buttonIsPressed == 8 then
			y = y + dt / 3000;
		end;	

		if self.buttonIsPressed == 2 then
			y = y - dt / 3000;
		end;	

		if self.buttonIsPressed == 1 then
			z = z + dt / 3000;
		end;	

		if self.buttonIsPressed == 3 then
			z = z - dt / 3000;
		end;	
		
		if self.buttonIsPressed == 9 then
			n = n + dt / 20;
		end;	

		if self.buttonIsPressed == 7 then
			n = n - dt / 20;
		end;

		if self.buttonIsPressed == 5 then
			self:setConsoleAttachMode(false, true);			
			self:addFrontloaderAttacherJoint();
			self.buttonIsPressed = 0;
		end;		
		
		self.consoleID:setConsoleAttributes(y1, z1, r, x, y, z, n);
	end;
end;

function AloeConsole:updateTick(dt)
end;

function AloeConsole:draw() 
--[[
	for i = 1, table.getn(self.attacherJoints) do
		if self.attacherJoints[i].jointType == Vehicle.jointTypeNameToInt["attachableFrontloader"] then
			renderText(0.2,0.2+0.02*i,0.015, i..".: fl attacher");
		end;
	end;

	renderText(0.2,0.1,0.015, "self.consoleInstalled: "..tostring(self.consoleInstalled));
	renderText(0.2,0.12,0.015, "self.consoleIsLinked: "..tostring(self.consoleIsLinked));
	renderText(0.2,0.14,0.015, "self.consoleAttachMode: "..tostring(self.consoleAttachMode));
	renderText(0.2,0.16,0.015, "self.consolePositionated: "..tostring(self.consolePositionated));	
	renderText(0.2,0.18,0.015, "self.readyToInstallConsole: "..tostring(self.readyToInstallConsole));
	renderText(0.2,0.20,0.015, "self.readyToUninstallConsole: "..tostring(self.readyToUninstallConsole));	
]]
	if self.consoleID ~= nil and self.consoleAttachMode then
		if not self.consolePositionated then
			self.consoleID.controlsHUD.overlay_console:render();	
		else
			self.consoleID.controlsHUD.overlay_lcs:render();	
		end;
		renderText(self.consoleID.controlsHUD.xPos,self.consoleID.controlsHUD.yPos-0.03,0.017,self.consoleID.controlsHUD.helpText);
	end;
end;

function AloeConsole:addFrontloaderAttacherJoint(noEventSend)
	if self.consoleID ~= nil then
		AddAttacherJointEvent.sendEvent(self, noEventSend);	
		local object = self.consoleID.aloeConsole.attacherJoint;
		setRotation(object, math.rad(90), math.rad(-85.52899933), math.rad(-90)); --don't know why its rotating
		if object ~= nil then
			local entry = {};
			entry.jointTransform = object;
			entry.jointOrigRot = { getRotation(entry.jointTransform) };
			entry.jointOrigTrans = { getTranslation(entry.jointTransform) };
			entry.jointPositionOffset = {0,0,0};

			entry.jointType = Vehicle.jointTypeNameToInt["attachableFrontloader"];

			entry.allowsJointLimitMovement = false;
			entry.allowsLowering = false;

			entry.maxRotDistanceToGround = 0;
			entry.minRotDistanceToGround = 0;
			entry.maxRotRotationOffset = 0;
			entry.minRotRotationOffset = 0;

			entry.maxRotLimit = {0,0,0};
			entry.minRotLimit = {0,0,0};
			entry.maxTransLimit = {0,0,0};
			entry.minTransLimit = {0,0,0};

			entry.moveTime = 0;

			entry.enableCollision = false;
			entry.ptoActive = false;
			entry.canTurnOnImplement	= true;

			entry.rootNode = self.components[1].node;
			entry.jointIndex = 0;

			entry.transLimitDamping = {0,0,0};
			entry.transLimitSpring = {0,0,0};
			entry.rotLimitDamping = {0,0,0};
			entry.rotLimitSpring = {0,0,0};

			table.insert(self.attacherJoints, entry);
		end;

		local entry = {};
		entry.x = 0;
		entry.y = 0.4;
		entry.invertX = true;
		entry.rotation = 0;
		table.insert(self.schemaOverlay.attacherJoints, entry);
	end;
end;

SetAttachConsoleEvent = {};
SetAttachConsoleEvent_mt = Class(SetAttachConsoleEvent, Event);

InitEventClass(SetAttachConsoleEvent, "SetAttachConsoleEvent");

function SetAttachConsoleEvent:emptyNew()
    local self = Event:new(SetAttachConsoleEvent_mt);
    self.className="SetAttachConsoleEvent";
    return self;
end;

function SetAttachConsoleEvent:new(vehicle)
    local self = SetAttachConsoleEvent:emptyNew()
    self.vehicle = vehicle;
    return self;
end;

function SetAttachConsoleEvent:readStream(streamId, connection)
    self.vehicle = networkGetObject(streamReadInt32(streamId));

	if self.vehicle ~= nil then
		self.vehicle:attachConsole(nil, true);
	end;
	
	if not connection:getIsServer() then
        g_server:broadcastEvent(SetAttachConsoleEvent:new(self.vehicle), nil, connection, self.vehicle);
    end;
end;

function SetAttachConsoleEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
end;

function SetAttachConsoleEvent.sendEvent(vehicle, noEventSend)
	if not noEventSend then
		if g_server ~= nil then
			g_server:broadcastEvent(SetAttachConsoleEvent:new(vehicle), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetAttachConsoleEvent:new(vehicle));
		end;
	end;
end;

SetDetachConsoleEvent = {};
SetDetachConsoleEvent_mt = Class(SetDetachConsoleEvent, Event);

InitEventClass(SetDetachConsoleEvent, "SetDetachConsoleEvent");

function SetDetachConsoleEvent:emptyNew()
    local self = Event:new(SetDetachConsoleEvent_mt);
    self.className="SetDetachConsoleEvent";
    return self;
end;

function SetDetachConsoleEvent:new(vehicle)
    local self = SetDetachConsoleEvent:emptyNew()
    self.vehicle = vehicle;
    return self;
end;

function SetDetachConsoleEvent:readStream(streamId, connection)
    self.vehicle = networkGetObject(streamReadInt32(streamId));

	if self.vehicle ~= nil then
		self.vehicle:detachConsole(true);
	end;
	
	if not connection:getIsServer() then
        g_server:broadcastEvent(SetDetachConsoleEvent:new(self.vehicle), nil, connection, self.vehicle);
    end;
end;

function SetDetachConsoleEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
end;

function SetDetachConsoleEvent.sendEvent(vehicle, noEventSend)
	if not noEventSend then
		if g_server ~= nil then
			g_server:broadcastEvent(SetDetachConsoleEvent:new(vehicle), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetDetachConsoleEvent:new(vehicle));
		end;
	end;
end;

AddAttacherJointEvent = {};
AddAttacherJointEvent_mt = Class(AddAttacherJointEvent, Event);

InitEventClass(AddAttacherJointEvent, "AddAttacherJointEvent");

function AddAttacherJointEvent:emptyNew()
    local self = Event:new(AddAttacherJointEvent_mt);
    self.className="AddAttacherJointEvent";
    return self;
end;

function AddAttacherJointEvent:new(vehicle)
    local self = AddAttacherJointEvent:emptyNew()
    self.vehicle = vehicle;
    return self;
end;

function AddAttacherJointEvent:readStream(streamId, connection)
    self.vehicle = networkGetObject(streamReadInt32(streamId));

	if self.vehicle ~= nil then
		self.vehicle:addFrontloaderAttacherJoint(true);
	end;
	
	if not connection:getIsServer() then
        g_server:broadcastEvent(AddAttacherJointEvent:new(self.vehicle), nil, connection, self.vehicle);
    end;
end;

function AddAttacherJointEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
end;

function AddAttacherJointEvent.sendEvent(vehicle, noEventSend)
	if not noEventSend then
		if g_server ~= nil then
			g_server:broadcastEvent(AddAttacherJointEvent:new(vehicle), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(AddAttacherJointEvent:new(vehicle));
		end;
	end;
end;

SetConsoleAttachModeEvent = {};
SetConsoleAttachModeEvent_mt = Class(SetConsoleAttachModeEvent, Event);

InitEventClass(SetConsoleAttachModeEvent, "SetConsoleAttachModeEvent");

function SetConsoleAttachModeEvent:emptyNew()
    local self = Event:new(SetConsoleAttachModeEvent_mt);
    self.className="SetConsoleAttachModeEvent";
    return self;
end;

function SetConsoleAttachModeEvent:new(vehicle, consoleAttachMode)
    local self = SetConsoleAttachModeEvent:emptyNew()
    self.vehicle = vehicle;
	self.consoleAttachMode = consoleAttachMode;
    return self;
end;

function SetConsoleAttachModeEvent:readStream(streamId, connection)
    local id = streamReadInt32(streamId);
    self.vehicle = networkGetObject(id);

	self.consoleAttachMode = streamReadBool(streamId);
	if self.vehicle ~= nil then
		self.vehicle:setConsoleAttachMode(self.consoleAttachMode, false, true);
	end;
	
	if not connection:getIsServer() then
        g_server:broadcastEvent(SetConsoleAttachModeEvent:new(self.vehicle, self.consoleAttachMode), nil, connection, self.vehicle);
    end;
end;

function SetConsoleAttachModeEvent:writeStream(streamId, connection)
    streamWriteInt32(streamId, networkGetObjectId(self.vehicle));
	streamWriteBool(streamId, self.consoleAttachMode);
end;

function SetConsoleAttachModeEvent.sendEvent(vehicle, consoleAttachMode, noEventSend)
	if noEventSend == nil or noEventSend == false then
		if g_server ~= nil then
			g_server:broadcastEvent(SetConsoleAttachModeEvent:new(vehicle, consoleAttachMode), nil, nil, vehicle);
		else
			g_client:getServerConnection():sendEvent(SetConsoleAttachModeEvent:new(vehicle, consoleAttachMode));
		end;
	end;
end;

local original = Vehicle.attachImplement;
Vehicle.attachImplement = function(self, object, inputJointDescIndex, jointDescIndex, noEventSend, index, startLowered)
	local jointDesc = self.attacherJoints[jointDescIndex];
	if jointDesc ~= nil then
		original(self, object, inputJointDescIndex, jointDescIndex, noEventSend, index, startLowered);
	end;
end;

local original = Vehicle.updatePowerTakeoff;
Vehicle.updatePowerTakeoff = function(self, implement, dt)
	if self.attacherJoints[implement.jointDescIndex] ~= nil then
		original(self, implement, dt);
	end;
end;

local original = Vehicle.updateAttacherJointGraphics;
Vehicle.updateAttacherJointGraphics = function(self, implement, dt)
	if self.attacherJoints[implement.jointDescIndex] ~= nil then
		original(self, implement, dt);
	end;
end;

local original = Vehicle.setJointMoveDown;
Vehicle.setJointMoveDown = function(self, jointDescIndex, moveDown, noEventSend)
	if self.attacherJoints[jointDescIndex] ~= nil then
		original(self, jointDescIndex, moveDown, noEventSend);
	end;
end;