# 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.
#
"""an example of creating a custom with shapes and drags window"""

# TODO : This need clean up for full documentation
from omni import ui

EXTENSION_NAME = "Brick Demo Window"

LIGHT_WINDOW_STYLE = {
    # main frame style
    "ScrollingFrame::canvas": {"background_color": 0xFFCACACA},
    "Frame::main_frame": {"background_color": 0xFFCACACA},
    # title bar style
    "Label::title": {"color": 0xFF777777, "font_size": 16.0},
    "Rectangle::titleBar": {"background_color": 0xFFCACACA},
    "Rectangle::timeSelection": {"background_color": 0xFF888888, "border_radius": 5.0},
    "Triangle::timeArrows": {"background_color": 0xFFCACACA},
    "Label::timeLabel": {"color": 0xFFDDDDDD, "font_size": 16.0},
    # custom widget slider
    "Rectangle::sunStudySliderBackground": {
        "background_color": 0xFFBBBBBB,
        "border_color": 0xFF888888,
        "border_width": 1.0,
        "border_radius": 10.0,
    },
    "Rectangle::sunStudySliderForground": {"background_color": 0xFF888888},
    "Circle::slider": {"background_color": 0xFFBBBBBB},
    "Circle::slider:hovered": {"background_color": 0xFFCCCCCC},
    "Circle::slider:pressed": {"background_color": 0xFFAAAAAA},
    "Triangle::selector": {"background_color": 0xFF888888},
    "Triangle::selector:hovered": {"background_color": 0xFF999999},
    "Triangle::selector:pressed": {"background_color": 0xFF777777},
    # toolbar
    "Triangle::play_button": {"background_color": 0xFF6E6E6E},
}

DARK_WINDOW_STYLE = {
    # main frame style
    "ScrollingFrame::canvas": {"background_color": 0xFF454545},
    "Frame::main_frame": {"background_color": 0xFF454545},
    # title bar style
    "Label::title": {"color": 0xFF777777, "font_size": 16.0},
    "Rectangle::titleBar": {"background_color": 0xFF454545},
    "Rectangle::timeSelection": {"background_color": 0xFF888888, "border_radius": 5.0},
    "Triangle::timeArrows": {"background_color": 0xFF454545},
    "Label::timeLabel": {"color": 0xFF454545, "font_size": 16.0},
    # custom widget slider
    "Rectangle::sunStudySliderBackground": {
        "background_color": 0xFF666666,
        "border_color": 0xFF333333,
        "border_width": 1.0,
        "border_radius": 10.0,
    },
    "Rectangle::sunStudySliderForground": {"background_color": 0xFF333333},
    "Circle::slider": {"background_color": 0xFF888888},
    "Triangle::selector": {"background_color": 0xFF888888},
    # toolbar
    "Triangle::play_button": {"background_color": 0xFF6E6E6E},
}


class BrickSunStudyWindow:
    """ example of sun study window using Omni::UI """

    def __init__(self):
        self._is_playing = False
        self._window_Frame = None

        self._time_selector_left_spacer = None

        self._slider_spacer = None
        self._slider_spacer_width = [200]

        self._start_time_offset = [200]
        self._start_time_label = None
        self._start_time = "8:00 AM"

        self._end_time_offset = [600]
        self._end_time_label = None
        self._end_time = "6:00 PM"

        self._time_of_day_offset = [200]
        self._mouse_press_position = [0, 0]

    def _play_pause_fn(self, x, y):
        """ """
        self._is_playing = not self._is_playing
        self._play_button.visible = not self._is_playing
        self._pause_button.visible = self._is_playing

    def _on_object_mouse_pressed(self, position, x, y):
        position[0] = x
        position[1] = y

    def on_placer_mouse_moved_both(self, placer, offset, position, x, y):
        # TODO: DPI is the problem we need to solve
        offset[0] += x - position[0]
        offset[1] += y - position[1]
        placer.offset_x = max(offset[0], 0)
        placer.offset_y = offset[1]
        self._on_object_mouse_pressed(position, x, y)

    def on_time_placer_mouse_moved_X(self, placer, offset, position, x, y):
        # TODO: DPI is the problem we need to solve
        offset[0] += x - position[0]
        offset[0] = max(offset[0], 0)
        placer.offset_x = offset[0]
        # this is not very correct but serve ok for this demo
        hours = int(offset[0] / 800 * 24)
        time = "AM"
        if hours > 12:
            hours = hours - 12
            time = "PM"

        self._current_time_label.text = f"{hours}:00 {time}"
        self._on_object_mouse_pressed(position, x, 0)

    def on_start_placer_mouse_moved_X(self, placer, offset, position, x, y):
        # TODO: DPI is the problem we need to solve
        offset[0] += x - position[0]
        offset[0] = max(offset[0], 0)
        placer.offset_x = offset[0]
        self._time_range_placer.offset_x = offset[0] + 50
        self._time_range_rectangle.width = ui.Pixel(self._end_time_offset[0] - self._start_time_offset[0] + 3)

        # this is not very correct but serve ok for this demo
        hours = int(offset[0] / 800 * 24)
        time = "AM"
        if hours > 12:
            hours = hours - 12
            time = "PM"
        self._start_time_label.text = f"{hours}:00 {time}"
        self._on_object_mouse_pressed(position, x, 0)

    def on_end_placer_mouse_moved_X(self, placer, offset, position, x, y):
        # TODO: DPI is the problem we need to solve
        offset[0] += x - position[0]
        offset[0] = max(offset[0], 0)
        placer.offset_x = offset[0]
        self._time_range_rectangle.width = ui.Pixel(self._end_time_offset[0] - self._start_time_offset[0] + 3)

        # this is not very correct but serve ok for this demo
        hours = int(offset[0] / 800 * 24)
        time = "AM"
        if hours > 12:
            hours = hours - 12
            time = "PM"

        self._end_time_label.text = f"{hours}:00 {time}"

        self._on_object_mouse_pressed(position, x, 0)

    def set_style_light(self, button):
        """ """
        self._window_Frame.set_style(LIGHT_WINDOW_STYLE)

    def set_style_dark(self, button):
        """ """
        self._window_Frame.set_style(DARK_WINDOW_STYLE)

    def _build_title_bar(self):
        """ return the title bar stack"""
        with ui.VStack():
            with ui.ZStack(height=30):
                ui.Rectangle(name="titleBar")
                # Title Bar
                with ui.HStack():
                    ui.Spacer(width=10, height=0)
                    with ui.VStack(width=0):
                        ui.Spacer(width=0, height=8)
                        ui.Label("Sun Study", name="title", width=0, alignment=ui.Alignment.LEFT)
                        ui.Spacer(width=0, height=ui.Fraction(1))

                    ui.Spacer(width=ui.Fraction(1))

                    with ui.VStack(width=0):
                        ui.Spacer(height=5)
                        with ui.HStack():
                            ui.Spacer(width=10, height=0)
                            ui.Image("resources/icons/Panel_Options@2x.png", width=20, height=20)
                            ui.Spacer(width=10)
                            ui.Image("resources/icons/Help@2x.png", width=20, height=20)
                            ui.Spacer(width=5)
                        ui.Spacer(height=5)
        # Shadow
        ui.Image("resources/icons/TitleBarShadow_wAlpha_v2.png", fill_policy=ui.FillPolicy.STRETCH, height=20)

    def _build_time_arrow(self, arrowAlignment):
        with ui.VStack(width=0):  # remove spacer with Fraction Padding
            ui.Spacer()
            ui.Triangle(name="timeArrows", width=12, height=12, alignment=arrowAlignment)
            ui.Spacer()

    def _build_start_time_selector(self):
        """ """
        selector_placer = ui.Placer(offset_x=self._start_time_offset[0])
        with selector_placer:
            with ui.VStack(
                width=80,
                mouse_pressed_fn=lambda x, y, b, a, c=self._mouse_press_position: self._on_object_mouse_pressed(
                    c, x, y
                ),
                mouse_moved_fn=lambda x, y, b, a: self.on_start_placer_mouse_moved_X(
                    selector_placer, self._start_time_offset, self._mouse_press_position, x, y
                ),
                opaque_for_mouse_events=True,
            ):  # SELECTOR START
                self._start_time_selector_stack = ui.ZStack()
                with self._start_time_selector_stack:
                    ui.Rectangle(height=25, name="timeSelection")
                    with ui.HStack(height=25):  # remove spacer with Padding
                        ui.Spacer(width=5)
                        self._build_time_arrow(ui.Alignment.LEFT_CENTER)
                        ui.Spacer(width=5)
                        self._start_time_label = ui.Label(
                            self._start_time, name="timeLabel", alignment=ui.Alignment.RIGHT_CENTER
                        )
                        ui.Spacer(width=5)

                with ui.HStack(height=20):  # Selector tip, Spacer will be removed wiht Padding
                    ui.Spacer()

                    def show_hide_start_time_selector():
                        self._start_time_selector_stack.visible = not self._start_time_selector_stack.visible

                    ui.Triangle(
                        width=10,
                        height=17,
                        name="selector",
                        alignment=ui.Alignment.CENTER_BOTTOM,
                        mouse_pressed_fn=lambda x, y, b, a: show_hide_start_time_selector(),
                    )

                    ui.Spacer()

    def _build_end_time_selector(self):
        self._end_time_placer = ui.Placer(offset_x=self._end_time_offset[0])
        with self._end_time_placer:
            with ui.VStack(
                width=80,
                mouse_pressed_fn=lambda x, y, b, a: self._on_object_mouse_pressed(
                    self._mouse_press_position, x, y
                ),
                mouse_moved_fn=lambda x, y, b, a: self.on_end_placer_mouse_moved_X(
                    self._end_time_placer, self._end_time_offset, self._mouse_press_position, x, y
                ),
                opaque_for_mouse_events=True,
            ):  # SELECTOR END
                self._end_time_selector_stack = ui.ZStack()
                with self._end_time_selector_stack:
                    ui.Rectangle(height=25, name="timeSelection")
                    with ui.HStack(height=25):
                        ui.Spacer(width=5)
                        self._end_time_label = ui.Label(
                            self._end_time, name="timeLabel", widthalignment=ui.Alignment.RIGHT_CENTER
                        )
                        ui.Spacer(width=5)
                        self._build_time_arrow(ui.Alignment.RIGHT_CENTER)
                        ui.Spacer(width=5)

                def show_hide_end_time_selector():
                    self._end_time_selector_stack.visible = not self._end_time_selector_stack.visible

                with ui.HStack(height=20):
                    ui.Spacer()
                    ui.Triangle(
                        width=10,
                        height=17,
                        name="selector",
                        alignment=ui.Alignment.CENTER_BOTTOM,
                        mouse_pressed_fn=lambda x, y, b, a: show_hide_end_time_selector(),
                    )
                    ui.Spacer()

    def _build_central_slider(self):
        """ """
        # custom slider Widget
        with ui.VStack(height=70):
            ui.Spacer(height=40)
            with ui.HStack():
                with ui.ZStack(height=20):
                    ui.Rectangle(name="sunStudySliderBackground")

                    self._time_range_placer = ui.Placer(offset_x=self._start_time_offset[0])
                    with self._time_range_placer:
                        self._time_range_rectangle = ui.Rectangle(name="sunStudySliderForground", width=500, height=30)

                    circle_placer = ui.Placer(offset_x=self._time_of_day_offset[0])
                    with circle_placer:
                        ui.Circle(
                            name="slider",
                            width=30,
                            height=30,
                            radius=10,
                            mouse_pressed_fn=lambda x, y, b, a: self._on_object_mouse_pressed(
                                self._mouse_press_position, x, y
                            ),
                            mouse_moved_fn=lambda x, y, b, a: self.on_time_placer_mouse_moved_X(
                                circle_placer, self._time_of_day_offset, self._mouse_press_position, x, y
                            ),
                            opaque_for_mouse_events=True,
                        )

    def _build_custom_slider(self):
        """ return the slider  stack"""
        side_padding = 50
        with ui.HStack(height=70):
            ui.Spacer(width=side_padding)  # from Padding (will be removed by Padding on the HStack)
            with ui.ZStack():

                self._build_central_slider()

                # Selectors
                with ui.ZStack(height=40):  # Selector Height
                    self._build_start_time_selector()
                    self._build_end_time_selector()

            ui.Spacer(width=side_padding)

    def _build_control_bar(self):
        """ """
        with ui.HStack(height=40):
            ui.Spacer(width=50)
            ui.Image("resources/icons/2x_Flyout@2x.png", width=25)
            ui.Spacer(width=10)
            ui.Image("resources/icons/Loop_off@2x.png", width=20)
            ui.Spacer(width=10)
            ui.Image("resources/icons/Share@2x.png", width=20)
            ui.Spacer(width=ui.Fraction(2))
            # with ui.ZStack():
            self._play_button = ui.Image(
                "resources/icons/Play@2x.png",
                height=30,
                width=30,
                mouse_pressed_fn=lambda x, y, button, modifier: self._play_pause_fn(x, y),
            )
            self._pause_button = ui.Image(
                "resources/icons/Pause@2x.png",
                height=30,
                width=30,
                mouse_pressed_fn=lambda x, y, button, modifier: self._play_pause_fn(x, y),
            )
            self._pause_button.visible = False
            ui.Spacer(width=ui.Fraction(1))
            with ui.HStack(width=120):
                self._current_time_label = ui.Label("9:30 AM", name="title")
                ui.Label(" October 21, 2019", name="title")
            ui.Spacer(width=30)

    def build_window(self):
        """ build the window for the Class"""
        self._window = ui.Window("Brick Sun Study", width=800, height=250, flags=ui.WINDOW_FLAGS_NO_TITLE_BAR)

        with self._window.frame:
            with ui.VStack():
                with ui.HStack(height=20):
                    ui.Label("Styling :  ", alignment=ui.Alignment.RIGHT_CENTER)
                    ui.Button("Light Mode", clicked_fn=lambda b=None: self.set_style_light(b))
                    ui.Button("Dark Mode", clicked_fn=lambda b=None: self.set_style_dark(b))
                    ui.Spacer()

                ui.Spacer(height=10)
                self._window_Frame = ui.ScrollingFrame(
                    style=LIGHT_WINDOW_STYLE,
                    name="canvas",
                    height=200,
                    horizontal_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_OFF,
                    vertical_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_OFF,
                )
                with self._window_Frame:
                    with ui.VStack(height=0):
                        # Build the toolbar for the window
                        self._build_title_bar()

                        ui.Spacer(height=10)

                        # build the custom slider
                        self._build_custom_slider()

                        ui.Spacer(height=10)

                        self._build_control_bar()

                        # botton Padding
                        ui.Spacer(height=10)

        return self._window
