package link.roadio.riff.player.library import link.roadio.cuetree.NodeKind /** Resolves a row through its catalog index, then checks compact parent/view membership. * AI-INTENT: Alphabetical display order is never used as an ID index. * https://wiki.271.pics/Riff/1-1-0/catalog-consumption#prepared-collection-views */ internal fun CuetreeBrowseCatalog.rowRecord( collection: String, row: String, ): Int? { val value = row .substringAfter(':') .substringBefore(':') .toULongOrNull(16) ?.toLong() val parent = collection.substringAfter(':', "").toIntOrNull() if (collection == "albums" || collection.startsWith("artist-albums:") || collection.startsWith("genre-albums:")) { if (!row.startsWith("album:")) return null val index = value?.let(snapshot::albumIndex)?.takeIf { it >= 0 && albumVisible(it) } ?: return null val admitted = when { collection == "albums" -> true collection.startsWith("artist-albums:") -> parent?.let { facts.artistAlbums[it].binarySearch(index) >= 0 } == true else -> parent?.let { facts.genreAlbums[it].binarySearch(index) >= 0 } == true } return index.takeIf { admitted } } if (collection == "artists" ) { return value?.takeIf { row.startsWith("artist:") }?.let(snapshot::artistIndex)?.takeIf { it >= 0 && artistIndices.binarySearch(it) >= 0 } } if (collection == "genres" ) { return value?.takeIf { row.startsWith("genre:") }?.let(snapshot::genreIndex)?.takeIf { it >= 0 && genreIndices.binarySearch(it) >= 0 } } val track = row .substringAfter(':') .substringBefore(':') .toIntOrNull() ?.takeIf { it in snapshot.nodes.indices } if (collection.startsWith("album-tracks:")) { return track?.takeIf { row.startsWith("track-row:") && parent != null && facts.albumSourceLookup[parent].binarySearch(it) >= 0 } } if (collection.startsWith("file-members:")) { return track?.takeIf { val container = parent?.let(facts.containers.records::get) ?: return@takeIf false row == "folder-track-row:$it:${container.base}" && container.lookup.binarySearch(it) >= 0 && snapshot.nodeAvailable(it) } } if (collection == "retained" || collection == "tracks" ) { return track?.takeIf { isMedia(it) && (collection == "retained" || playable(it)) } } if (row.startsWith("media-container:") && collection.startsWith("folder-children:")) { val index = fileIndex(row) ?: return null val base = facts.containers.records[index].base return (-1 - index).takeIf { snapshot.nodeAvailable(base) && snapshot.parentOf(base) == parent } } if (row.startsWith("folder:")) { val index = value?.let(::folderIndex) ?: return null return index.takeIf { snapshot.nodeAvailable(it) && if (collection == "folders" ) { facts.rootFolders.binarySearch(it) >= 0 } else { collection.startsWith("folder-children:") && snapshot.parentOf(it) == parent } } } return track?.takeIf { collection.startsWith("folder-children:") && row == "folder-track-row:$it:$it" && snapshot.nodeKind(it) == NodeKind.MEDIA && snapshot.nodeAvailable(it) && snapshot.parentOf(it) == parent && it !in facts.containers.structuredBases } } internal fun CuetreeBrowseCatalog.rowIdentity( collection: String, record: Int, ): String = when { collection == "albums" || collection.startsWith("artist-albums:") || collection.startsWith("genre-albums:") -> { "album:${snapshot.albumId(record).toULong().toString(16)}" } collection == "artists" -> { "artist:${snapshot.artistId(record).toULong().toString(16)}" } collection == "genres" -> { "genre:${snapshot.genreId(record).toULong().toString(16)}" } collection == "folders" -> { "folder:${snapshot.nodeId(record).hi.toULong().toString(16)}" } collection.startsWith("folder-children:") -> { if (record < 0 ) { fileId(-1 - record) } else if (snapshot.nodeKind(record) == NodeKind.DIRECTORY ) { "folder:${snapshot.nodeId(record).hi.toULong().toString(16)}" } else { "folder-track-row:$record:$record" } } collection.startsWith("file-members:") -> { "folder-track-row:$record:${facts.containers.records[collection.substringAfter(':').toInt()].base}" } else -> { "track-row:$record" } }