// Copyright (c) 2018-2023, 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.
//
#pragma once

#include <omni/kit/KitTypes.h>

#include <functional>

namespace omni
{
namespace usd
{

typedef uint64_t SubscriptionId;

/**
 * Defines the USD state types.
 */
enum class StageState
{
    eClosed, ///! USD is closed/unopened.
    eOpening, ///! USD is opening.
    eOpened, ///! USD is opened.
    eClosing ///! USD is closing.
};

/**
 * Defines the usd event types.
 */
enum class StageEventType
{
    eSaved, ///! USD file saved.
    eSaveFailed, ///! Failed to save USD.
    eOpening, ///! USD stage is opening.
    eOpened, ///! USD stage is opened successfully.
    eOpenFailed, ///! USD stage failed to open.
    eClosing, ///! USD stage is about to close. This is a good opportunity to shutdown anything depends on USD stage.
    eClosed, ///! USD stage is fully closed.
    eSelectionChanged, ///! USD Prim selection has changed.
    eAssetsLoaded, ///! Current batch of async asset loading has been completed.
    eAssetsLoadAborted, ///! Current batch of async asset loading has been aborted.
    eGizmoTrackingChanged, ///! Started or stopped tracking (hovering) on a gizmo
    eMdlParamLoaded, ///! MDL parameter is loaded for a MDL UsdShadeShader.
    eSettingsLoaded, /// Stage settings have loaded
    eSettingsSaving, /// Stage settings are being saved
    eOmniGraphStartPlay, /// OmniGraph play has started
    eOmniGraphStopPlay, /// OmniGraph play has stopped
    eSimulationStartPlay, /// Simulation play has started
    eSimulationStopPlay, /// Simulation play has stopped
    eAnimationStartPlay, /// Animation playback has started
    eAnimationStopPlay, /// Animation playback has stopped
    eDirtyStateChanged, /// Dirty state of USD stage has changed. Dirty state means if it has unsaved changes or not.
    eAssetsLoading, ///! A new batch of async asset loading has started.
    eActiveLightsCountChanged, ///! Number of active lights in the scene has changed. This signal should be triggered
                               /// every time a scene has been loaded or number of lights has been changed. A few
                               /// features, for instance view lighting mode, need to detect when a number of active
                               /// lights becomes zero / become non-zero.
    eHierarchyChanged, ///! USD stage hierarchy has changed.
    eHydraGeoStreamingStarted, ///! Fabric Scene Delegate sends this when starting to stream rprims.
    eHydraGeoStreamingStopped, ///! Fabric Scene Delegate sends this when stopping to stream rprims.
    eHydraGeoStreamingStoppedNotEnoughMem, ///! Fabric Scene Delegate sends this when geometry streaming stops loading more geometry because of insufficient device memory
    eHydraGeoStreamingStoppedAtLimit, ///! Fabric Scene Delegate sends this when stopping to stream rprims because of the limit set by the user.
    eSaving, ///! Saving is in progress
};

enum class StageRenderingEventType
{
    eNewFrame, ///! New frame available for Viewport, params are ViewportHandle, FrameNo, RenderResults
    /// Frames complete for a single hydra engine render() invocation.
    /// Payload is {
    ///     render_results: [ { viewport_handle: ViewportHandle, product: HydraRenderProduct*, subframe_count: int32_t } ],
    ///     average_frame_time_ns: float,
    ///     swh_frame_number: uint64_t,
    /// }
    eHydraEngineFramesComplete,
    /// Frames added to the GPU queue for a single hydra engine.
    /// This event signifies that the frame is scheduled for GPU rendering and has not been rendered yet.
    /// The payload structure is the same as eHydraEngineFramesComplete.
    eHydraEngineFramesAdded,
};

using OnStageResultFn = std::function<void(bool result, const char* err)>;
using OnLayersSavedResultFn =
    std::function<void(bool result, const char* err, const std::vector<std::string>& savedLayers)>;
using OnPickingCompleteFn = std::function<void(const char* path, const carb::Double3* worldPos)>;

}
}
