ComponentPlacementFix = {}

function ComponentPlacementFix.prerequisitesPresent(specializations)
	return true
end
	
function ComponentPlacementFix.registerOverwrittenFunctions(vehicleType)
	SpecializationUtil.registerOverwrittenFunction(vehicleType, "setRelativePosition", ComponentPlacementFix.setRelativePosition)
	SpecializationUtil.registerOverwrittenFunction(vehicleType, "setAbsolutePosition", ComponentPlacementFix.setAbsolutePosition)
	SpecializationUtil.registerOverwrittenFunction(vehicleType, "setWorldPosition", ComponentPlacementFix.setWorldPosition)
end

function ComponentPlacementFix.registerEventListeners(vehicleType)
	SpecializationUtil.registerEventListener(vehicleType, "onPostLoad", ComponentPlacementFix)
end

function ComponentPlacementFix:onPostLoad(savegame)
	if self.isServer then
		for _, jointDesc in pairs(self.componentJoints) do
			local component2 = self.components[jointDesc.componentIndices[2]]
			local jointNode = jointDesc.jointNode

			if self:getParentComponent(jointNode) == component2.node then
				jointNode = jointDesc.jointNodeActor1
			end

			if self:getParentComponent(jointNode) ~= component2.node and getParent(component2.node) == jointNode then
				local ox = 0
				local oy = 0
				local oz = 0

				if jointDesc.jointNodeActor1 ~= jointDesc.jointNode then
					local x1, y1, z1 = localToLocal(jointDesc.jointNode, component2.node, 0, 0, 0)
					local x2, y2, z2 = localToLocal(jointDesc.jointNodeActor1, component2.node, 0, 0, 0)
					oz = z1 - z2
					oy = y1 - y2
					ox = x1 - x2
				end

				local x, y, z = localToWorld(component2.node, ox, oy, oz)
				local rx, ry, rz = localRotationToWorld(component2.node, 0, 0, 0)
				component2.fixedTranslation = {
					x,
					y,
					z
				}
				component2.fixedRotation = {
					rx,
					ry,
					rz
				}
			end
		end
	end
end

function ComponentPlacementFix:setRelativePosition(superFunc, positionX, offsetY, positionZ, yRot)
	ComponentPlacementFix.fixComponentPositions(self)
	superFunc(self, positionX, offsetY, positionZ, yRot)
end

function ComponentPlacementFix:setAbsolutePosition(superFunc, positionX, positionY, positionZ, xRot, yRot, zRot, componentPositions)
	ComponentPlacementFix.fixComponentPositions(self)
	superFunc(self, positionX, positionY, positionZ, xRot, yRot, zRot, componentPositions)
end

function ComponentPlacementFix:setWorldPosition(superFunc, x, y, z, xRot, yRot, zRot, i, changeInterp)
	ComponentPlacementFix.fixComponentPositions(self)
	superFunc(self, x, y, z, xRot, yRot, zRot, i, changeInterp)
end

function ComponentPlacementFix:fixComponentPositions()
	if self.isServer then
		local fixed = false

		for _, component in pairs(self.components) do
			if component.fixedTranslation ~= nil and component.fixedRotation ~= nil then
				local x, y, z = unpack(component.fixedTranslation)
				local rx, ry, rz = unpack(component.fixedRotation)

				setWorldTranslation(component.node, x, y, z)
				setWorldRotation(component.node, rx, ry, rz)

				component.originalTranslation = {
					x,
					y,
					z
				}
				component.originalRotation = {
					rx,
					ry,
					rz
				}
				component.sentTranslation = {
					x,
					y,
					z
				}
				component.sentRotation = {
					rx,
					ry,
					rz
				}
				component.fixedTranslation = nil
				component.fixedRotation = nil
				fixed = true
			end
		end

		if fixed then
			for _, jointDesc in pairs(self.componentJoints) do
				self:setComponentJointFrame(jointDesc, 0)
				self:setComponentJointFrame(jointDesc, 1)
			end
		end
	end
end
