# 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 Workspaces"""

from omni import ui
from .doc_page import DocPage
import json

SPACING = 5


class WorkspaceDoc(DocPage):
    """document Workspace class"""

    def _undock(self, selection):
        if not selection:
            return

        for item in selection:
            item.window.undock()

    def _dock(self, left, right, position):
        if not left or not right:
            return

        target = right[0].window

        for item in left:
            item.window.dock_in(target, position)

    def _left(self, selection):
        if not selection:
            return

        for item in selection:
            item.window.position_x -= 100

    def _right(self, selection):
        if not selection:
            return

        for item in selection:
            item.window.position_x += 100

    def _set_visibility(self, selection, visible):
        if not selection:
            return

        for item in selection:
            if visible is not None:
                item.window.visible = visible
            else:
                item.window.visible = not item.window.visible

    def _dock_reorder(self, selection):
        if not selection:
            return

        docking_groups = [ui.Workspace.get_docked_neighbours(item.window) for item in selection]

        for group in docking_groups:
            # Reverse order
            for i, window in enumerate(reversed(group)):
                window.dock_order = i

    def _tabs(self, selection, visible):
        if not selection:
            return

        for item in selection:
            item.window.dock_tab_bar_visible = visible

    def _focus(self, selection):
        if not selection:
            return

        for item in selection:
            item.window.focus()
            break

    def create_doc(self, navigate_to=None):
        self._section_title("Workspace")

        self._caption("Controlling Windows", navigate_to)

        class WindowItem(ui.AbstractItem):
            def __init__(self, window):
                super().__init__()
                # Don't keep the window because it prevents the window from closing.
                self._window_title = window.title
                self.title_model = ui.SimpleStringModel(self._window_title)
                self.type_model = ui.SimpleStringModel(type(window).__name__)

            @property
            def window(self):
                return ui.Workspace.get_window(self._window_title)

        class WindowModel(ui.AbstractItemModel):
            def __init__(self):
                super().__init__()
                self._root = ui.SimpleStringModel("Windows")
                self.update()

            def update(self):
                self._children = [WindowItem(i) for i in ui.Workspace.get_windows()]
                self._item_changed(None)

            def get_item_children(self, item):
                if item is not None:
                    return []

                return self._children

            def get_item_value_model_count(self, item):
                return 2

            def get_item_value_model(self, item, column_id):
                if item is None:
                    return self._root

                if column_id == 0:
                    return item.title_model
                if column_id == 1:
                    return item.type_model

        self._window_model = WindowModel()
        self._tree_left = None
        self._tree_right = None

        with ui.VStack(style=self._style_system):
            ui.Button("Refresh", clicked_fn=lambda: self._window_model.update())
            with ui.HStack():
                ui.Button("Clear", clicked_fn=ui.Workspace.clear)
                ui.Button("Focus", clicked_fn=lambda: self._focus(self._tree_left.selection))
            with ui.HStack():
                ui.Button("Visibile", clicked_fn=lambda: self._set_visibility(self._tree_left.selection, True))
                ui.Button("Invisibile", clicked_fn=lambda: self._set_visibility(self._tree_left.selection, False))
                ui.Button("Toggle Visibility", clicked_fn=lambda: self._set_visibility(self._tree_left.selection, None))
            with ui.HStack():
                ui.Button(
                    "Dock Right",
                    clicked_fn=lambda: self._dock(
                        self._tree_left.selection, self._tree_right.selection, ui.DockPosition.RIGHT
                    ),
                )
                ui.Button(
                    "Dock Left",
                    clicked_fn=lambda: self._dock(
                        self._tree_left.selection, self._tree_right.selection, ui.DockPosition.LEFT
                    ),
                )
                ui.Button(
                    "Dock Top",
                    clicked_fn=lambda: self._dock(
                        self._tree_left.selection, self._tree_right.selection, ui.DockPosition.TOP
                    ),
                )
                ui.Button(
                    "Dock Bottom",
                    clicked_fn=lambda: self._dock(
                        self._tree_left.selection, self._tree_right.selection, ui.DockPosition.BOTTOM
                    ),
                )
                ui.Button(
                    "Dock Same",
                    clicked_fn=lambda: self._dock(
                        self._tree_left.selection, self._tree_right.selection, ui.DockPosition.SAME
                    ),
                )
                ui.Button("Undock", clicked_fn=lambda: self._undock(self._tree_left.selection))
            with ui.HStack():
                ui.Button("Move Left", clicked_fn=lambda: self._left(self._tree_left.selection))
                ui.Button("MoveRight", clicked_fn=lambda: self._right(self._tree_left.selection))
            with ui.HStack():
                ui.Button(
                    "Reverse Docking Tabs of Neighbours",
                    clicked_fn=lambda: self._dock_reorder(self._tree_left.selection),
                )
                ui.Button("Hide Tabs", clicked_fn=lambda: self._tabs(self._tree_left.selection, False))
                ui.Button("Show Tabs", clicked_fn=lambda: self._tabs(self._tree_left.selection, True))

        with ui.HStack(height=400):
            with ui.ScrollingFrame(
                horizontal_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_OFF,
                vertical_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_ON,
                style_type_name_override="TreeView",
            ):
                self._tree_left = ui.TreeView(self._window_model, column_widths=[ui.Fraction(1), 80])
            with ui.ScrollingFrame(
                horizontal_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_OFF,
                vertical_scrollbar_policy=ui.ScrollBarPolicy.SCROLLBAR_ALWAYS_ON,
                style_type_name_override="TreeView",
            ):
                self._tree_right = ui.TreeView(self._window_model, column_widths=[ui.Fraction(1), 80])

        self._caption("Capture Layout", navigate_to)

        def generate(label):
            dump = ui.Workspace.dump_workspace()
            label.text = json.dumps(dump, sort_keys=True, indent=4)

        def restore(label):
            dump = label.text
            ui.Workspace.restore_workspace(json.loads(dump))

        with ui.HStack(style=self._style_system):
            ui.Button("Generate", clicked_fn=lambda: generate(self._label))
            ui.Button("Restore", clicked_fn=lambda: restore(self._label))

        self._label = self._code("Press Generate to dump layout")

        # some padding at the bottom
        ui.Spacer(height=100)
