from omni.kit.widget.settings import SettingType
import omni.ui as ui
import carb
import omni.kit.app

from omni.rtx.window.settings.rtx_settings_stack import RTXSettingsStack
from omni.rtx.window.settings.settings_collection_frame import SettingsCollectionFrame
from omni.rtx.window.settings.rendersettingsdefaults import SettingsDefaultHandler

from .heatmap_bar import *

class DeviceSettingsFrame(SettingsCollectionFrame):
    def _build_ui(self):
        """ RTX - Accurate (Iray) Device Settings """
        # CPU
        self._add_setting(
            SettingType.BOOL, "CPU Enabled", "/iray/device/cpuEnabled", has_reset=False, tooltip="Enable/Disable CPU"
        )

        self._change_cb = omni.kit.app.SettingChangeSubscription("/iray/device/gpuCount", self._on_change)

        # GPU selection
        gpuCount = self._settings.get("/iray/device/gpuCount")
        if gpuCount is not None and gpuCount > 0:
            gpuCount = int(gpuCount)
            for deviceIdx in range(0, gpuCount):
                isAttachedToDisplay = self._settings.get("/iray/device/gpu" + str(deviceIdx) + "/isAttachedToDisplay")
                name = self._settings.get("/iray/device/gpu" + str(deviceIdx) + "/name")
                deviceName = "GPU " + str(deviceIdx) + " " + name + (" (display)" if isAttachedToDisplay else "")
                self._add_setting(
                    SettingType.BOOL,
                    deviceName,
                    "/iray/device/gpu" + str(deviceIdx) + "/enabled",
                    has_reset=False,
                    tooltip="Enable/Disable GPU " + str(deviceIdx),
                )
        else:
             ui.Label("GPU settings available when Iray is in use");


class SchedulerSettingsFrame(SettingsCollectionFrame):
    def _build_ui(self):
        iray_scheduler_mode_items = {"Interactive": "interactive", "Final Frame": "batch"}
        schedulerModeCombo = self._add_setting_combo(
            "Scheduler Mode",
            "/rtx/iray/scheduler_mode",
            iray_scheduler_mode_items,
            tooltip="Optimize for interactivity or faster convergence",
        )

        self._add_setting(
            SettingType.INT,
            "Samples Limit",
            "/rtx/iray/progressive_rendering_max_samples",
            -1,
            1048576,
            1000,
            tooltip="Stop rendering after this amount of samples (-1 means never stop)",
        )

        maxQualityEnabledWidget = self._add_setting(
            SettingType.BOOL,
            "Quality Limit Enabled",
            "/rtx/iray/progressive_rendering_quality_enabled",
            tooltip="Activate quality estimation (only available in Final Frame mode)",
        )

        maxQualityWidget = self._add_setting(
            SettingType.FLOAT,
            "Quality Limit",
            "/rtx/iray/progressive_rendering_quality",
            0.0,
            1.0,
            0.005,
            tooltip="Stop rendering when the image has reached this quality threshold between 0.0 and 1.0 (fully converged)",
        )

        clampSpp = self._settings.get("/rtx/iray/max_min_samples_per_update")
        if clampSpp is not None:
            if clampSpp <= 1:  # better 0, but setting range = (1,1) completely disables the UI control range
                clampSpp = 512

            self._add_setting(
                SettingType.INT,
                "Samples per Frame",
                "/rtx/iray/min_samples_per_update",
                1,
                clampSpp,
                tooltip="Render this many samples per frame",
            )


class RenderSettingsFrame(SettingsCollectionFrame):
    def _build_ui(self):
        canvas_type_items = {
            "Beauty": "result",
            "Diffuse": "diffuse",
            "Specular": "specular",
            "Glossy": "glossy",
            "Emission": "emission",
            "Custom LPE": "custom_lpe",
            "Alpha": "alpha",
            "Illuminance": "irradiance",
            "Luminance": "luminance",
            "Ray Length": "ray_length",
            "Depth": "depth",
            "Normal": "normal",
            "UVWs[0]": "texture_coordinate[0]",
            "UVWs[1]": "texture_coordinate[1]",
            "Material ID": "material_tag",
        }

        if self._settings.get("/rtx/iray/debugMotion") == True:
            canvas_type_items["Motion Vectors"] = "motion_vector";

        self._add_setting_combo(
            "Canvas", "/rtx/iray/canvasType", canvas_type_items, tooltip="Render specified canvas type"
        )

        self._change_cb = omni.kit.app.SettingChangeSubscription("/rtx/iray/canvasType", self._on_change)

        if self._settings.get("/rtx/iray/canvasType") == "diffuse":
            self._add_setting(
                SettingType.STRING,
                "LPE",
                "/rtx/iray/lpeDiffuse",
                tooltip="Diffuse light path expression",
        )

        if self._settings.get("/rtx/iray/canvasType") == "glossy":
            self._add_setting(
                SettingType.STRING,
                "LPE",
                "/rtx/iray/lpeGlossy",
                tooltip="Glossy light path expression",
        )

        if self._settings.get("/rtx/iray/canvasType") == "specular":
            self._add_setting(
                SettingType.STRING,
                "LPE",
                "/rtx/iray/lpeSpecular",
                tooltip="Specular light path expression",
        )

        if self._settings.get("/rtx/iray/canvasType") == "emission":
            self._add_setting(
                SettingType.STRING,
                "LPE",
                "/rtx/iray/lpeEmission",
                tooltip="Emissive light path expression",
        )

        if self._settings.get("/rtx/iray/canvasType") == "custom_lpe":
            self._add_setting(
                SettingType.STRING,
                "LPE",
                "/rtx/iray/lpeCustom",
                tooltip="Custom light path expression",
        )

        if self._settings.get("/rtx/iray/canvasType") == "alpha":
            self._add_setting(
                SettingType.STRING,
                "Alpha LPE",
                "/rtx/iray/lpeAlpha",
                tooltip="Alpha light path expression",
        )

        if self._settings.get("/rtx/iray/canvasType") == "irradiance":
            self._add_setting(
                SettingType.STRING,
                "Illuminance Value",
                "/iray/illuminanceVal",
                tooltip="The Illuminance value at the last clicked position",)

            self._add_setting(
                SettingType.BOOL, "Auto Range", "/rtx/iray/illuminanceAutoRange", tooltip="Enable/disable auto range",)

            self._change_cb_2 = omni.kit.app.SettingChangeSubscription("/rtx/iray/illuminanceAutoRange", self._on_change)

            if self._settings.get("/rtx/iray/illuminanceAutoRange") == True:
                self._add_setting(
                    SettingType.FLOAT,
                    "    Range Min",
                    "/iray/illuminanceMin",
                    tooltip="Min illuminance range value", has_reset=False)

                self._add_setting(
                    SettingType.FLOAT,
                    "    Range Max",
                    "/iray/illuminanceMax",
                    tooltip="Max illuminance range value", has_reset=False)
            else:
                self._add_setting(
                    SettingType.FLOAT,
                    "    User Range Min",
                    "/rtx/iray/illuminanceUserMin",
                    tooltip="User min illuminance range value")

                self._add_setting(
                    SettingType.FLOAT,
                    "    User Range Max",
                    "/rtx/iray/illuminanceUserMax",
                    tooltip="User max illuminance range value",)

            with ui.HStack():
                ui.Button("Show Illuminance Legend", clicked_fn=self._on_open_illuminance_bar)

        if self._settings.get("/rtx/iray/canvasType") == "luminance":
            self._add_setting(
                SettingType.STRING,
                "Luminance Value",
                "/iray/luminanceVal",
                tooltip="The luminance value at the last clicked position",)

            self._add_setting(
                SettingType.BOOL, "Auto Range", "/rtx/iray/luminanceAutoRange", tooltip="Enable/disable auto range",)

            self._change_cb_3 = omni.kit.app.SettingChangeSubscription("/rtx/iray/luminanceAutoRange", self._on_change)

            if self._settings.get("/rtx/iray/luminanceAutoRange") == True:
                self._add_setting(
                    SettingType.FLOAT,
                    "    Range Min",
                    "/iray/luminanceMin",
                    tooltip="Min luminance range value", has_reset=False)

                self._add_setting(
                    SettingType.FLOAT,
                    "    Range Max",
                    "/iray/luminanceMax",
                    tooltip="Max luminance range value", has_reset=False)
            else:
                self._add_setting(
                    SettingType.FLOAT,
                    "    User Range Min",
                    "/rtx/iray/luminanceUserMin",
                    tooltip="User min luminance range value")

                self._add_setting(
                    SettingType.FLOAT,
                    "    User Range Max",
                    "/rtx/iray/luminanceUserMax",
                    tooltip="User max luminance range value",)

            with ui.HStack():
                ui.Button("Show Luminance Legend", clicked_fn=self._on_open_luminance_bar)

        self._add_setting(
            SettingType.BOOL, "Denoiser", "/rtx/iray/optixDenoiser/enabled", tooltip="Enable/Disable Denoising"
        )

        self._add_setting(
            SettingType.BOOL,
            "Caustic Sampler",
            "/rtx/iray/iray_caustic_sampler",
            tooltip="Enable to improve the quality of caustics (can impact performance)",
        )

        self._add_setting(
            SettingType.BOOL,
            "Guided Sampling",
            "/rtx/iray/guided_sampling",
            tooltip="Enable to improve overall convergence speed, especially for indoor scenes"
        )

        self._add_setting(
            SettingType.BOOL,
            "Backplate Refraction",
            "/rtx/iray/refract_backplate",
            tooltip="Forces perfectly specular materials to respect the virtual backplate (in addition to the environment)",
        )

        # see LightTypes.hlslh for enum
        show_lights_settings = {
            "Per-Light Enable": 0,
            "Force Enable": 1,
            "Force Disable": 2
        }
        self._add_setting_combo("Light Visibility In Primary Rays", "/rtx/iray/showLights", show_lights_settings, tooltip="Specify how lights are made visible in primary rays")

    def _on_open_illuminance_bar(self):
        if not hasattr(self, '_illuminance_legend') or self._illuminance_legend is None:
            self._illuminance_legend = ui.Window("RTX - Accurate Illuminance Legend", width=400, height=100)
            self._illuminance_legend.set_visibility_changed_fn(self._on_illum_window_visibility_changed)
            with self._illuminance_legend.frame:
                with ui.VStack():
                    IrayHeatmapBarWidget(self._illuminance_legend, 400, 100, 5, "illumination")
        else:
            self._illuminance_legend.visible = True

    def _on_open_luminance_bar(self):
        if not hasattr(self, '_luminance_legend') or self._luminance_legend is None:
            self._luminance_legend = ui.Window("RTX - Accurate Luminance Legend", width=400, height=100)
            self._luminance_legend.set_visibility_changed_fn(self._on_lum_window_visibility_changed)
            with self._luminance_legend.frame:
                with ui.VStack():
                    IrayHeatmapBarWidget(self._luminance_legend, 400, 100, 5, "lumination")
        else:
            self._luminance_legend.visible = True

    def _on_illum_window_visibility_changed(self, val):
        pass

    def _on_lum_window_visibility_changed(self, val):
        pass

    def destroy(self):
        if hasattr(self, '_illuminance_legend') and self._illuminance_legend:
            self._illuminance_legend.destroy()
            self._illuminance_legend = None
        if hasattr(self, '_luminance_legend') and self._luminance_legend:
            self._luminance_legend.destroy()
            self._luminance_legend = None
        super().destroy()

class SpectralRenderSettingsFrame(SettingsCollectionFrame):
    def _build_ui(self):
        """ Spectral Rendering """

        self._add_setting(
            SettingType.BOOL,
            "Spectral Rendering",
            "/rtx/iray/iray_spectral_rendering",
            tooltip="Enable/Disable spectral rendering (light transport simulated on a continuous range of wavelengths)",
        )

        self._change_cb = omni.kit.app.SettingChangeSubscription("/rtx/iray/iray_spectral_rendering", self._on_change)
        if self._settings.get("/rtx/iray/iray_spectral_rendering"):

            iray_spectral_conversion_color_space_items = {
                "CIE XYZ": "xyz",
                "Rec.709/linear sRGB": "rec709",
                "Rec.2020": "rec2020",
                "ACES2065-1": "aces",
                "ACEScg": "acescg",
            }
            self._add_setting_combo(
                "Conversion Color Space",
                "/rtx/iray/iray_spectral_conversion_color_space",
                iray_spectral_conversion_color_space_items,
                tooltip="The color space of the color data (also used without spectral rendering if spectral data is provided)",
            )

            iray_spectral_conversion_intent_items = {"Natural": "natural", "Faithful": "faithful"}
            self._add_setting_combo(
                "Conversion Intent",
                "/rtx/iray/iray_spectral_conversion_intent",
                iray_spectral_conversion_intent_items,
                tooltip="Natural for more smoothness or Faithful for more compatibility with color rendering (only used with rec709 color space)",
            )

            iray_spectral_observer_items = {"CIE 1931 2 degree": "cie1931", "CIE 1964 10 degree": "cie1964"}
            self._add_setting_combo(
                "Color Matching",
                "/rtx/iray/iray_spectral_observer",
                iray_spectral_observer_items,
                tooltip="Specifies the color matching function to use",
            )

    def destroy(self):
        self._change_cb = None
        super().destroy()


class GroundSettingsFrame(SettingsCollectionFrame):
    def _build_ui(self):
        self._add_setting(
            SettingType.BOOL,
            "Enable",
            "/rtx/iray/environment_dome_ground",
            tooltip="Enable/Disable an implicit ground plane to catch shadows (requires a dome light in the scene)",
        )

        self._change_cb = omni.kit.app.SettingChangeSubscription("/rtx/iray/environment_dome_ground", self._on_change)
        if self._settings.get("/rtx/iray/environment_dome_ground"):

            self._add_setting(
                SettingType.COLOR3,
                "Reflectivity",
                "/rtx/iray/environment_dome_ground_reflectivity",
                tooltip="The amount of reflectivity of the ground plane",
            )
            self._add_setting(
                SettingType.FLOAT,
                "Glossiness",
                "/rtx/iray/environment_dome_ground_glossiness",
                0,
                10000000,
                100,
                tooltip="Sets the glossiness of the reflection from 0 (diffuse) to 10000000 (perfect mirror)",
            )
            self._add_setting(
                SettingType.FLOAT,
                "Shadow Intensity",
                "/rtx/iray/environment_dome_ground_shadow_intensity",
                0,
                2,
                0.01,
                tooltip="Controls shadow intensity where 0.0 is no shadow, 1.0 is normal shadow, and 2.0 is very heavy shadow",
            )
            self._add_setting(
                SettingType.DOUBLE3,
                "Position",
                "/rtx/iray/environment_dome_ground_position",
                tooltip="The origin of the ground plane",
            )
            self._add_setting(
                SettingType.DOUBLE3,
                "Rotation Axis",
                "/rtx/iray/environment_dome_rotation_axis",
                tooltip="Defines rotation axis and up vector of the ground plane, (0,1,0) for y-up scenes and (0,0,1) for z-up scenes",
            )
            self._add_setting(
                SettingType.FLOAT,
                "Environment Rotation",
                "/rtx/iray/environment_dome_rotation_angle",
                0,
                360,
                tooltip="Inexpensive rotation of the dome around the specified rotation axis from 0 to 360 degrees",
            )

    def destroy(self):
        self._change_cb = None
        super().destroy()

class IrayServerSettingsFrame(SettingsCollectionFrame):
    def _build_ui(self):

        self._change_cb = omni.kit.app.SettingChangeSubscription("/iray/iray_server/state", self._on_change)
        self._change_cb_2 = omni.kit.app.SettingChangeSubscription("/iray/iray_server/bridge_upload_message", self._on_change)
        #self._change_cb_2 = omni.kit.app.SettingChangeSubscription("/iray/iray_server/queue_state", self._on_change)
        #self._change_cb_3 = omni.kit.app.SettingChangeSubscription("/iray/iray_server/job_state", self._on_change)

        def do_connect():
            print("Connecting to server...")
            self._settings.set("/iray/iray_server/state", "connecting")
            self._settings.set("/iray/iray_server/connect", True)

        def do_cancel_connect():
            print("Cancelling connection to server...")
            self._settings.set("/iray/iray_server/connect", False)
            #self._settings.set("/iray/iray_server/state", "disconnected")

        def do_disconnect():
            print("Disconnecting from server...")
            self._settings.set("/iray/iray_server/connect", False)
            #self._settings.set("/iray/iray_server/state", "disconnected")
        
        def do_queue_connect():
            print("Connecting to Queue Manager...")
            self._settings.set("/iray/iray_server/queue_state", "connecting")
            self._settings.set("/iray/iray_server/queue_msg", "Connecting to server...")
            self._settings.set("/iray/iray_server/queue_connect", "true")

        def do_queue_disconnect():
            print("Disconnecting from Queue Manager...")
            self._settings.set("/iray/iray_server/queue_connect", "false")
            self._settings.set("/iray/iray_server/queue_state", "disconnected")
            self._settings.set("/iray/iray_server/queue_msg", "")
        
        def do_add_job():
            print("Adding server job...")
            self._settings.set("/iray/iray_server/add_job", True)
            self._settings.set("/iray/iray_server/queue_msg", "")

        def do_cancel_job():
            print("Cancling server job...")
            self._settings.set("/iray/iray_server/job_state", "idle")
            self._settings.set("/iray/iray_server/queue_msg", "")

        state = self._settings.get("/iray/iray_server/state")
        
        if state  == "disconnected" or state  == "error":

            self._add_setting(
                SettingType.STRING,
                "Server Address",
                "/rtx/iray/iray_server/address",
                tooltip="The address to the Iray Server to connect to",
            )

            self._add_setting(
                SettingType.INT,
                "Server Port",
                "/rtx/iray/iray_server/port",
                0,
                255,
                tooltip="The Iray Server port to connect to",
            )

            self._add_setting(
                SettingType.BOOL,
                "Use Encryption",
                "/rtx/iray/iray_server/ssl",
                tooltip="Enable ssl encrytion. Note that the server must be set up to support this.",
            )

            self._add_setting(
                SettingType.STRING,
                "User Name",
                "/rtx/iray/iray_server/user",
                tooltip="Iray Server user",
            )

            self._add_setting(
                SettingType.STRING,
                "Password",
                "/iray/iray_server/pwd",
                tooltip="Iray Server user password",
            )
            
        # Bridge streaming options
        #ui.Label("Streaming", alignment=ui.Alignment.CENTER)
        if state  == "connected":
            ui.Label("Connected to " + self._settings.get("/rtx/iray/iray_server/user") + "@" + self._settings.get("/rtx/iray/iray_server/address") + ":" + str(self._settings.get("/rtx/iray/iray_server/port")), style={"color": 0xFFFFFFFF});
            self._add_setting(SettingType.BOOL, "Cloud rendering","/iray/iray_server/cloud_rendering", tooltip="Enable cloud rendering.")
            if self._settings.get("/iray/iray_server/bridge_upload_state")  == "detecting":
                ui.Label("Detecting changes...");
            elif self._settings.get("/iray/iray_server/bridge_upload_state")  == "calculating": 
                ui.Label("Calculating hashes...");
            elif self._settings.get("/iray/iray_server/bridge_upload_state")  == "cache_status": 
                ui.Label("Querying cache status...");
            elif self._settings.get("/iray/iray_server/bridge_upload_state")  == "uploading": 
                ui.Label("Uploading data...");
            elif self._settings.get("/iray/iray_server/bridge_upload_state")  == "waiting": 
                ui.Label("Server processing data...");
            #else:
            #    ui.Label("Idle");
            ui.Label(self._settings.get("/iray/iray_server/bridge_upload_message"));
            ui.Button("Disconnect", tooltip="Disconnect from server", clicked_fn=do_disconnect, width=120)
        elif state  == "disconnected":
            ui.Button("Connect", tooltip="Connect to server", clicked_fn=do_connect, width=120)
        elif state  == "connecting":
            ui.Label("Connecting to server...");
            ui.Button("Cancel", tooltip="Cancel connection", clicked_fn=do_cancel_connect, width=100)
        elif state == None:
            ui.Label("Switch to Accurate to connect to Iray Server", word_wrap=True);
        else:
            ui.Label("Failed to connect:", word_wrap=True, style={"color": 0xFF0000FF});
            ui.Label(self._settings.get("/iray/iray_server/error_msg"));
            ui.Button("Connect", tooltip="Connect to server", clicked_fn=do_connect, width=120)

        # Queue manager options (currently not exposed)
        if False:
            ui.Label("Job Queue", alignment=ui.Alignment.CENTER)
            if self._settings.get("/iray/iray_server/queue_state")  == "disconnected":
                ui.Button("Connect", tooltip="Connect to Queue Manager", clicked_fn=do_queue_connect, width=120)
                ui.Label(self._settings.get("/iray/iray_server/queue_msg"));
            elif self._settings.get("/iray/iray_server/queue_state")  == "connected":
                ui.Button("Disconnect", tooltip="Disconnect from Queue Manager", clicked_fn=do_queue_disconnect, width=120)
                ui.Button("Add Job", tooltip="Add a job to the queue", clicked_fn=do_add_job, width=120)
                ui.Label(self._settings.get("/iray/iray_server/queue_msg"));
            else:
                ui.Button("Connect", tooltip="Connect to Queue Manager", clicked_fn=do_queue_connect, width=120)
                ui.Label(self._settings.get("/iray/iray_server/queue_msg"));

    def destroy(self):
        self._change_cb = None
        super().destroy()


class AdvancedSettingsFrame(SettingsCollectionFrame):
    def _build_ui(self):
        self._add_setting(
            SettingType.INT,
            "Max Path Length",
            "/rtx/iray/iray_max_path_length",
            0,
            500,
            tooltip="Limits the number of light path bounces that contribute to the result (-1 means no limit)",
        )

        self._add_setting(
            SettingType.BOOL,
            "Firefly Filter",
            "/rtx/iray/iray_firefly_filter",
            tooltip="Enable/disable the firefly filter",
        )

        iray_instancing_items = {"On": "on", "Off": "off", "Auto": "auto"}
        self._add_setting_combo(
            "Instancing",
            "/rtx/iray/iray_instancing",
            iray_instancing_items,
            tooltip="Off favors render speed, On favors interactivity when moving objects and saves memory when geometry is instanced, and Auto tries to balance this automatically",
        )

        self._add_setting(
            SettingType.INT,
            "Environment Resolution",
            "/rtx/iray/environment_lighting_resolution",
            64,
            8192,
            tooltip="The resolution to use for dome light baking",
        )

        self._add_setting(
            SettingType.INT,
            "Environment Sample Count",
            "/rtx/iray/environment_lighting_shader_samples",
            1,
            1024,
            tooltip="The sample count to use for dome light baking",
        )

        shadow_terminator_items = {"Off": "off", "On": "on", "Per Object" : "user"}
        self._add_setting_combo(
            "Smooth Shadow Terminator",
            "/rtx/iray/shadow_terminator_offset_mode",
            shadow_terminator_items,
            tooltip="Enable/disable to override the per-object boolean attribute that controls if shading artifacts of curved surfaces with low detail shoud be reduced (can cause other problems, so more detail should always be preferred)",
        )

        self._add_setting(
            SettingType.INT,
            "Max value for \"Samples per Frame\"",
            "/rtx/iray/max_min_samples_per_update",
            2,
            10240,
            tooltip="Limits the maximum number of iterations per frame that can be set",
        )

        iray_texture_compression_items = {"None": "none", "Medium": "medium", "High": "high"}
        self._add_setting_combo(
            "Texture Compression",
            "/rtx/iray/iray_texture_compression",
            iray_texture_compression_items,
            tooltip="Enable to reduces texture memory usage at the cost of visual quality",
        )

        self._add_setting(
            SettingType.BOOL,
            "Window Glass Optimization",
            "/rtx/iray/windowGlassOptimization",
            tooltip="Enable to get faster results when light is travelling through window panes, with the caveat of inconsistent shadowing in some corner cases",
        )

        self._add_setting(
            SettingType.BOOL,
            "Use Iray's built-in denoiser",
            "/rtx/iray/useBuiltinDenoiser",
            tooltip="When enabled, Iray's built-in denoiser is used. Temporal denoising is not available in this case.",
        )

        self._add_setting(
            SettingType.BOOL,
            "Temporal Denoising during Navigation",
            "/rtx/iray/temporalDenoiser",
            tooltip="When enabled, the temporal denoiser is used during navigation. The setting is ignored when denoising is disabled in the Rendering Options or Iray's built-in denoiser is used.",
        )

        self._add_setting(
            SettingType.BOOL,
            "Iray Selection Outline",
            "/rtx/iray/selection_outline",
            tooltip="Disable to skip rendering selection outlines for Iray.",
        )

        self._add_setting(
            SettingType.STRING,
            ".mi File Path",
            "/iray/export/exportFilename",
            tooltip="Absolute path to the .mi file to export (for example c:\\scenes\\test.mi)",
        )

        def do_export():
            print("Setting /iray/export/doExport=True setting for Iray..")
            self._settings.set("/iray/export/doExport", True)

        ui.Button("Export", tooltip="Export .mi file (experimental)", clicked_fn=do_export)


class CommonIRaySettingStack(RTXSettingsStack):
    def __init__(self) -> None:
        self._stack = ui.VStack(spacing=10, identifier=__class__.__name__)
        self._settings = carb.settings.get_settings()
        with self._stack:
            gpuCount = None
            if SettingsDefaultHandler().does_exist("/iray/device/gpuCount"):
                gpuCount = self._settings.get("/iray/device/gpuCount")
                if gpuCount is None:
                    ui.Label("Iray doesn't appear to be loaded....")
                    return

            DeviceSettingsFrame("Device Settings", parent=self)
            SchedulerSettingsFrame("Scheduler Settings", parent=self)
            RenderSettingsFrame("Render Settings", parent=self)
            SpectralRenderSettingsFrame("Spectral Rendering", parent=self)
            GroundSettingsFrame("Matte Ground Plane Settings", parent=self)
            IrayServerSettingsFrame("Iray Server Settings", parent=self)
            AdvancedSettingsFrame("Advanced", parent=self)
            ui.Spacer()
