
import carb
import omni.kit.test
import omni.usd
from omni.kit import ui_test

settings = carb.settings.get_settings()


class TestIRaySettingsUI(omni.kit.test.AsyncTestCase):

    async def setUp(self):
        super().setUp()
        # We need to trigger Iray load to get the default render-settings values written to carb.settings
        # Viewports state is valid without any open stage, and only loads renderer when stage is opened.
        await omni.usd.get_context().new_stage_async()
        await omni.kit.app.get_app().next_update_async()

    def get_render_setings_window(self):
        render_settings_window = ui_test.find("Render Settings")
        render_settings_window.widget.height = 600
        render_settings_window.widget.width = 600
        render_settings_window.widget.visible = True

        return render_settings_window

    async def test_bool_checkbox_setting(self):
        render_settings_window = self.get_render_setings_window()
        self.assertTrue(render_settings_window)
        setting_name = "/iray/device/cpuEnabled"

        #We don't have to set the renderer as we assume only IRay is loaded

        # Set initial value of the setting
        settings.set(setting_name, False)
        await omni.kit.app.get_app().next_update_async()

        #choose the "Iray" tab in tthe render settings main combo
        button = render_settings_window.find("Frame/VStack[0]/VStack[0]/ScrollingFrame[0]/ZStack[0]/CommonIRaySettingStack")
        self.assertTrue(button)
        await button.click()

        #Get the collapsable frame for Device Settings and open it
        collapsable_frame = render_settings_window.find("**/Device Settings")
        self.assertTrue(collapsable_frame)
        collapsable_frame.widget.collapsed = False
        await omni.kit.app.get_app().next_update_async()

        setting_hstack = collapsable_frame.find("/**/HStack_CPU_Enabled")
        self.assertTrue(isinstance(setting_hstack.widget, omni.ui.HStack))
        check_box = setting_hstack.find("**/CheckBox[0]")
        self.assertTrue(isinstance(check_box.widget, omni.ui.CheckBox))

        await check_box.click(human_delay_speed=10)
        setting_value = settings.get(setting_name)
        self.assertTrue(setting_value)

        await check_box.click(human_delay_speed=10)
        setting_value = settings.get(setting_name)
        self.assertFalse(setting_value)

    async def test_combo_box_setting(self):

        render_settings_window = self.get_render_setings_window()
        setting_name = "/rtx/iray/canvasType"

        #We don't have to set the renderer as we assume only IRay is loaded

        # Set initial value
        settings.set(setting_name, "result")
        await omni.kit.app.get_app().next_update_async()

        #choose the "Iray" tab in each case
        button = render_settings_window.find("Frame/VStack[0]/VStack[0]/ScrollingFrame[0]/ZStack[0]/CommonIRaySettingStack")
        await button.click()

        #Get the collapsable frame for Device Settings and open it
        collapsable_frame = render_settings_window.find("**/Render Settings")
        collapsable_frame.widget.collapsed = False
        await omni.kit.app.get_app().next_update_async()

        setting_hstack = collapsable_frame.find("/**/HStack_Canvas")
        self.assertTrue(isinstance(setting_hstack.widget, omni.ui.HStack))
        combo_box = setting_hstack.find("ComboBox[0]")
        self.assertTrue(isinstance(combo_box.widget, omni.ui.ComboBox))

        combo_box.model.get_item_value_model(None, 0).set_value(1)
        await omni.kit.app.get_app().next_update_async()
        await omni.kit.app.get_app().next_update_async()
        await omni.kit.app.get_app().next_update_async()
        await ui_test.human_delay(50)
        value = settings.get(setting_name)
        self.assertTrue(value == "diffuse", f"value is {value}")

    async def test_int_setting(self):

        render_settings_window = self.get_render_setings_window()
        setting_name = "/rtx/iray/progressive_rendering_max_samples"

        #We don't have to set the renderer as we assume only IRay is loaded

        # Set initial value
        settings.set(setting_name, 100)
        await omni.kit.app.get_app().next_update_async()
        await ui_test.human_delay(50)

        #choose the "Iray" tab in each case
        button = render_settings_window.find("Frame/VStack[0]/VStack[0]/ScrollingFrame[0]/ZStack[0]/CommonIRaySettingStack")
        await button.click()

        #Get the collapsable frame for Device Settings and open it
        collapsable_frame = render_settings_window.find("**/Scheduler Settings")
        collapsable_frame.widget.collapsed = False
        await omni.kit.app.get_app().next_update_async()

        setting_hstack = collapsable_frame.find("**/HStack_Samples_Limit")
        self.assertTrue(isinstance(setting_hstack.widget, omni.ui.HStack))

        slider = setting_hstack.find("IntDrag[0]")
        self.assertTrue(slider)
        self.assertTrue(isinstance(slider.widget, omni.ui.IntDrag))
        await ui_test.human_delay(50)
        await slider.input("200")
        setting_value = settings.get(setting_name)
        self.assertEqual(setting_value, 200)
