package de.arxsilex.maptools.converter.desktop

import de.arxsilex.maptools.converter.core.NormalizedMapArea
import de.arxsilex.maptools.converter.core.MapSelectionShape
import de.arxsilex.maptools.converter.core.RectangleSelection
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotNull
import kotlin.test.assertTrue

class AreaSelectionHistoryTest {
    @Test
    fun `undo and redo restore committed area states`() {
        val first = listOf(area(0.1f))
        val second = listOf(area(0.2f))
        val recorded = AreaSelectionHistory().record(emptyList(), first).record(first, second)

        val undone = assertNotNull(recorded.undo(second))
        assertEquals(first, undone.areas)
        assertTrue(undone.history.canRedo)

        val redone = assertNotNull(undone.history.redo(first))
        assertEquals(second, redone.areas)
    }

    @Test
    fun `new action clears redo and history keeps only twenty states`() {
        var history = AreaSelectionHistory()
        var previous = emptyList<MapSelectionShape>()
        repeat(25) { index ->
            val next = listOf(area(index / 100f))
            history = history.record(previous, next)
            previous = next
        }

        repeat(AreaSelectionHistory.HISTORY_LIMIT) {
            val step = assertNotNull(history.undo(previous))
            previous = step.areas
            history = step.history
        }
        assertFalse(history.canUndo)

        val replacement = listOf(area(0.7f))
        history = history.record(previous, replacement)
        assertFalse(history.canRedo)
    }

    private fun area(left: Float): MapSelectionShape = RectangleSelection(NormalizedMapArea(
        left = left.coerceAtMost(0.8f),
        top = 0.1f,
        right = (left + 0.1f).coerceAtMost(0.9f),
        bottom = 0.2f,
    ))
}
