#--------------------------------------------
#
#         CamiTK SDK Python binding 
#
#              Do not edit this file, unless
#              you really (really!) know
#              what you're doing
#
#--------------------------------------------


#--------------------------------------------
#
# Python binding requirements
#
#--------------------------------------------
# First of all needs : Python
find_package(PythonLibs REQUIRED)
# Then the Shiboken tool, the PySide team C++ to Python wrapper
find_package(Shiboken REQUIRED)
find_program(CAMITK_BINDING_PYTHON_GENERATOR shiboken REQUIRED)
if (NOT CAMITK_BINDING_PYTHON_GENERATOR)
    message(FATAL_ERROR "Please add Shiboken binary in your PATH or manually point to it using the CAMITK_BINDING_PYTHON_GENERATOR variable")
endif()

# And of course Qt and PySide, the Python binding of Qt (4.8) using Shiboken.
find_package(Qt4 REQUIRED)
find_package(PySide REQUIRED)

# TEST Using VTK dependency 
find_package(VTK REQUIRED)

#--------------------------------------------
#
# Recursively parse subdirectories for classes to expose
#
#--------------------------------------------
# Shiboken PATH to look for typesystem.xml and global.h files, recursively udapted
set(SHIBOKEN_TYPESYSTEM_PATH ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")
set(SHIBOKEN_GLOBAL_H_PATH ${CMAKE_CURRENT_SOURCE_DIR} CACHE INTERNAL "")

# include subdirectories
add_subdirectory(actions)
add_subdirectory(applications)
add_subdirectory(components)
add_subdirectory(libraries)

# TODO : Remove once debugged
# message(WARNING "PYSIDE_INCLUDE_DIR = ${PYSIDE_INCLUDE_DIR}")
# message(WARNING "SHIBOKEN_TYPESYSTEM_PATH = ${SHIBOKEN_TYPESYSTEM_PATH}")
# message(WARNING "SHIBOKEN_GLOBAL_H_PATH = ${SHIBOKEN_GLOBAL_H_PATH}")
# message(WARNING "QT_INCLUDE_DIR = ${QT_INCLUDE_DIR}")
# message(WARNING "QT_QTCORE_INCLUDE_DIR = ${QT_QTCORE_INCLUDE_DIR}")
# message(WARNING "SHIBOKEN_CAMITK_SDK_PATH = ${SHIBOKEN_CAMITK_SDK_PATH}")
# message(WARNING "VTK_INCLUDE_DIRS = ${VTK_INCLUDE_DIRS}")

#--------------------------------------------
#
# Custom CMake Python binding targets
#
#--------------------------------------------
# Shiboken specific paths
set(PYSIDE_INCLUDE_ALL_DIR_SHIBOKEN
    ${PYSIDE_INCLUDE_DIR}:${PYSIDE_INCLUDE_DIR}/QtCore:${PYSIDE_INCLUDE_DIR}/QtGui
    #:${PYSIDE_INCLUDE_DIR}/QtHelp:${PYSIDE_INCLUDE_DIR}/QtNetwork:${PYSIDE_INCLUDE_DIR}/QtOpenGL:${PYSIDE_INCLUDE_DIR}/QtScript:${PYSIDE_INCLUDE_DIR}/QtScriptTools:${PYSIDE_INCLUDE_DIR}/QtSql:${PYSIDE_INCLUDE_DIR}/QtSvg:${PYSIDE_INCLUDE_DIR}/QtTest:${PYSIDE_INCLUDE_DIR}/QtUiTools:${PYSIDE_INCLUDE_DIR}/QtWebKit:${PYSIDE_INCLUDE_DIR}/QtXml:${PYSIDE_INCLUDE_DIR}/QtXmlPatterns:${PYSIDE_INCLUDE_DIR}/QtDeclarative
)

# TODO : Remove once debugged
# message(WARNING "PYSIDE_INCLUDE_ALL_DIR_SHIBOKEN = ${PYSIDE_INCLUDE_ALL_DIR_SHIBOKEN}")

# Wrap the CamiTK SDK. Wrapping uses Shiboken (PySide binding tool)
# It means it decorates the specified C++ classes to Python by adding 
# information in order to convert it into a CPython extension
# Shiboken parses the typesystem.xml files to detect which C++ classes to expose to Python
# For each of them, it create a CPython C++ decorated class in the build directory
add_custom_target(  camitk-sdk-wrap-to-python
#                     OUTPUT ${lib_python_SRC}
                    COMMAND ${CMAKE_COMMAND} -E echo "Cleaning C++ classes generated from previous wrapping."    
                    COMMAND ${CMAKE_COMMAND} -E remove_directory camitk_sdk
                    COMMAND ${CMAKE_COMMAND} -E echo "Wrapping CamiTK SDK for Python exposure."    
                    COMMAND ${CAMITK_BINDING_PYTHON_GENERATOR} --enable-parent-ctor-heuristic --enable-return-value-heuristic --enable-pyside-extensions #--debug-level=full
                    ${CMAKE_CURRENT_SOURCE_DIR}/global_sdk.h
                    --include-paths=${PYSIDE_INCLUDE_ALL_DIR_SHIBOKEN}:${QT_INCLUDE_DIR}:${QT_QTCORE_INCLUDE_DIR}:${SHIBOKEN_GLOBAL_H_PATH}:${SHIBOKEN_CAMITK_SDK_PATH}:${VTK_INCLUDE_DIRS}
                    --typesystem-paths=${PYSIDE_TYPESYSTEMS}:${SHIBOKEN_TYPESYSTEM_PATH}
                    --output-directory=${CMAKE_CURRENT_BINARY_DIR}
                    ${CMAKE_CURRENT_SOURCE_DIR}/typesystem_sdk.xml
#                     WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
#                     COMMENT "Running generator for ${PROJECT_NAME}:"
                    COMMAND ${CMAKE_COMMAND} -E echo "CamiTK SDK wrapped." 
                  )
                  
# The resulting C++ wrapped classes will be listed in the following CMake variable:
file(GLOB_RECURSE SDK_WRAPPED_CLASSES ${CMAKE_BINARY_DIR}/python_sdk/camitk_sdk/*.cpp )

# We list the CamiTK SDK generated dynamic libraries for linking the python package
# TODO do not manually list those libraries, but dynamically create this list at configuration
# step, using CamiTK CMake macros
file(GLOB_RECURSE CAMITK_SDK_LIBRARIES ${CMAKE_BINARY_DIR}/*.so)
# message(WARNING "CAMITK_SDK_LIBRARIES = ${CAMITK_SDK_LIBRARIES}")

# This CMake target aims at compiling the C++ Python-wrapped classes of CamiTK and link them against
# the original CamiTK SDK libraries.
# WARNING Do not manually run this target, it requires another configure step wich is run by the camitk-sdk-package-to-python
# CMake target.
if(NOT SDK_WRAPPED_CLASSES STREQUAL "") # only create camitk_sdk target if camitk sdk has been wrapped
    set(PROJECT_NAME camitk_sdk) # the name of the camitk sdk package once compiled
    string(REPLACE ":" ";" CAMITK_SDK_INCLUDE_DIR ${SHIBOKEN_CAMITK_SDK_PATH}) # deduce the list of include directories of CamiTK SDK
    string(REPLACE ":" ";" PYSIDE_INCLUDE_ALL_DIR ${PYSIDE_INCLUDE_ALL_DIR_SHIBOKEN}) #deduce the list of include directories provided from PySide / Shiboken
    # Qt libraries dependencies
    set(QT_LIBRARIES "${QT_QTCORE_LIBRARY};${QT_QTGUI_LIBRARY}")
#     message(WARNING "QT_LIBRARIES = ${QT_LIBRARIES}")
    set(CAMITK_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/../sdk/libraries/core
                        ${CMAKE_CURRENT_BINARY_DIR}/../sdk/actions/mesh/basicmesh 
                        ${CMAKE_CURRENT_BINARY_DIR}/../sdk/actions/image/arbitraryslice ${CMAKE_CURRENT_BINARY_DIR}/../sdk/actions/image/cropvolume 
                        ${CMAKE_CURRENT_BINARY_DIR}/../sdk/actions/image/imagelut 
                        ${CMAKE_CURRENT_BINARY_DIR}/../sdk/actions/image/multipicking ${CMAKE_CURRENT_BINARY_DIR}/../sdk/actions/image/reconstruction
                        ${CMAKE_CURRENT_BINARY_DIR}/../sdk/actions/image/volumerendering
        ) #build directories required for ui wrapping includes !

    include_directories(${PROJECT_NAME} ${CAMITK_SDK_INCLUDE_DIR} ${PYSIDE_INCLUDE_ALL_DIR} ${SHIBOKEN_INCLUDE_DIR} ${PYTHON_INCLUDE_PATH} ${QT_INCLUDE_DIR} ${QT_QTCORE_INCLUDE_DIR} ${QT_QTGUI_INCLUDE_DIR} ${VTK_INCLUDE_DIRS} ${CMAKE_CURRENT_BINARY_DIR} ${CAMITK_BUILD_DIR})
    add_library(${PROJECT_NAME} SHARED  ${SDK_WRAPPED_CLASSES}) 
    # # set_property(TARGET ${PROJECT_NAME} PROPERTY PREFIX "")
    set_property(TARGET ${PROJECT_NAME} PROPERTY PREFIX "")
    target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES} ${VTK_LIBRARIES} ${PYSIDE_LIBRARY} ${SHIBOKEN_PYTHON_LIBRARIES} ${SHIBOKEN_LIBRARY} ${CAMITK_SDK_LIBRARIES})
    # WARNING  check VTK dependency
#     message(WARNING "SHIBOKEN_PYTHON_LIBRARIES = ${SHIBOKEN_PYTHON_LIBRARIES}")
#     message(WARNING "SHIBOKEN_LIBRARY = ${SHIBOKEN_LIBRARY}")
    # add_dependencies(${PROJECT_NAME} camitkcore)  
endif() 


# Create the Python package of CamiTK SDK
# This package is compiled from the generated C++ classes of the camitk-sdk-wrap-to-python target 
# and link against the CamiTK SDK libraries.
# Build the custom camitk-sdk-package-to-python target in order to compile the wrapped C++ classes and link against
# CamiTK SDK dynamic libraries.
add_custom_target(  camitk-sdk-package-to-python
                    COMMAND ${CMAKE_COMMAND} -E echo "Creating Python package of CamiTK SDK."   
                    COMMAND ${CMAKE_COMMAND} ${CMAKE_BINARY_DIR}
                    COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target camitk_sdk
                    COMMAND ${CMAKE_COMMAND} -E echo "CamiTK SDK Python package created." 
                 )
add_dependencies(camitk-sdk-package-to-python camitk-sdk-wrap-to-python) # need to wrapp before creating the package
