# Copyright (c) 2018-2020, NVIDIA CORPORATION.  All rights reserved.
#
# NVIDIA CORPORATION and its licensors retain all intellectual property
# and proprietary rights in and to this software, related documentation
# and any modifications thereto.  Any use, reproduction, disclosure or
# distribution of this software and related documentation without an express
# license agreement from NVIDIA CORPORATION is strictly prohibited.
#
"""The documentation for Widget"""

from .doc_page import DocPage
from omni import ui
from omni.ui import color as cl
from pathlib import Path
import inspect
import random

SPACING = 5


def tooltip_fixed_position():
    ui.Button("Fixed-position Tooltip", width=200, tooltip="Hello World", tooltip_offset_y=22)


def tooltip_random_position():
    button = ui.Button("Random-position Tooltip", width=200, tooltip_offset_y=22)

    def create_tooltip(button=button):
        button.tooltip_offset_x = random.randint(0, 200)
        ui.Label("Hello World")

    button.set_tooltip_fn(create_tooltip)


def image_button():
    style = {
        "Button": {"stack_direction": ui.Direction.TOP_TO_BOTTOM},
        "Button.Image": {
            "color": cl("#99CCFF"),
            "image_url": "resources/icons/Learn_128.png",
            "alignment": ui.Alignment.CENTER,
        },
        "Button.Label": {"alignment": ui.Alignment.CENTER},
    }

    def direction(model, button, style=style):
        value = model.get_item_value_model().get_value_as_int()
        direction = (
            ui.Direction.TOP_TO_BOTTOM,
            ui.Direction.BOTTOM_TO_TOP,
            ui.Direction.LEFT_TO_RIGHT,
            ui.Direction.RIGHT_TO_LEFT,
            ui.Direction.BACK_TO_FRONT,
            ui.Direction.FRONT_TO_BACK,
        )[value]
        style["Button"]["stack_direction"] = direction
        button.set_style(style)

    def align(model, button, image, style=style):
        value = model.get_item_value_model().get_value_as_int()
        alignment = (
            ui.Alignment.LEFT_TOP,
            ui.Alignment.LEFT_CENTER,
            ui.Alignment.LEFT_BOTTOM,
            ui.Alignment.CENTER_TOP,
            ui.Alignment.CENTER,
            ui.Alignment.CENTER_BOTTOM,
            ui.Alignment.RIGHT_TOP,
            ui.Alignment.RIGHT_CENTER,
            ui.Alignment.RIGHT_BOTTOM,
        )[value]
        if image:
            style["Button.Image"]["alignment"] = alignment
        else:
            style["Button.Label"]["alignment"] = alignment
        button.set_style(style)

    def layout(model, button, padding, style=style):
        padding = "padding" if padding else "margin"
        style["Button"][padding] = model.get_value_as_float()
        button.set_style(style)

    def spacing(model, button):
        button.spacing = model.get_value_as_float()

    button = ui.Button("Label", style=style, width=64, height=64)

    with ui.HStack(width=ui.Percent(50)):
        ui.Label('"Button": {"stack_direction"}', name="text")
        options = (
            0,
            "TOP_TO_BOTTOM",
            "BOTTOM_TO_TOP",
            "LEFT_TO_RIGHT",
            "RIGHT_TO_LEFT",
            "BACK_TO_FRONT",
            "FRONT_TO_BACK",
        )
        model = ui.ComboBox(*options).model
        model.add_item_changed_fn(lambda m, i, b=button: direction(m, b))

    alignment = (
        4,
        "LEFT_TOP",
        "LEFT_CENTER",
        "LEFT_BOTTOM",
        "CENTER_TOP",
        "CENTER",
        "CENTER_BOTTOM",
        "RIGHT_TOP",
        "RIGHT_CENTER",
        "RIGHT_BOTTOM",
    )
    with ui.HStack(width=ui.Percent(50)):
        ui.Label('"Button.Image": {"alignment"}', name="text")
        model = ui.ComboBox(*alignment).model
        model.add_item_changed_fn(lambda m, i, b=button: align(m, b, 1))

    with ui.HStack(width=ui.Percent(50)):
        ui.Label('"Button.Label": {"alignment"}', name="text")
        model = ui.ComboBox(*alignment).model
        model.add_item_changed_fn(lambda m, i, b=button: align(m, b, 0))

    with ui.HStack(width=ui.Percent(50)):
        ui.Label("padding", name="text")
        model = ui.FloatSlider(min=0, max=500).model
        model.add_value_changed_fn(lambda m, b=button: layout(m, b, 1))

    with ui.HStack(width=ui.Percent(50)):
        ui.Label("margin", name="text")
        model = ui.FloatSlider(min=0, max=500).model
        model.add_value_changed_fn(lambda m, b=button: layout(m, b, 0))

    with ui.HStack(width=ui.Percent(50)):
        ui.Label("Button.spacing", name="text")
        model = ui.FloatSlider(min=0, max=50).model
        model.add_value_changed_fn(lambda m, b=button: spacing(m, b))


class WidgetDoc(DocPage):
    """ document for Widget"""

    def radio_button(self):
        style = {
            "": {"background_color": cl.transparent, "image_url": f"{self._extension_path}/icons/radio_off.svg"},
            ":checked": {"image_url": f"{self._extension_path}/icons/radio_on.svg"},
        }
        collection = ui.RadioCollection()
        for i in range(5):
            with ui.HStack(style=style):
                ui.RadioButton(radio_collection=collection, width=30, height=30)
                ui.Label(f"Option {i}", name="text")

        ui.IntSlider(collection.model, min=0, max=4)

    def create_doc(self, navigate_to=None):
        self._section_title("Widgets")
        self._text(
            "The widget provides all the base functionality for most ui elements" "There is a lot of default feature "
        )

        self._caption("Button", navigate_to)

        self._text(
            "The Button widget provides a command button. The command button, is perhaps the most commonly used widget "
            "in any graphical user interface. Click a button to execute a command. It is rectangular and typically "
            "displays a text label describing its action."
        )

        def make_longer_text(button):
            """Set the text of the button longer"""
            button.text = "Longer " + button.text

        def make_shorter_text(button):
            """Set the text of the button shorter"""
            splitted = button.text.split(" ", 1)
            button.text = splitted[1] if len(splitted) > 1 else splitted[0]

        with ui.HStack(style=self._style_system):
            btn_with_text = ui.Button("Text", width=0)
            ui.Button("Press me", width=0, clicked_fn=lambda b=btn_with_text: make_longer_text(b))
            btn_with_text.set_clicked_fn(lambda b=btn_with_text: make_shorter_text(b))

        self._code(
            """
        def make_longer_text(button):
            '''Set the text of the button longer'''
            button.text = "Longer " + button.text

        def make_shorter_text(button):
            '''Set the text of the button shorter'''
            splitted = button.text.split(" ", 1)
            button.text = \\
                splitted[1] if len(splitted) > 1 else splitted[0]

        with ui.HStack(style=style_system):
            btn_with_text = ui.Button("Text", width=0)
            ui.Button(
                "Press me",
                width=0,
                clicked_fn=lambda b=btn_with_text: make_longer_text(b)
            )
            btn_with_text.set_clicked_fn(
                lambda b=btn_with_text: make_shorter_text(b))
            """
        )

        image_button()
        self._code(inspect.getsource(image_button).split("\n", 1)[-1])

        self._caption("RadioButton", navigate_to)

        self._text(
            "RadioButton is the widget that allows the user to choose only one of a predefined set of mutually "
            "exclusive options."
        )

        self._text(
            "RadioButtons are arranged in collections of two or more with the class RadioGroup, which is the central "
            "component of the system and controls the behavior of all the RadioButtons in the collection."
        )

        self.radio_button()
        self._code(inspect.getsource(self.radio_button).split("\n", 1)[-1])

        self._caption("Label", navigate_to)

        self._text(
            "Labels are used everywhere in omni.ui. They are text-only objects, and don't have a background color"
            "But you can control the color, font_size and alignment in the styling."
        )

        self._exec_code(
            """
        ui.Label("this is a simple label", style={"color": cl.black})
        """
        )

        self._exec_code(
            """
        ui.Label("label with aligment", style={"color": cl.black}, alignment=ui.Alignment.CENTER)
        """
        )

        self._exec_code(
            """
        label_style = {"Label": {"font_size": 16, "color": cl.blue, "alignment":ui.Alignment.RIGHT }}

        ui.Label("Label with style", style=label_style)
        """
        )

        self._exec_code(
            """
        ui.Label(
            "Label can be elided: Lorem ipsum dolor "
            "sit amet, consectetur adipiscing elit, sed do "
            "eiusmod tempor incididunt ut labore et dolore "
            "magna aliqua. Ut enim ad minim veniam, quis "
            "nostrud exercitation ullamco laboris nisi ut "
            "aliquip ex ea commodo consequat. Duis aute irure "
            "dolor in reprehenderit in voluptate velit esse "
            "cillum dolore eu fugiat nulla pariatur. Excepteur "
            "sint occaecat cupidatat non proident, sunt in "
            "culpa qui officia deserunt mollit anim id est "
            "laborum.",
            style={"color":cl.black},
            elided_text=True,
        )
        """
        )

        self._caption("Tooltip", navigate_to)

        self._text(
            "All Widget can be augmented with a tooltip, it can take 2 forms, either a simple ui.Label or a callback"
            "when using the callback, tooltip_fn= or widget.set_tooltip_fn() you can create virtually any widget for "
            "the tooltip"
        )

        self._exec_code(
            """
        tooltip_style = {
            "Tooltip": {"background_color": cl("#DDDD00"), "color": cl("#333333"), "margin_width": 3 ,
                        "margin_height": 2 , "border_width":3, "border_color": cl.red }}

        ui.Button("Simple Label Tooltip", name="tooltip", width=200,
                  tooltip="  I am a text ToolTip  ", style=tooltip_style)
        """
        )

        self._exec_code(
            """
        def create_tooltip():
            with ui.VStack(width=200, style=tooltip_style):
                with ui.HStack():
                    ui.Label("Fancy tooltip", width=150)
                    ui.IntField().model.set_value(12)
                ui.Line(height=2, style={"color": cl.white})
                with ui.HStack():
                    ui.Label("Anything is possible", width=150)
                    ui.StringField().model.set_value("you bet")
                image_source = "resources/desktop-icons/omniverse_512.png"
                ui.Image(
                    image_source,
                    width=200,
                    height=200,
                    alignment=ui.Alignment.CENTER,
                    style={"margin": 0},
                )
        tooltip_style = {
            "Tooltip": {"background_color": cl("#444444"), "border_width":2, "border_radius":5},
            }
        ui.Button("Callback function Tooltip", width=200, style=tooltip_style, tooltip_fn=create_tooltip)
        """
        )

        tooltip_fixed_position()
        self._code(inspect.getsource(tooltip_fixed_position).split("\n", 1)[-1])

        tooltip_random_position()
        self._code(inspect.getsource(tooltip_random_position).split("\n", 1)[-1])

        ui.Spacer(height=50)

        self._caption("Debug Color", navigate_to)

        self._text("All Widget can be styled to use a debug color that enable you to visualize their frame")

        self._exec_code(
            """
        style = {"background_color": cl("#DDDD00"),
                 "color": cl("#333333"),
                 "debug_color": cl("#FF000022") }

        ui.Label("Label with Debug", width=200, style=style)
        """
        )

        self._exec_code(
            """
        style = {":hovered": {"debug_color": cl("#00FFFF22") },
                 "Label": {"padding": 3,
                           "background_color": cl("#DDDD00"),
                           "color": cl("#333333"),
                           "debug_color": cl("#0000FF22") }}

        with ui.HStack(width=500, style=style):
            ui.Label("Label 1", width=50)
            ui.Label("Label 2")
            ui.Label("Label 3",
                      width=100,
                      alignment=ui.Alignment.CENTER)
            ui.Spacer()
            ui.Label("Label 3", width=50)
        """
        )

        self._caption("Font", navigate_to)

        self._text(
            "It's possible to set the font of the label using styles. The style key 'font' should point to the font "
            "file, which allows packaging of the font to the extension. We support both TTF and OTF formats. "
            "All text-based widgets support custom fonts."
        )

        self._exec_code(
            """
        ui.Label(
                "The quick brown fox jumps over the lazy dog",
                style={
                    "font_size": 55,
                    "font": "${fonts}/OpenSans-SemiBold.ttf",
                    "alignment": ui.Alignment.CENTER
                },
                word_wrap=True,
            )
        """
        )

        ui.Spacer(height=10)
