package theorycrafter.utils

import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.foundation.layout.Box
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.scale


/**
 * A utility to run a scale animation to attract the user's attention.
 */
class ScaleAnimationToAttractAttention(private val maxScale: Float = 1.15f) {


    /**
     * The [Animatable] of the scale value.
     */
    private val animatableScale = Animatable(1.0f)


    /**
     * Returns the current scale to use.
     */
    val value: Float
        get() =  animatableScale.value


    /**
     * Runs the animation in the given coroutine scope.
     */
    suspend fun animate() {
        animatableScale.animateTo(maxScale, animationSpec = ANIMATION_SPEC)
        animatableScale.animateTo(1.0f, animationSpec = ANIMATION_SPEC)
    }


    private companion object {

        /**
         * The animation spec to use for the scale animation.
         */
        val ANIMATION_SPEC = spring<Float>(
            dampingRatio = Spring.DampingRatioLowBouncy,
            stiffness = Spring.StiffnessMedium
        )

    }

}


/**
 * A [Box] that runs a scale animation to attract attention whenever the given value changes.
 */
@Composable
fun AttractAttentionOnValueChange(
    value: Any,
    maxScale: Float = 1.15f,
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
){
    val scaleAnimation = remember(maxScale) { ScaleAnimationToAttractAttention(maxScale) }
    var rememberedValue by remember { mutableStateOf(value) }
    LaunchedEffect(rememberedValue, value) {
        if (rememberedValue != value)
            scaleAnimation.animate()
        rememberedValue = value
    }

    Box(modifier = modifier.scale(scaleAnimation.value)) {
        content()
    }
}