/*
 * 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.ui.core.demos

import androidx.compose.Composable
import androidx.compose.foundation.BaseTextField
import androidx.compose.foundation.Box
import androidx.compose.foundation.ContentGravity
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.ScrollableColumn
import androidx.compose.foundation.Text
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.preferredHeight
import androidx.compose.foundation.layout.preferredSize
import androidx.compose.foundation.layout.preferredWidth
import androidx.compose.foundation.shape.corner.CircleShape
import androidx.compose.state
import androidx.ui.core.Alignment
import androidx.ui.core.Modifier
import androidx.ui.core.Popup
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.TextFieldValue
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp

@Composable
fun PopupDemo() {
    val exampleIndex = state { 0 }
    val totalExamples = 8

    Column {
        Row(
            Modifier.fillMaxWidth().gravity(Alignment.CenterHorizontally),
            horizontalArrangement = Arrangement.SpaceBetween
        ) {
            this@Column.ClickableTextWithBackground(
                text = "Prev",
                color = Color.Cyan,
                onClick = {
                    if (exampleIndex.value == 0) {
                        exampleIndex.value = totalExamples
                    }

                    exampleIndex.value = (exampleIndex.value - 1) % totalExamples
                },
                padding = 20.dp
            )

            Box(
                modifier = Modifier.weight(1f),
                gravity = ContentGravity.Center
            ) {
                val description: String = {
                    when (exampleIndex.value) {
                        0 -> "Toggle a simple popup"
                        1 -> "Different content for the popup"
                        2 -> "Popup's behavior when the parent's size or position " +
                                "changes"
                        3 -> "Aligning the popup below the parent"
                        4 -> "Aligning the popup inside a parent"
                        5 -> "Insert an email in the popup and then click outside to " +
                                "dismiss"
                        6 -> "[bug] Undesired visual effect caused by" +
                                " having a new size content displayed at the old" +
                                " position, until the new one is calculated"
                        7 -> "The popup is aligning to its parent when the parent is" +
                                " inside a Scroller"
                        8 -> "[bug] The popup is not repositioned " +
                                "when the parent is moved by the keyboard"
                        else -> "Demo description here"
                    }
                }.invoke()

                Text(
                    text = description,
                    textAlign = TextAlign.Center
                )
            }

            this@Column.ClickableTextWithBackground(
                text = "Next",
                color = Color.Cyan,
                onClick = {
                    exampleIndex.value = (exampleIndex.value + 1) % totalExamples
                },
                padding = 20.dp
            )
        }

        when (exampleIndex.value) {
            0 -> PopupToggle()
            1 -> PopupWithChangingContent()
            2 -> PopupWithChangingParent()
            3 -> PopupAlignmentDemo()
            4 -> PopupWithEditText()
            5 -> PopupWithChangingSize()
            6 -> PopupInsideScroller()
            7 -> PopupOnKeyboardUp()
        }
    }
}

@Composable
private fun ColumnScope.PopupToggle() {
    val showPopup = state { true }

    Column(Modifier.gravity(Alignment.CenterHorizontally)) {
        Box(Modifier.preferredSize(100.dp)) {
            if (showPopup.value) {
                Popup(alignment = Alignment.Center) {
                    Box(
                        Modifier.preferredSize(70.dp),
                        backgroundColor = Color.Green,
                        shape = CircleShape,
                        gravity = ContentGravity.Center
                    ) {
                        Text(
                            text = "This is a popup!",
                            textAlign = TextAlign.Center
                        )
                    }
                }
            }
        }

        ClickableTextWithBackground(
            text = "Toggle Popup",
            color = Color.Cyan,
            onClick = {
                showPopup.value = !showPopup.value
            }
        )
    }
}

@Composable
private fun ColumnScope.PopupWithChangingContent() {
    Column(Modifier.gravity(Alignment.CenterHorizontally)) {
        val heightSize = 120.dp
        val widthSize = 160.dp
        val popupContentState = state { 0 }
        val totalContentExamples = 2
        val popupCounter = state { 0 }

        Box(Modifier.preferredSize(widthSize, heightSize), backgroundColor = Color.Gray) {
            Popup(Alignment.Center) {
                when (popupContentState.value % totalContentExamples) {
                    0 -> ClickableTextWithBackground(
                        text = "Counter : ${popupCounter.value}",
                        color = Color.Green,
                        onClick = {
                            popupCounter.value += 1
                        }
                    )
                    1 -> Box(
                        Modifier.preferredSize(60.dp, 40.dp),
                        backgroundColor = Color.Blue,
                        shape = CircleShape
                    )
                }
            }
        }

        Spacer(Modifier.preferredHeight(10.dp))
        ClickableTextWithBackground(
            text = "Change content",
            color = Color.Cyan,
            onClick = {
                popupContentState.value += 1
            }
        )
    }
}

@Composable
private fun ColumnScope.PopupWithChangingParent() {
    val containerWidth = 400.dp
    val containerHeight = 200.dp
    val parentGravity = state { ContentGravity.TopStart }
    val parentWidth = state { 80.dp }
    val parentHeight = state { 60.dp }
    val parentSizeChanged = state { false }

    Column(Modifier.gravity(Alignment.CenterHorizontally)) {
        Box(
            Modifier.preferredSize(containerWidth, containerHeight),
            gravity = parentGravity.value
        ) {
            Box(
                Modifier.preferredSize(parentWidth.value, parentHeight.value),
                backgroundColor = Color.Blue
            ) {
                Popup(Alignment.BottomCenter) {
                    Text("Popup", modifier = Modifier.background(color = Color.Green))
                }
            }
        }
        Spacer(Modifier.preferredHeight(10.dp))
        ClickableTextWithBackground(
            text = "Change parent's position",
            color = Color.Cyan,
            onClick = {
                parentGravity.value =
                    if (parentGravity.value == ContentGravity.TopStart)
                        ContentGravity.TopEnd
                    else
                        ContentGravity.TopStart
            }
        )
        Spacer(Modifier.preferredHeight(10.dp))
        ClickableTextWithBackground(
            text = "Change parent's size",
            color = Color.Cyan,
            onClick = {
                if (parentSizeChanged.value) {
                    parentWidth.value = 80.dp
                    parentHeight.value = 60.dp
                } else {
                    parentWidth.value = 160.dp
                    parentHeight.value = 120.dp
                }
                parentSizeChanged.value = !parentSizeChanged.value
            }
        )
    }
}

@Composable
private fun ColumnScope.PopupAlignmentDemo() {
    Column(Modifier.gravity(Alignment.CenterHorizontally)) {
        val heightSize = 200.dp
        val widthSize = 400.dp
        val counter = state { 0 }
        val popupAlignment = state { Alignment.TopStart }
        Box(
            modifier = Modifier.preferredSize(widthSize, heightSize),
            backgroundColor = Color.Red,
            gravity = ContentGravity.BottomCenter
        ) {
            Popup(popupAlignment.value) {
                ClickableTextWithBackground(
                    text = "Click to change alignment",
                    color = Color.White,
                    onClick = {
                        counter.value += 1
                        when (counter.value % 9) {
                            0 -> popupAlignment.value = Alignment.TopStart
                            1 -> popupAlignment.value = Alignment.TopCenter
                            2 -> popupAlignment.value = Alignment.TopEnd
                            3 -> popupAlignment.value = Alignment.CenterEnd
                            4 -> popupAlignment.value = Alignment.BottomEnd
                            5 -> popupAlignment.value = Alignment.BottomCenter
                            6 -> popupAlignment.value = Alignment.BottomStart
                            7 -> popupAlignment.value = Alignment.CenterStart
                            8 -> popupAlignment.value = Alignment.Center
                        }
                    }
                )
            }
        }

        Spacer(Modifier.preferredHeight(10.dp))
        Text(
            modifier = Modifier.gravity(Alignment.CenterHorizontally)
                .background(color = Color.White),
            text = "Alignment : " + popupAlignment.value.toString()
        )
    }
}

@Composable
private fun ColumnScope.PopupWithEditText() {
    Column(Modifier.gravity(Alignment.CenterHorizontally)) {
        val widthSize = 190.dp
        val heightSize = 120.dp
        val editLineSize = 150.dp
        val showEmail = state {
            "Enter your email in the white rectangle and click outside"
        }
        val email = state { "email" }
        val showPopup = state { true }

        Text(text = showEmail.value)

        Box(
            modifier = Modifier.preferredSize(widthSize, heightSize)
                .gravity(Alignment.CenterHorizontally),
            backgroundColor = Color.Red
        ) {
            if (showPopup.value) {
                Popup(
                    alignment = Alignment.Center,
                    isFocusable = true,
                    onDismissRequest = {
                        showEmail.value = "You entered: " + email.value
                        showPopup.value = false
                    }
                ) {
                    EditLine(
                        modifier = Modifier.preferredWidth(editLineSize),
                        initialText = "",
                        color = Color.White,
                        onValueChange = {
                            email.value = it
                        }
                    )
                }
            }
        }
    }
}

@Composable
private fun ColumnScope.PopupWithChangingSize() {
    Column(Modifier.gravity(Alignment.CenterHorizontally)) {
        val showPopup = state { true }
        val heightSize = 120.dp
        val widthSize = 160.dp
        val rectangleState = state { 0 }

        Spacer(Modifier.preferredHeight(15.dp))
        Box(
            modifier = Modifier.preferredSize(widthSize, heightSize),
            backgroundColor = Color.Magenta
        ) {
            if (showPopup.value) {
                Popup(Alignment.Center) {
                    val size = when (rectangleState.value % 4) {
                        0 -> Modifier.preferredSize(30.dp)
                        1 -> Modifier.preferredSize(100.dp)
                        2 -> Modifier.preferredSize(30.dp, 90.dp)
                        else -> Modifier.preferredSize(90.dp, 30.dp)
                    }
                    Box(modifier = size, backgroundColor = Color.Gray)
                }
            }
        }
        Spacer(Modifier.preferredHeight(25.dp))
        ClickableTextWithBackground(
            text = "Change size",
            color = Color.Cyan,
            onClick = {
                rectangleState.value += 1
            }
        )
    }
}

@Composable
private fun ColumnScope.PopupInsideScroller() {
    ScrollableColumn(
        modifier = Modifier.preferredSize(200.dp, 400.dp).gravity(Alignment.CenterHorizontally)
    ) {
        Column(Modifier.fillMaxHeight()) {
            Box(
                modifier = Modifier.preferredSize(80.dp, 160.dp),
                backgroundColor = Color(0xFF00FF00)
            ) {
                Popup(alignment = Alignment.Center) {
                    ClickableTextWithBackground(text = "Centered", color = Color.Cyan)
                }
            }

            for (i in 0..30) {
                Text(text = "Scroll #$i", modifier = Modifier.gravity(Alignment.CenterHorizontally))
            }
        }
    }
}

@Composable
private fun PopupOnKeyboardUp() {
    Column {
        val widthSize = 190.dp
        val heightSize = 120.dp

        Spacer(Modifier.preferredHeight(350.dp))
        Text("Start typing in the EditText below the parent(Red rectangle)")
        Box(
            modifier = Modifier.preferredSize(widthSize, heightSize)
                .gravity(Alignment.CenterHorizontally),
            backgroundColor = Color.Red
        ) {
            Popup(Alignment.Center) {
                Box(backgroundColor = Color.Green) {
                    Text("Popup")
                }
            }
        }

        EditLine(initialText = "Continue typing...", color = Color.Gray)

        Spacer(Modifier.preferredHeight(24.dp))
    }
}

@Composable
private fun ColumnScope.ClickableTextWithBackground(
    text: String,
    color: Color,
    onClick: (() -> Unit)? = null,
    padding: Dp = 0.dp
) {
    Box(
        Modifier
            .gravity(Alignment.CenterHorizontally)
            .clickable(onClick = onClick ?: {}, enabled = onClick != null),
        backgroundColor = color,
        padding = padding
    ) {
        Text(text)
    }
}

@Composable
@OptIn(ExperimentalFoundationApi::class)
private fun EditLine(
    modifier: Modifier = Modifier,
    keyboardType: KeyboardType = KeyboardType.Text,
    imeAction: ImeAction = ImeAction.Unspecified,
    onValueChange: (String) -> Unit = {},
    initialText: String = "",
    color: Color = Color.White
) {
    val state = state { TextFieldValue(initialText) }
    BaseTextField(
        value = state.value,
        modifier = modifier.background(color = color),
        keyboardType = keyboardType,
        imeAction = imeAction,
        onValueChange = {
            state.value = it
            onValueChange(it.text)
        }
    )
}