package ch.dissem.yaep.ui.common.layout

import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.Placeable
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.Constraints.Companion.fixed
import androidx.compose.ui.unit.Constraints.Companion.fixedWidth

internal fun Placeable.PlacementScope.landscape(
    constraints: Constraints,
    spacingPx: Int,
    grid: FocusGroup,
    horizontalClues: FocusGroup,
    verticalClues: FocusGroup,
    timeMeasurable: Measurable,
    dividerMeasurable: Measurable
) {
    val gridSize = constraints.maxHeight
    val gridItemSize = (gridSize - 12 * spacingPx) / 18
    val rightBarWidth = constraints.maxWidth - gridSize - 2 * spacingPx

    val gridConstraints = fixed(gridSize, gridSize)
    val baseSpace = gridSize - 2 * spacingPx
    val horizontalCluesConstraints = fixed(
        width = 3 * gridItemSize + 2 * spacingPx,
        height = gridItemSize + 2 * spacingPx
    )
    val verticalCluesConstraints = fixed(
        width = gridItemSize + 2 * spacingPx,
        height = 3 * gridItemSize + 2 * spacingPx
    )
    val timeConstraints = Constraints.fixedHeight(baseSpace / 10)
    val dividerConstraints = fixedWidth(rightBarWidth - 2 * spacingPx)

    val gridPlaceable = grid.item.measure(gridConstraints)
    val gridBoxPlaceable = grid.box.measure(gridConstraints)
    val horizontalCluesPlaceables = horizontalClues.items.map {
        it.measure(horizontalCluesConstraints)
    }
    val horizontalCluesBoxPlaceable = horizontalClues.box
        .measure(
            cluesBoxConstraints(
                width = rightBarWidth,
                itemConstraints = horizontalCluesConstraints,
                group = horizontalClues
            )
        )

    val verticalCluesPlaceables = verticalClues.items.map {
        it.measure(verticalCluesConstraints)
    }
    val verticalCluesBoxPlaceable = verticalClues.box
        .measure(
            cluesBoxConstraints(
                width = rightBarWidth,
                itemConstraints = verticalCluesConstraints,
                group = verticalClues
            )
        )

    val timePlaceable = timeMeasurable.measure(timeConstraints)
    val dividerPlaceable = dividerMeasurable.measure(dividerConstraints)

    // Position the grid
    gridBoxPlaceable.place(0, 0)
    gridPlaceable.place(0, 0)

    // Position the horizontal clues4
    val horizontalCluesOffsetX = gridSize + 2 * spacingPx
    horizontalCluesBoxPlaceable.place(horizontalCluesOffsetX, 0)
    val offsetY = placeClues(
        placeables = horizontalCluesPlaceables,
        offsetX = horizontalCluesOffsetX,
        offsetY = 0,
        maxWidth = rightBarWidth
    )

    if (verticalClues.hasItems) {
        // Add divider in between
        dividerPlaceable.place(gridSize + 3 * spacingPx, offsetY + spacingPx)

        // Position the vertical clues
        val verticalCluesOffsetX = gridSize + 2 * spacingPx
        val verticalCluesOffsetY = offsetY + spacingPx + dividerPlaceable.height
        verticalCluesBoxPlaceable.place(verticalCluesOffsetX, verticalCluesOffsetY)
        placeClues(
            placeables = verticalCluesPlaceables,
            offsetX = verticalCluesOffsetX,
            offsetY = verticalCluesOffsetY,
            maxWidth = rightBarWidth
        )
    }

    // Position the time
    timePlaceable.place(
        x = constraints.maxWidth - timePlaceable.width - spacingPx,
        y = constraints.maxHeight - timePlaceable.height
    )
}