-- TODO: Optimize for vertical faces

function BitOps.getConnectivityForFace(connectivity, face)
	local result = 0

	local bitIndexes = BitOps.CONNECTIVITY_INDEXES_FOR_FACE[tostring(BitOps.normalizeVec3(face))]
	for _, index in ipairs(bitIndexes) do
		result = bit32.lshift(result, 1)
		result = bit32.bor(result, bit32.extract(connectivity, index))
	end

	return result
end

function BitOps.getVerticalFaceFromOccupancy(occupancy)
	local horizontalFace
	for _, face in pairs(BitOps.FACES) do
		horizontalFace = face.Y ~= 0
		if not horizontalFace and occupancy == BitOps.OCCUPANCY_FACE_MASK[tostring(face)] then
			return face
		end
	end

	return false
end

function BitOps.applyFaceOccupancy(targetOccupancy, targetFace, appliedOccupancy, appliedFace)
	local appliedOccupancyFaceBit = bit32.extract(appliedOccupancy, BitOps.OCCUPANCY_INDEX_FOR_FACE[tostring(BitOps.normalizeVec3(appliedFace))])
	if appliedOccupancyFaceBit == 1 then
		targetOccupancy =
			bit32.replace(targetOccupancy, appliedOccupancyFaceBit, BitOps.OCCUPANCY_INDEX_FOR_FACE[tostring(BitOps.normalizeVec3(targetFace))])
	end

	return targetOccupancy
end

function BitOps.removeFaceOccupancy(targetOccupancy, targetFace, appliedOccupancy, appliedFace)
	local appliedOccupancyFaceBit = bit32.extract(appliedOccupancy, BitOps.OCCUPANCY_INDEX_FOR_FACE[tostring(BitOps.normalizeVec3(appliedFace))])
	if appliedOccupancyFaceBit == 1 then
		targetOccupancy =
		bit32.replace(targetOccupancy, 0, BitOps.OCCUPANCY_INDEX_FOR_FACE[tostring(BitOps.normalizeVec3(targetFace))])
	end

	return targetOccupancy
end

function BitOps.applyFaceConnectivity(targetConnectivity, targetFace, appliedConnectivity, appliedFace)
	local appliedConnectivityFaceBits = BitOps.getConnectivityForFace(appliedConnectivity, appliedFace)
	local targetConnectivityFaceBits = BitOps.getConnectivityForFace(targetConnectivity, targetFace)
	local newTargetConnectivityFaceBits = bit32.bor(targetConnectivityFaceBits, appliedConnectivityFaceBits)

	targetConnectivity = BitOps.setFaceConnectivity(targetConnectivity, targetFace, newTargetConnectivityFaceBits)

	return targetConnectivity
end
