## 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.async_unittest import AsyncTestCase
from omni.kit import ui_test
from omni.kit.material.library.test_helper import MaterialLibraryTestHelper
from omni.kit.test_suite.helpers import (
    open_stage,
    get_test_data_path,
    select_prims,
    wait_stage_loading,
    arrange_windows
    )
from omni.kit.window.content_browser.test_helper import ContentBrowserTestHelper

PERSISTENT_SETTINGS_PREFIX = "/persistent"


class DragDropFilePropertyMaterialPath(AsyncTestCase):
    # Before running each test
    async def setUp(self):
        await arrange_windows("Stage", 64)
        await open_stage(get_test_data_path(__name__, "bound_material.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_drop_target_absolute(self):
        carb.settings.get_settings().set(PERSISTENT_SETTINGS_PREFIX + "/app/material/dragDropMaterialPath", "absolute")
        await ui_test.find("Stage").focus()
        await ui_test.find("Content").focus()

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

        # create prims
        omni.kit.commands.execute("CreatePrimWithDefaultXform", prim_type="Sphere")
        await select_prims(["/World/Sphere"])
        await ui_test.human_delay()

        # drag file from content window
        property_widget = ui_test.find("Property//Frame/**/Button[*].identifier=='preview_drop_target'")
        drag_target = property_widget.center

        async with ContentBrowserTestHelper() as content_browser_helper:
            mdl_path = get_test_data_path(__name__, "mtl/badname.mdl")
            await content_browser_helper.drag_and_drop_tree_view(mdl_path, drag_target=drag_target)

        # 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_combo_absolute(self):
        carb.settings.get_settings().set(PERSISTENT_SETTINGS_PREFIX + "/app/material/dragDropMaterialPath", "absolute")
        await ui_test.find("Stage").focus()
        await ui_test.find("Content").focus()

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

        # create prims
        omni.kit.commands.execute("CreatePrimWithDefaultXform", prim_type="Sphere")
        await select_prims(["/World/Sphere"])
        await ui_test.human_delay()

        # drag file from content window
        property_widget = ui_test.find("Property//Frame/**/StringField[*].identifier=='combo_drop_target'")
        drag_target = property_widget.center

        async with ContentBrowserTestHelper() as content_browser_helper:
            mdl_path = get_test_data_path(__name__, "mtl/badname.mdl")
            await content_browser_helper.drag_and_drop_tree_view(mdl_path, drag_target=drag_target)

        # 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_asset_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()

        await select_prims(["/World/Looks/OmniHair/Shader"])
        await wait_stage_loading()

        # drag file from content window
        property_widget = ui_test.find("Property//Frame/**/StringField[*].identifier=='sdf_asset_info:mdl:sourceAsset'")
        drag_target = property_widget.center

        async with ContentBrowserTestHelper() as content_browser_helper:
            mdl_path = get_test_data_path(__name__, "mtl/OmniHairTest.mdl")
            await content_browser_helper.drag_and_drop_tree_view(mdl_path, drag_target=drag_target)

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


    async def test_l1_drag_drop_path_drop_target_relative(self):
        carb.settings.get_settings().set(PERSISTENT_SETTINGS_PREFIX + "/app/material/dragDropMaterialPath", "relative")
        await ui_test.find("Stage").focus()
        await ui_test.find("Content").focus()

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

        # create prims
        omni.kit.commands.execute("CreatePrimWithDefaultXform", prim_type="Sphere")
        await select_prims(["/World/Sphere"])
        await ui_test.human_delay()

        # drag file from content window
        property_widget = ui_test.find("Property//Frame/**/Button[*].identifier=='preview_drop_target'")
        drag_target = property_widget.center

        async with ContentBrowserTestHelper() as content_browser_helper:
            mdl_path = get_test_data_path(__name__, "mtl/badname.mdl")
            await content_browser_helper.drag_and_drop_tree_view(mdl_path, drag_target=drag_target)

        # 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))


    async def test_l1_drag_drop_path_combo_relative(self):
        carb.settings.get_settings().set(PERSISTENT_SETTINGS_PREFIX + "/app/material/dragDropMaterialPath", "relative")
        await ui_test.find("Stage").focus()
        await ui_test.find("Content").focus()

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

        # create prims
        omni.kit.commands.execute("CreatePrimWithDefaultXform", prim_type="Sphere")
        await select_prims(["/World/Sphere"])
        await ui_test.human_delay()

        # drag file from content window
        property_widget = ui_test.find("Property//Frame/**/StringField[*].identifier=='combo_drop_target'")
        drag_target = property_widget.center

        async with ContentBrowserTestHelper() as content_browser_helper:
            mdl_path = get_test_data_path(__name__, "mtl/badname.mdl")
            await content_browser_helper.drag_and_drop_tree_view(mdl_path, drag_target=drag_target)

        # 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))


    async def test_l1_drag_drop_path_asset_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()

        await select_prims(["/World/Looks/OmniHair/Shader"])
        await wait_stage_loading()

        # drag file from content window
        property_widget = ui_test.find("Property//Frame/**/StringField[*].identifier=='sdf_asset_info:mdl:sourceAsset'")
        drag_target = property_widget.center

        async with ContentBrowserTestHelper() as content_browser_helper:
            mdl_path = get_test_data_path(__name__, "mtl/OmniHairTest.mdl")
            await content_browser_helper.drag_and_drop_tree_view(mdl_path, drag_target=drag_target)

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


    async def test_l1_drag_drop_path_drop_target_multi_absolute(self):
        carb.settings.get_settings().set(PERSISTENT_SETTINGS_PREFIX + "/app/material/dragDropMaterialPath", "absolute")
        await ui_test.find("Stage").focus()
        await ui_test.find("Content").focus()

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

        # create prims
        omni.kit.commands.execute("CreatePrimWithDefaultXform", prim_type="Sphere")
        await select_prims(["/World/Sphere"])
        await ui_test.human_delay()

        # drag file from content window
        property_widget = ui_test.find("Property//Frame/**/Button[*].identifier=='preview_drop_target'")
        drag_target = property_widget.center

        async with ContentBrowserTestHelper() as content_browser_helper:
            mdl_path = get_test_data_path(__name__, "mtl/multi_hair.mdl")
            await content_browser_helper.drag_and_drop_tree_view(mdl_path, drag_target=drag_target)
    
        async with MaterialLibraryTestHelper() as material_test_helper:
            await material_test_helper.handle_create_material_dialog(str(mdl_path), "OmniHair_Green")

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


    async def test_l1_drag_drop_path_drop_target_multi_relative(self):
        carb.settings.get_settings().set(PERSISTENT_SETTINGS_PREFIX + "/app/material/dragDropMaterialPath", "relative")
        await ui_test.find("Stage").focus()
        await ui_test.find("Content").focus()

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

        # create prims
        omni.kit.commands.execute("CreatePrimWithDefaultXform", prim_type="Sphere")
        await select_prims(["/World/Sphere"])
        await ui_test.human_delay()

        # drag file from content window
        property_widget = ui_test.find("Property//Frame/**/Button[*].identifier=='preview_drop_target'")
        drag_target = property_widget.center

        async with ContentBrowserTestHelper() as content_browser_helper:
            mdl_path = get_test_data_path(__name__, "mtl/multi_hair.mdl")
            await content_browser_helper.drag_and_drop_tree_view(mdl_path, drag_target=drag_target)

        async with MaterialLibraryTestHelper() as material_test_helper:
            await material_test_helper.handle_create_material_dialog(str(mdl_path), "OmniHair_Green")

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