## Copyright (c) 2022, 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.
##
import os
import omni.kit.app
import omni.usd
import carb

from omni.kit.test.teamcity import is_running_in_teamcity
import sys
import unittest

from omni.kit.test.async_unittest import AsyncTestCase
from omni.kit import ui_test
from omni.kit.test_suite.helpers import open_stage, get_test_data_path, wait_stage_loading, arrange_windows
from omni.kit.window.content_browser.test_helper import ContentBrowserTestHelper

PERSISTENT_SETTINGS_PREFIX = "/persistent"


class DragDropFileViewportPath(AsyncTestCase):
    # Before running each test
    async def setUp(self):
        await arrange_windows()
        await open_stage(get_test_data_path(__name__, "empty_stage.usda"))

    # After running each test
    async def tearDown(self):
        await wait_stage_loading()
        carb.settings.get_settings().set(PERSISTENT_SETTINGS_PREFIX + "/app/material/dragDropMaterialPath", "absolute")

    async def test_l1_drag_drop_path_viewport_absolute(self):
        carb.settings.get_settings().set(PERSISTENT_SETTINGS_PREFIX + "/app/material/dragDropMaterialPath", "absolute")

        usd_context = omni.usd.get_context()
        stage = usd_context.get_stage()

        viewport_window = ui_test.find("Viewport")
        await viewport_window.focus()

        # drag/drop from content browser to stage window
        async with ContentBrowserTestHelper() as content_browser_helper:
            mdl_path = get_test_data_path(__name__, "materials/badname.mdl")
            await content_browser_helper.drag_and_drop_tree_view(mdl_path, drag_target=viewport_window.center)

        # verify prims
        shader = omni.usd.get_shader_from_material(stage.GetPrimAtPath('/World/Looks/Ue4basedMDL'), False)
        self.assertTrue(bool(shader), "/World/Looks/Ue4basedMDL not found")
        asset = shader.GetSourceAsset("mdl")
        self.assertTrue(os.path.isabs(asset.path))


    async def test_l1_drag_drop_path_viewport_relative(self):
        carb.settings.get_settings().set(PERSISTENT_SETTINGS_PREFIX + "/app/material/dragDropMaterialPath", "relative")

        usd_context = omni.usd.get_context()
        stage = usd_context.get_stage()

        viewport_window = ui_test.find("Viewport")
        await viewport_window.focus()

        # drag/drop from content browser to stage window
        async with ContentBrowserTestHelper() as content_browser_helper:
            mdl_path = get_test_data_path(__name__, "materials/badname.mdl")
            await content_browser_helper.drag_and_drop_tree_view(mdl_path, drag_target=viewport_window.center)

        # verify prims
        shader = omni.usd.get_shader_from_material(stage.GetPrimAtPath('/World/Looks/Ue4basedMDL'), False)
        self.assertTrue(bool(shader), "/World/Looks/Ue4basedMDL not found")
        asset = shader.GetSourceAsset("mdl")
        self.assertFalse(os.path.isabs(asset.path))

    @unittest.skipIf(is_running_in_teamcity() and sys.platform.startswith("linux"), "OM-84020")
    async def test_l1_drag_drop_hilighting(self):
        from pathlib import Path
        import omni.kit.test
        from omni.kit.viewport.utility.tests.capture import capture_viewport_and_compare
        from carb.input import MouseEventType
        from carb.tokens import get_tokens_interface

        await ui_test.find("Content").focus()
        viewport_window = ui_test.find("Viewport")
        await viewport_window.focus()

        await open_stage(get_test_data_path(__name__, "bound_shapes.usda"))

        async with ContentBrowserTestHelper() as content_browser_helper:
            usd_path = get_test_data_path(__name__, "shapes").replace("\\", "/")
            await content_browser_helper.toggle_grid_view_async(False)
            selections = await content_browser_helper.select_items_async(usd_path, ["basic_cube.usda"])
            self.assertIsNotNone(selections)

            widget = await content_browser_helper.get_treeview_item_async(selections[-1].name)
            self.assertIsNotNone(widget)

            start_pos = widget.center
            pos_0 = viewport_window.center
            pos_1 = ui_test.Vec2(50, pos_0.y + 75)
            pos_2 = ui_test.Vec2(viewport_window.size.x - 50, pos_0.y - 25)
            wait_delay = 4
            drag_delay = 12
            await ui_test.input.emulate_mouse(MouseEventType.MOVE, start_pos)
            await ui_test.input.emulate_mouse(MouseEventType.LEFT_BUTTON_DOWN)
            await ui_test.human_delay(wait_delay)
            await ui_test.input.emulate_mouse_slow_move(start_pos, pos_0, human_delay_speed=drag_delay)
            await ui_test.human_delay(wait_delay)
            await ui_test.input.emulate_mouse_slow_move(pos_0, pos_1, human_delay_speed=drag_delay)
            await ui_test.human_delay(wait_delay)
            await ui_test.input.emulate_mouse_slow_move(pos_1, pos_2, human_delay_speed=drag_delay)
            await ui_test.input.emulate_mouse(MouseEventType.LEFT_BUTTON_UP)
            await ui_test.human_delay(wait_delay)

        EXTENSION_ROOT = Path(get_tokens_interface().resolve("${omni.kit.test_suite.viewport}")).resolve().absolute()
        GOLDEN_IMAGES = EXTENSION_ROOT.joinpath("data", "tests", "images")
        OUTPUTS_DIR = Path(omni.kit.test.get_test_output_path())

        passed, fail_msg = await capture_viewport_and_compare(image_name="test_l1_drag_drop_hilighting.png",
                                                              output_img_dir=OUTPUTS_DIR,
                                                              golden_img_dir=GOLDEN_IMAGES)
        self.assertTrue(passed, msg=fail_msg)
