/**
 * Utilities related to the "selected" state of elements, as in the item selected in a list.
 */
@file:OptIn(ExperimentalComposeUiApi::class)

package compose.utils

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.material.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.modifier.ProvidableModifierLocal
import androidx.compose.ui.modifier.modifierLocalOf
import androidx.compose.ui.modifier.modifierLocalProvider


/**
 * Specifies the "selected" state of the node.
 * A `null` value means the state is not yet known.
 */
val ModifierLocalSelected: ProvidableModifierLocal<Boolean?> = modifierLocalOf { null }


/**
 * Sets the "selected" state of the node to which this modifier is applied.
 * Together with [requestFocusWhenSelected], this can be used to automatically transfer focus to the currently selected
 * item.
 */
fun Modifier.markSelected(isSelected: () -> Boolean) = this.modifierLocalProvider(ModifierLocalSelected, isSelected)


/**
 * A basic selectable item in e.g. a list.
 */
@Composable
fun SelectableBox(
    isSelected: Boolean,
    selectedBackgroundColor: Color,
    selectedContentColor: Color,
    modifier: Modifier = Modifier,
    content: @Composable BoxScope.() -> Unit,
) {
    val selectionColor = if (isSelected) selectedBackgroundColor else Color.Unspecified
    val contentColor = if (isSelected) selectedContentColor else LocalContentColor.current

    CompositionLocalProvider(LocalContentColor provides contentColor) {
        Box(
            modifier = Modifier
                .background(selectionColor)
                .markSelected { isSelected }
                .then(modifier),
            content = content
        )
    }

}
