/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package androidx.compose.material

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.InnerPadding
import androidx.compose.foundation.layout.Stack
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Scaffold.FabPosition
import androidx.compose.runtime.Composable
import androidx.compose.runtime.Providers
import androidx.compose.runtime.Stable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.onDispose
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.runtime.staticAmbientOf
import androidx.compose.runtime.structuralEqualityPolicy
import androidx.compose.ui.Alignment
import androidx.compose.ui.Layout
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.geometry.Size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.layout.boundsInParent
import androidx.compose.ui.onPositioned
import androidx.compose.ui.platform.DensityAmbient
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.zIndex

/**
 * State for [Scaffold] composable component.
 *
 * Contains basic screen state, e.g. Drawer configuration, as well as sizes of components after
 * layout has happened
 *
 * @param drawerState the drawer state
 * @param isDrawerGesturesEnabled whether or not drawer can be interacted with via gestures
 */
@Stable
class ScaffoldState(
    val drawerState: DrawerState,
    isDrawerGesturesEnabled: Boolean = true
) {

    /**
     * Whether or not drawer sheet in scaffold (if set) can be interacted by gestures.
     */
    var isDrawerGesturesEnabled by mutableStateOf(isDrawerGesturesEnabled)
    // TODO: add showSnackbar() method here

    /**
     * Get current size of the topBar in [Scaffold], if known. `null` if this unknown or topBar
     * parameter in scaffold is not set
     */
    val topBarSize: Size?
        get() = scaffoldGeometry.topBarBounds?.size

    /**
     * Get current size of the bottomBar in [Scaffold], if known. `null` if this unknown or
     * bottomBar parameter in scaffold is not set
     */
    val bottomBarSize: Size?
        get() = scaffoldGeometry.bottomBarBounds?.size

    /**
     * Get current size of the floatingActionButton in [Scaffold], if known. `null` if this unknown
     * or floatingActionButton parameter in scaffold is not set
     */
    val floatingActionButtonSize: Size?
        get() = scaffoldGeometry.fabBounds?.size

    internal val scaffoldGeometry = ScaffoldGeometry()
}

/**
 * Creates a [ScaffoldState] with the default animation clock and memoizes it.
 *
 * @param drawerState the drawer state
 * @param isDrawerGesturesEnabled whether or not drawer can be interacted with via gestures
 */
@Composable
fun rememberScaffoldState(
    drawerState: DrawerState = rememberDrawerState(DrawerValue.Closed),
    isDrawerGesturesEnabled: Boolean = true
): ScaffoldState {
    return remember { ScaffoldState(drawerState, isDrawerGesturesEnabled) }
}

@Stable
internal class ScaffoldGeometry {
    var topBarBounds by mutableStateOf<Rect?>(null, structuralEqualityPolicy())
    var bottomBarBounds by mutableStateOf<Rect?>(null, structuralEqualityPolicy())
    var fabBounds by mutableStateOf<Rect?>(null, structuralEqualityPolicy())

    var isFabDocked by mutableStateOf(false)
}

internal val ScaffoldGeometryAmbient = staticAmbientOf { ScaffoldGeometry() }

object Scaffold {
    /**
     * The possible positions for a [FloatingActionButton] attached to a [Scaffold].
     */
    enum class FabPosition {
        /**
         * Position FAB at the bottom of the screen in the center, above the [BottomAppBar] (if it
         * exists)
         */
        Center,
        /**
         * Position FAB at the bottom of the screen at the end, above the [BottomAppBar] (if it
         * exists)
         */
        End
    }
}

/**
 * Scaffold implements the basic material design visual layout structure.
 *
 * This component provides API to put together several material components to construct your
 * screen, by ensuring proper layout strategy for them and collecting necessary data so these
 * components will work together correctly.
 *
 * Simple example of a Scaffold with [TopAppBar], [FloatingActionButton] and drawer:
 *
 * @sample androidx.compose.material.samples.SimpleScaffoldWithTopBar
 *
 * More fancy usage with [BottomAppBar] with cutout and docked [FloatingActionButton], which
 * animates it's shape when clicked:
 *
 * @sample androidx.compose.material.samples.ScaffoldWithBottomBarAndCutout
 *
 * @param scaffoldState state of this scaffold widget. It contains the state of the screen, e.g.
 * variables to provide manual control over the drawer behavior, sizes of components, etc
 * @param topBar top app bar of the screen. Consider using [TopAppBar].
 * @param bottomBar bottom bar of the screen. Consider using [BottomAppBar].
 * @param floatingActionButton Main action button of your screen. Consider using
 * [FloatingActionButton] for this slot.
 * @param floatingActionButtonPosition position of the FAB on the screen. See [FabPosition] for
 * possible options available.
 * @param isFloatingActionButtonDocked whether [floatingActionButton] should overlap with
 * [bottomBar] for half a height, if [bottomBar] exists. Ignored if there's no [bottomBar] or no
 * [floatingActionButton].
 * @param drawerContent content of the Drawer sheet that can be pulled from the left side (right
 * for RTL).
 * @param drawerShape shape of the drawer sheet (if set)
 * @param drawerElevation drawer sheet elevation. This controls the size of the shadow
 * below the drawer sheet (if set)
 * @param bodyContent content of your screen. The lambda receives an [InnerPadding] that should be
 * applied to the content root via [Modifier.padding] to properly offset top and bottom bars. If
 * you're using VerticalScroller, apply this modifier to the child of the scroller, and not on
 * the scroller itself.
 */
@Composable
fun Scaffold(
    scaffoldState: ScaffoldState = rememberScaffoldState(),
    topBar: @Composable (() -> Unit)? = null,
    bottomBar: @Composable (() -> Unit)? = null,
    floatingActionButton: @Composable (() -> Unit)? = null,
    floatingActionButtonPosition: FabPosition = FabPosition.End,
    isFloatingActionButtonDocked: Boolean = false,
    drawerContent: @Composable (() -> Unit)? = null,
    drawerShape: Shape = MaterialTheme.shapes.large,
    drawerElevation: Dp = DrawerConstants.DefaultElevation,
    backgroundColor: Color = MaterialTheme.colors.background,
    bodyContent: @Composable (InnerPadding) -> Unit
) {
    scaffoldState.scaffoldGeometry.isFabDocked = isFloatingActionButtonDocked
    val child = @Composable {
        Surface(color = backgroundColor) {
            Column(Modifier.fillMaxSize()) {
                if (topBar != null) {
                    TopBarContainer(Modifier.zIndex(TopAppBarZIndex), scaffoldState, topBar)
                }
                Stack(Modifier.weight(1f, fill = true)) {
                    ScaffoldContent(Modifier.fillMaxSize(), scaffoldState, bodyContent)
                    ScaffoldBottom(
                        Modifier.gravity(Alignment.BottomCenter),
                        scaffoldState = scaffoldState,
                        fabPos = floatingActionButtonPosition,
                        isFabDocked = isFloatingActionButtonDocked,
                        fab = floatingActionButton,
                        bottomBar = bottomBar
                    )
                }
            }
        }
    }

    if (drawerContent != null) {
        ModalDrawerLayout(
            drawerState = scaffoldState.drawerState,
            gesturesEnabled = scaffoldState.isDrawerGesturesEnabled,
            drawerContent = { ScaffoldSlot(content = drawerContent) },
            drawerShape = drawerShape,
            drawerElevation = drawerElevation,
            bodyContent = child
        )
    } else {
        child()
    }
}

private fun FabPosition.toColumnAlign() =
    if (this == FabPosition.End) Alignment.End else Alignment.CenterHorizontally

/**
 * Scaffold part that is on the bottom. Includes FAB and BottomBar
 */
@Composable
private fun ScaffoldBottom(
    modifier: Modifier,
    scaffoldState: ScaffoldState,
    fabPos: FabPosition,
    isFabDocked: Boolean,
    fab: @Composable (() -> Unit)? = null,
    bottomBar: @Composable (() -> Unit)? = null
) {
    if (isFabDocked && bottomBar != null && fab != null) {
        DockedBottomBar(
            modifier = modifier,
            fabPosition = fabPos,
            fab = { FabContainer(Modifier, scaffoldState, fab) },
            bottomBar = { BottomBarContainer(scaffoldState, bottomBar) }
        )
    } else {
        Column(modifier.fillMaxWidth()) {
            if (fab != null) {
                FabContainer(
                    Modifier.gravity(fabPos.toColumnAlign())
                        .padding(start = FabSpacing, end = FabSpacing, bottom = FabSpacing),
                    scaffoldState,
                    fab
                )
            }
            if (bottomBar != null) {
                BottomBarContainer(scaffoldState, bottomBar)
            }
        }
    }
}

/**
 * Simple `Stack` implementation that places [fab] on top (z-axis) of [bottomBar], with the midpoint
 * of the [fab] aligned to the top edge of the [bottomBar].
 *
 * This is needed as we want the total height of the BottomAppBar to be equal to the height of
 * [bottomBar] + half the height of [fab], which is only possible with a custom layout.
 */
@Composable
private fun DockedBottomBar(
    modifier: Modifier,
    fabPosition: FabPosition,
    fab: @Composable () -> Unit,
    bottomBar: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        children = {
            bottomBar()
            fab()
        }) { measurables, constraints ->
        val (appBarPlaceable, fabPlaceable) = measurables.map { it.measure(constraints) }

        val layoutWidth = appBarPlaceable.width
        // Total height is the app bar height + half the fab height
        val layoutHeight = appBarPlaceable.height + (fabPlaceable.height / 2)

        val appBarVerticalOffset = layoutHeight - appBarPlaceable.height
        val fabPosX = if (fabPosition == FabPosition.End) {
            layoutWidth - fabPlaceable.width - DockedFabEndSpacing.toIntPx()
        } else {
            (layoutWidth - fabPlaceable.width) / 2
        }

        layout(layoutWidth, layoutHeight) {
            appBarPlaceable.place(0, appBarVerticalOffset)
            fabPlaceable.place(fabPosX, 0)
        }
    }
}

@Composable
private fun ScaffoldContent(
    modifier: Modifier,
    scaffoldState: ScaffoldState,
    content: @Composable (InnerPadding) -> Unit
) {
    ScaffoldSlot(modifier) {
        val innerPadding = with(DensityAmbient.current) {
            val bottom = scaffoldState.scaffoldGeometry.bottomBarBounds?.height?.toDp() ?: 0.dp
            InnerPadding(bottom = bottom)
        }
        content(innerPadding)
    }
}

@Composable
private fun BottomBarContainer(
    scaffoldState: ScaffoldState,
    bottomBar: @Composable () -> Unit
) {
    BoundsAwareScaffoldSlot(
        Modifier,
        { scaffoldState.scaffoldGeometry.bottomBarBounds = it },
        slotContent = {
            Providers(ScaffoldGeometryAmbient provides scaffoldState.scaffoldGeometry) {
                bottomBar()
            }
        }
    )
}

@Composable
private fun FabContainer(
    modifier: Modifier,
    scaffoldState: ScaffoldState,
    fab: @Composable () -> Unit
) {
    BoundsAwareScaffoldSlot(modifier, { scaffoldState.scaffoldGeometry.fabBounds = it }, fab)
}

@Composable
private fun TopBarContainer(
    modifier: Modifier,
    scaffoldState: ScaffoldState,
    topBar: @Composable () -> Unit
) {
    BoundsAwareScaffoldSlot(modifier, { scaffoldState.scaffoldGeometry.topBarBounds = it }, topBar)
}

@Composable
private fun BoundsAwareScaffoldSlot(
    modifier: Modifier,
    onBoundsKnown: (Rect?) -> Unit,
    slotContent: @Composable () -> Unit
) {
    onDispose {
        onBoundsKnown(null)
    }
    ScaffoldSlot(
        modifier = modifier.onPositioned { coords -> onBoundsKnown(coords.boundsInParent) },
        content = slotContent
    )
}

/**
 * Default slot implementation for Scaffold slots content
 */
@Composable
private fun ScaffoldSlot(modifier: Modifier = Modifier, content: @Composable () -> Unit) {
    Stack(modifier) { content() }
}

private val FabSpacing = 16.dp
private val DockedFabEndSpacing = 16.dp
private const val TopAppBarZIndex = 1f