# 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
    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
)
