# This file is a hacked CMakeLists.txt from ParaView/Octave
# Thanks to Brad King.

PROJECT(OCTAVIZ)

## added from cmake FAQ, JJS 3/29/05; also needs the file cmake_uninstall.cmake.in
CONFIGURE_FILE(
  "${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in"
  "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
  IMMEDIATE @ONLY)

ADD_CUSTOM_TARGET(uninstall
  "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake")
##

OPTION(USE_PREC_HEADERS "Use precompiled headers" OFF)

OPTION(WARN_ABOUT_DEPRECATED  "Set -Wno-deprecated. If using precompiled headers, this must be set to the same value that was used when compiling VTK." ON )
IF(WARN_ABOUT_DEPRECATED)
  SET(WNODEPRECATED "-Wno-deprecated" CACHE STRING "Pass -Wno-deprecated to gcc.")
ENDIF(WARN_ABOUT_DEPRECATED)


# If the octaviz library is put outside Octave's library path, the
# .oct file need an rpath 
#
# This is mainly for packagers who want to put the library into a path
# independent of the current Octave version, ie /usr/lib/octaviz
SET(OCTAVIZ_RPATH "" CACHE PATH "rpath for inclusion into the compiled .oct files")
MARK_AS_ADVANCED(OCTAVIZ_RPATH)


SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} /usr/local/lib/vtk /usr/lib/vtk)

FIND_PACKAGE(VTK)
IF(NOT VTK_FOUND)
  MESSAGE(FATAL_ERROR "VTK is required.  Please set VTK_DIR.")
ENDIF(NOT VTK_FOUND)

# load the needed compiler and linker settings to use VTK.
INCLUDE(${VTK_USE_FILE})

FIND_PACKAGE(X11)
IF(NOT X11_FOUND)
  MESSAGE(FATAL_ERROR "X11 is required.  Please install X11 development libraries.")
ENDIF(NOT X11_FOUND)
LINK_LIBRARIES(${X11_LIBRARIES} Xt)

# find octave-config and get variables from it
FIND_PROGRAM(OCTAVE_CONFIG octave-config)
IF(NOT OCTAVE_CONFIG)
  MESSAGE(FATAL_ERROR "Octave is required, but octave-config was not found.  Please install Octave and rerun cmake.")
ENDIF(NOT OCTAVE_CONFIG)

EXECUTE_PROCESS(COMMAND ${OCTAVE_CONFIG} --oct-site-dir 
  OUTPUT_VARIABLE OCT_SITE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
EXECUTE_PROCESS(COMMAND ${OCTAVE_CONFIG} --m-site-dir 
  OUTPUT_VARIABLE M_SITE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
EXECUTE_PROCESS(COMMAND ${OCTAVE_CONFIG} -p OCTINCLUDEDIR 
  OUTPUT_VARIABLE OCTINCLUDEDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
EXECUTE_PROCESS(COMMAND ${OCTAVE_CONFIG} -p OCTLIBDIR 
  OUTPUT_VARIABLE OCTLIBDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
    

FIND_PROGRAM(MKOCTFILE mkoctfile)
IF(NOT MKOCTFILE)
  MESSAGE(FATAL_ERROR "mkoctfile was not found. If you installed Octave from a distribution package, please check if there are any devel packages for it (normally named '-dev' or '-devel')")
ENDIF(NOT MKOCTFILE)
EXECUTE_PROCESS(COMMAND ${MKOCTFILE} -p ALL_CXXFLAGS 
  OUTPUT_VARIABLE ALL_CXXFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
EXECUTE_PROCESS(COMMAND ${MKOCTFILE} -p XTRA_CXXFLAGS 
  OUTPUT_VARIABLE XTRA_CXXFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
# -mieee-fp
EXECUTE_PROCESS(COMMAND ${MKOCTFILE} -p CXXPICFLAG 
  OUTPUT_VARIABLE CXXPICFLAG OUTPUT_STRIP_TRAILING_WHITESPACE)
# -fPIC
EXECUTE_PROCESS(COMMAND ${MKOCTFILE} -p CXXFLAGS 
  OUTPUT_VARIABLE CXXFLAGS OUTPUT_STRIP_TRAILING_WHITESPACE)
# -O2
EXECUTE_PROCESS(COMMAND ${MKOCTFILE} -p CXX 
  OUTPUT_VARIABLE OCTAVE_CXX OUTPUT_STRIP_TRAILING_WHITESPACE)
SET(CMAKE_CXX_COMPILER ${OCTAVE_CXX})


# Make the values accessible from other CMakeLists.txt files
# Also, this allows packagers to override the default values 
SET(OCTAVIZ_OCT_DIR ${OCT_SITE_DIR}/octaviz CACHE PATH ".oct files from Octaviz")
SET(OCTAVIZ_M_DIR ${M_SITE_DIR}/octaviz CACHE PATH ".m files from Octaviz")
SET(OCTAVIZ_EXAMPLES_DIR ${OCTAVIZ_M_DIR}/Examples CACHE PATH "Example .m files from Octaviz")
SET(OCTAVIZ_SHARED_DIR ${OCTLIBDIR} CACHE PATH "shared libraries from Octaviz")

# Build the vtkOctave wrapping utility first.
ADD_SUBDIRECTORY(Wrapping)

# Macro to create Octave wrapper functions
MACRO(OCTAVE_WRAP_VTK kit)
  STRING(TOUPPER ${kit} ukit)
  
  INCLUDE(${VTK_KITS_DIR}/vtk${kit}Kit.cmake)

  # what we don't want or can't build;
  # this is an ugly hack[TM] and should be fixed by e.g.
  # including a list of not-to-be-built-functions shipped with
  # Octaviz
  # see http://public.kitware.com/pipermail/vtkusers/2004-November/077447.html
  SET(CANNOT_BUILD vtkLongLongArray vtkSignedCharArray vtkUnsignedLongLongArray)
  IF(APPLE)
    # Mac OS X will not compile these as well.  Will exclude until a better
    # solution is determined
    SET(CANNOT_BUILD ${CANNOT_BUILD} 
      vtkStreamTracer vtkTensorGlyph vtkDEMReader vtkTIFFWriter 
      vtkCameraInterpolator vtkQuaternionInterpolator vtkTransformInterpolator 
      vtkProjectedTerrainPath vtkImagePlaneWidget vtkDistributedStreamTracer 
      vtkPStreamTracer)
  ENDIF(APPLE)

  FOREACH(class ${CANNOT_BUILD})
    SET(VTK_CLASS_WRAP_EXCLUDE_${class} 1 CACHE INTERNAL "We can't build ${class}" FORCE)
  ENDFOREACH(class)


  # There are some header files in the Common/ directory that we need
  # Add binary directory before source directory for the precompiled headers
  SET(INCLUDE_FLAGS -I${VTK_${ukit}_HEADER_DIR} -I${CMAKE_BINARY_DIR}/Common -I${CMAKE_SOURCE_DIR}/Common)
  SET(LINK_FLAGS -L${X11_LIBRARY_DIR} -lX11 -lXt 
    -L${VTK_LIBRARY_DIRS} -lvtkCommon  -lvtk${kit} -lvtkFiltering -lvtkGraphics
    -L${CMAKE_BINARY_DIR}/Common -loctaviz)

  SET(COMPILERFLAGS ${CXXFLAGS} ${CXXPICFLAG} ${XTRA_CXXFLAGS} ${WNODEPRECATED} 
    -I${OCTINCLUDEDIR} -I${OCTINCLUDEDIR}/octave
    ${INCLUDE_FLAGS})
  SEPARATE_ARGUMENTS(COMPILERFLAGS)
  # Combine all flags, so that each compiler run gets them in the same
  # order; this seems necessary for precompiled headers
  # SEPARATE_ARGUMENTS is necessary, otherwise cmake combines the flag into one
  # long string and escapes it when passing to g++ later => bug
  
  # Precompiled headers
  IF(USE_PREC_HEADERS)
    # Which flags will mkoctfile use?
    SET (PCHFLAGS "-Winvalid-pch")
    
    SET(GCH_HEADER ${OCTAVIZ_BINARY_DIR}/Common/OctavizCommon.h.gch)
      # type path of file only once
    
    ADD_CUSTOM_COMMAND(OUTPUT ${GCH_HEADER} 
      COMMAND ${CMAKE_CXX_COMPILER} 
        ARGS -c ${PCHFLAGS} ${COMPILERFLAGS}
        "-o" ${GCH_HEADER}
        ${OCTAVIZ_SOURCE_DIR}/Common/OctavizCommon.h
        VERBATIM)
  ENDIF(USE_PREC_HEADERS)

  SET ( all_o "" )
  SET ( all_oct "" )
  # track compiled object and .oct files for dependencies

  FOREACH(class ${VTK_${ukit}_CLASSES})
    SET(full_name "${VTK_${ukit}_HEADER_DIR}/${class}.h")
    IF(NOT VTK_CLASS_WRAP_EXCLUDE_${class})
      # create individual .cc files

      ADD_CUSTOM_COMMAND(
        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${class}.cc 
        DEPENDS vtkWrapOctave 
        COMMAND ${CMAKE_BINARY_DIR}/Wrapping/vtkWrapOctave 
        ARGS ${full_name} ${CMAKE_SOURCE_DIR}/Wrapping/hints 1 ${CMAKE_CURRENT_BINARY_DIR}/${class}.cc 
        COMMENT "Generating ${CMAKE_CURRENT_BINARY_DIR}/${class}.cc from ${full_name}"
        VERBATIM)
      
      # compile individual .cc files into object files
      ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${class}.o 
        DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${class}.cc octaviz ${GCH_HEADER}
        # octaviz is the target from the shared lib in Common/ directory
        # COMMAND ${CMAKE_CXX_COMPILER} 
        COMMAND ${CMAKE_CXX_COMPILER} 
        ARGS  -c ${PCHFLAGS} ${COMPILERFLAGS}
          -o ${CMAKE_CURRENT_BINARY_DIR}/${class}.o
          ${CMAKE_CURRENT_BINARY_DIR}/${class}.cc
        COMMENT "Compiling ${class}.cc to ${class}.o"
        VERBATIM)
      SET (all_o ${all_o} ${CMAKE_CURRENT_BINARY_DIR}/${class}.o )

      # link object files into .oct files 
      ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${class}.oct
        DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${class}.o octaviz ${GCH_HEADER}
        # octaviz is the target from the shared lib in Common/ directory
        # COMMAND ${CMAKE_CXX_COMPILER} 
        COMMAND ${MKOCTFILE}
        ARGS ${PCHFLAGS} ${LINK_FLAGS}
          -o ${CMAKE_CURRENT_BINARY_DIR}/${class}.oct
          #-Wl,-rpath=${OCTAVIZ_RPATH}
          ${CMAKE_CURRENT_BINARY_DIR}/${class}.o
        COMMENT "Linking ${class}.o to ${class}.oct"
        VERBATIM)

      SET (all_oct ${all_oct} ${CMAKE_CURRENT_BINARY_DIR}/${class}.oct )

    ENDIF(NOT VTK_CLASS_WRAP_EXCLUDE_${class})
  ENDFOREACH(class)

  # add custom target for the current kit
  ADD_CUSTOM_TARGET( ${kit} ALL  
    COMMAND echo ${all_oct}
    DEPENDS ${all_oct} vtkWrapOctave octaviz
    COMMENT "Building VTK kit ${kit} in ${CMAKE_CURRENT_BINARY_DIR}."
    VERBATIM)

  # INSTALL rule for the current .oct files
  INSTALL(PROGRAMS ${all_oct} DESTINATION ${OCTAVIZ_OCT_DIR})

  ADD_DEPENDENCIES(${kit} OctavizCommonFiles)
ENDMACRO(OCTAVE_WRAP_VTK)



# Build octave wrappers for VTK kits.
ADD_SUBDIRECTORY(Common)
ADD_SUBDIRECTORY(Filtering)
ADD_SUBDIRECTORY(Imaging)
ADD_SUBDIRECTORY(Graphics)
ADD_SUBDIRECTORY(IO)

SET(vtk_kits Common Filtering Imaging Graphics IO)
IF(VTK_USE_RENDERING)
  ADD_SUBDIRECTORY(Rendering)
  SET(vtk_kits ${vtk_kits} Rendering)
  # Hybrid and Widgets are toggled by Rendering
  # http://public.kitware.com/pipermail/vtk-developers/2005-July/003385.html
  ADD_SUBDIRECTORY(Hybrid)
  SET(vtk_kits ${vtk_kits} Hybrid)
  ADD_SUBDIRECTORY(Widgets)
  SET(vtk_kits ${vtk_kits} Widgets)
ENDIF(VTK_USE_RENDERING)
IF(VTK_USE_PATENTED)
  ADD_SUBDIRECTORY(Patented)
  SET(vtk_kits ${vtk_kits} Patented)
ENDIF(VTK_USE_PATENTED)
IF(VTK_USE_PARALLEL)
  ADD_SUBDIRECTORY(Parallel)
  SET(vtk_kits ${vtk_kits} Parallel)
ENDIF(VTK_USE_PARALLEL)

ADD_SUBDIRECTORY(Scripts)
ADD_SUBDIRECTORY(Examples)
