package theorycrafter.ui.graphs

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import compose.widgets.GraphLine
import eve.data.asSpeed
import eve.data.millisAsTimeSec
import theorycrafter.fits.FitHandle
import theorycrafter.fitting.timeToFractionOfMaxVelocity
import theorycrafter.fitting.velocity


/**
 * The graphs window pane for exploring the speed of ships.
 */
@Composable
fun SpeedGraphPane(initialFitHandle: FitHandle?) {
    FitsGraphPane(
        initialFitHandle = initialFitHandle,
        graph = { fits, modifier ->
            SpeedGraph(
                fits = fits,
                modifier = modifier
            )
        }
    )
}


/**
 * The graph of the speed over time of the given list of fits.
 */
@Composable
private fun SpeedGraph(
    fits: List<GraphFit>,
    modifier: Modifier
) {
    val maxDisplayedSpeed = fits.maxOfOrNull { it.fit.propulsion.maxVelocity }?.times(1.1) ?: 1000.0
    val maxDisplayedTime = fits.maxOfOrNull {
        timeToFractionOfMaxVelocity(
            mass = it.fit.propulsion.mass.value,
            inertiaModifier = it.fit.propulsion.inertiaModifier.value,
            fraction = 0.995
        )
    } ?: 30.0
    BasicGraph(
        modifier = modifier,
        xRange = 0.0 .. maxDisplayedTime,
        yRange = 0.0 .. maxDisplayedSpeed,
        xValueFormatter = { (it*1000).millisAsTimeSec() },
        yValueFormatter = Double::asSpeed,
        lines = fits.map { graphFit ->
            val propulsion = graphFit.fit.propulsion
            val maxVelocity = propulsion.maxVelocity
            GraphLine(
                name = graphFit.name,
                function = { time ->
                    velocity(
                        maxVelocity = maxVelocity,
                        mass = propulsion.mass.value,
                        inertiaModifier = propulsion.inertiaModifier.value,
                        timeSec = time
                    )
                },
                samplingStepPx = DefaultLineSamplingStep,
                lineStyleAtPoint = graphFit.lineStyle
            )
        }
    )
}

