# FindOpenUSD.cmake
# Finds OpenUSD installation and sets up necessary variables
#
# This module defines:
#  OpenUSD_FOUND - System has OpenUSD
#  OpenUSD_INCLUDE_DIRS - OpenUSD include directories
#  OpenUSD_LIBRARIES - Libraries needed to use OpenUSD
#  OpenUSD_LIBRARY_DIR - Directory containing OpenUSD libraries
#  OpenUSD_VERSION - Version of OpenUSD found

# Look for OpenUSD root
find_path(OpenUSD_ROOT_DIR
    NAMES include/pxr/pxr.h lib/usd_usd.lib
    PATHS
        ${CMAKE_PREFIX_PATH}
        $ENV{OpenUSD_ROOT}
    DOC "OpenUSD root directory"
)

if(OpenUSD_ROOT_DIR)
    set(OpenUSD_INCLUDE_DIR "${OpenUSD_ROOT_DIR}/include")
    set(OpenUSD_LIBRARY_DIR "${OpenUSD_ROOT_DIR}/lib")
    set(OpenUSD_BIN_DIR "${OpenUSD_ROOT_DIR}/lib")
endif()

# Find Python 3.12 (required by this USD build)
find_path(Python312_INCLUDE_DIR
    NAMES Python.h
    PATHS
        "$ENV{LOCALAPPDATA}/Programs/Python/Python312/include"
        "C:/Python312/include"
        "C:/Program Files/Python312/include"
    DOC "Python 3.12 include directory"
    NO_DEFAULT_PATH
)

find_path(Python312_LIBRARY_DIR
    NAMES python312.lib
    PATHS
        "$ENV{LOCALAPPDATA}/Programs/Python/Python312/libs"
        "C:/Python312/libs"
        "C:/Program Files/Python312/libs"
    DOC "Python 3.12 library directory"
    NO_DEFAULT_PATH
)

# Core USD libraries needed for the project
set(OpenUSD_REQUIRED_LIBS
    arch
    tf
    gf
    vt
    work
    plug
    trace
    sdf
    pcp
    usd
    usdGeom
    usdLux
    usdShade
    usdVol
    usdImaging
    usdImagingGL
    hdx
    hd
    hdSt
    hf
    hgi
    hgiGL
    glf
    hio
    ar
    kind
    ndr
    sdr
    python
    cameraUtil
)

# Dependency libraries bundled with USD
set(OpenUSD_DEP_LIBS
    tbb
    tbbmalloc
    Imath-3_1
    osdCPU
)

# Find USD libraries
set(OpenUSD_LIBRARIES "")
foreach(lib ${OpenUSD_REQUIRED_LIBS})
    find_library(OpenUSD_${lib}_LIBRARY
        NAMES usd_${lib}
        PATHS ${OpenUSD_LIBRARY_DIR}
        NO_DEFAULT_PATH
    )
    
    if(OpenUSD_${lib}_LIBRARY)
        list(APPEND OpenUSD_LIBRARIES ${OpenUSD_${lib}_LIBRARY})
    else()
        message(WARNING "Could not find OpenUSD library: usd_${lib}")
    endif()
endforeach()

# Find dependency libraries
foreach(lib ${OpenUSD_DEP_LIBS})
    find_library(OpenUSD_dep_${lib}_LIBRARY
        NAMES ${lib}
        PATHS ${OpenUSD_LIBRARY_DIR}
        NO_DEFAULT_PATH
    )
    
    if(OpenUSD_dep_${lib}_LIBRARY)
        list(APPEND OpenUSD_LIBRARIES ${OpenUSD_dep_${lib}_LIBRARY})
    endif()
endforeach()

# Find Python library
if(Python312_LIBRARY_DIR)
    find_library(Python312_LIBRARY
        NAMES python312
        PATHS ${Python312_LIBRARY_DIR}
        NO_DEFAULT_PATH
    )
    if(Python312_LIBRARY)
        list(APPEND OpenUSD_LIBRARIES ${Python312_LIBRARY})
    endif()
endif()

# Try to find version from pxr.h
if(OpenUSD_INCLUDE_DIR AND EXISTS "${OpenUSD_INCLUDE_DIR}/pxr/pxr.h")
    file(STRINGS "${OpenUSD_INCLUDE_DIR}/pxr/pxr.h" _version_line 
         REGEX "^#define PXR_VERSION ")
    if(_version_line)
        string(REGEX REPLACE "^#define PXR_VERSION ([0-9]+).*" "\\1" OpenUSD_VERSION "${_version_line}")
    endif()
endif()

# Handle standard find_package arguments
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OpenUSD
    REQUIRED_VARS
        OpenUSD_INCLUDE_DIR
        OpenUSD_LIBRARY_DIR
        OpenUSD_LIBRARIES
    VERSION_VAR OpenUSD_VERSION
)

if(OpenUSD_FOUND)
    set(OpenUSD_INCLUDE_DIRS 
        ${OpenUSD_INCLUDE_DIR}
    )
    
    # Add Python include if found
    if(Python312_INCLUDE_DIR)
        list(APPEND OpenUSD_INCLUDE_DIRS ${Python312_INCLUDE_DIR})
    endif()
    
    # Create imported target
    if(NOT TARGET OpenUSD::OpenUSD)
        add_library(OpenUSD::OpenUSD INTERFACE IMPORTED)
        set_target_properties(OpenUSD::OpenUSD PROPERTIES
            INTERFACE_INCLUDE_DIRECTORIES "${OpenUSD_INCLUDE_DIRS}"
            INTERFACE_LINK_LIBRARIES "${OpenUSD_LIBRARIES}"
        )
        
        # Add required compile definitions for USD
        target_compile_definitions(OpenUSD::OpenUSD INTERFACE
            NOMINMAX
        )
    endif()
    
    message(STATUS "Found OpenUSD: ${OpenUSD_INCLUDE_DIR}")
    message(STATUS "OpenUSD Libraries: ${OpenUSD_LIBRARY_DIR}")
    message(STATUS "OpenUSD Binaries: ${OpenUSD_BIN_DIR}")
    if(Python312_INCLUDE_DIR)
        message(STATUS "Python 3.12: ${Python312_INCLUDE_DIR}")
    endif()
    if(OpenUSD_VERSION)
        message(STATUS "OpenUSD Version: ${OpenUSD_VERSION}")
    endif()
endif()

mark_as_advanced(
    OpenUSD_INCLUDE_DIR
    OpenUSD_LIBRARY_DIR
    Python312_INCLUDE_DIR
    Python312_LIBRARY_DIR
)
