## 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 omni.kit.test
import os
import sys
import unittest
import omni.kit.app
import omni.kit.window.property.managed_frame
from omni.kit.test.async_unittest import AsyncTestCase
import omni.usd

from omni.kit import ui_test
from pxr import Gf
from omni.kit.test_suite.helpers import (
    open_stage,
    get_test_data_path,
    select_prims,
    wait_stage_loading,
    arrange_windows
    )


class PropertyContextMenu(AsyncTestCase):
    # Before running each test
    async def setUp(self):
        await arrange_windows("Stage", 64)
        await open_stage(get_test_data_path(__name__, "usd/bound_shapes.usda"))
        omni.kit.window.property.managed_frame.reset_collapsed_state()
        omni.kit.window.property.managed_frame.set_collapsed_state("Property/Raw USD Properties", False)

    # After running each test
    async def tearDown(self):
        await wait_stage_loading()
        omni.kit.window.property.managed_frame.reset_collapsed_state()

    # @unittest.skipIf(sys.platform.startswith("linux"), "Pyperclip fails on some TeamCity agents")
    async def test_property_context_menu(self):
        await ui_test.find("Content").focus()

        stage_window = ui_test.find("Stage")
        await stage_window.focus()

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

        # get prim attributes
        cube_attr = stage.GetPrimAtPath("/World/Cube").GetAttribute('xformOp:translate')
        cone_attr = stage.GetPrimAtPath("/World/Cone").GetAttribute('xformOp:translate')

        # verify transforms different
        self.assertEqual(cube_attr.Get(), Gf.Vec3d(119.899608, -1.138346, -118.761261))
        self.assertEqual(cone_attr.Get(), Gf.Vec3d(  0.0,       0.0,         0.0))

        # select cube
        await select_prims(["/World/Cube"])
        await ui_test.human_delay()
        # scroll window to xformOp:translate
        ui_test.find("Property//Frame/**/Label[*].text=='xformOp:translate'").widget.scroll_here_y(0.5)
        await ui_test.human_delay()

        # right click on xformOp:translate
        await ui_test.find("Property//Frame/**/Label[*].text=='xformOp:translate'").click(right_click=True)
        await ui_test.human_delay()
        # context menu copy
        await ui_test.select_context_menu("Copy", offset=ui_test.Vec2(10, 10))

        # select cone
        await select_prims(["/World/Cone"])
        await ui_test.human_delay()
        # scroll window to xformOp:translate
        ui_test.find("Property//Frame/**/Label[*].text=='xformOp:translate'").widget.scroll_here_y(0.5)
        await ui_test.human_delay()

        # right click on xformOp:translate
        await ui_test.find("Property//Frame/**/Label[*].text=='xformOp:translate'").click(right_click=True)
        await ui_test.human_delay()
        # context menu paste
        await ui_test.select_context_menu("Paste", offset=ui_test.Vec2(10, 10))

        # verify transforms same
        self.assertEqual(cube_attr.Get(), Gf.Vec3d(119.899608, -1.138346, -118.761261))
        self.assertEqual(cone_attr.Get(), Gf.Vec3d(119.899608, -1.138346, -118.761261))

    async def test_property_context_menu_paste(self):
        await ui_test.find("Content").focus()

        stage_window = ui_test.find("Stage")
        await stage_window.focus()

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

        # select cube
        await select_prims(["/World/Cube"])
        await ui_test.human_delay(10)
        # scroll window to xformOp:translate
        ui_test.find("Property//Frame/**/Label[*].text=='xformOp:translate'").widget.scroll_here_y(0.5)
        await ui_test.human_delay()


        # verify code on clipbaord is NOT getting executed
        omni.kit.clipboard.copy("omni.kit.stage_templates.new_stage()")
        # right click on xformOp:translate
        await ui_test.find("Property//Frame/**/Label[*].text=='xformOp:translate'").click(right_click=True)
        await ui_test.human_delay()
        await ui_test.find("Property//Frame/**/Label[*].text=='xformOp:translate'").click()

        # if code was executed a new stage will have been created, so verify prims
        await ui_test.human_delay(250)
        prims = [prim.GetPath().pathString for prim in stage.TraverseAll() if not omni.usd.is_hidden_type(prim)]
        prims.sort()
        self.assertEqual(prims, ['/World', '/World/Cone', '/World/Cube', '/World/Cylinder', '/World/Looks', '/World/Looks/OmniGlass', '/World/Looks/OmniGlass/Shader', '/World/Looks/OmniPBR', '/World/Looks/OmniPBR/Shader', '/World/Looks/OmniSurface_Plastic', '/World/Looks/OmniSurface_Plastic/Shader', '/World/Sphere', '/World/defaultLight'])
