IF(WIN32)
  cmake_minimum_required(VERSION 2.6.0)
ELSE(WIN32)
  cmake_minimum_required(VERSION 2.4)
ENDIF(WIN32)

PROJECT(MedX3D)

# set the install directory to the MedX3D directory on Windows
IF( WIN32 AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND NOT H3D_CMAKE_INSTALL_PREFIX_ALREADY_SET ) 
  SET( CMAKE_INSTALL_PREFIX ${MedX3D_SOURCE_DIR}/.. CACHE PATH "Install path prefix, prepended onto install directories." FORCE )
  SET( H3D_CMAKE_INSTALL_PREFIX_ALREADY_SET TRUE )
ENDIF( WIN32 AND CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT AND NOT H3D_CMAKE_INSTALL_PREFIX_ALREADY_SET )

# Add a cache variable GENERATE_CPACK_PROJECT to have the choice of generating a project
# for packaging MedX3D. Default is NO since most people will not use this.
IF( NOT DEFINED GENERATE_CPACK_PROJECT )
  SET( GENERATE_CPACK_PROJECT "NO" CACHE BOOL "Decides if a cpack project should be generated. The project in the first loaded CMakeLists will configure CPack." )
  MARK_AS_ADVANCED(GENERATE_CPACK_PROJECT)
ENDIF( NOT DEFINED GENERATE_CPACK_PROJECT )

# Add a cache variable PREFER_STATIC_LIBRARIES to have the choice of generating a project
# linking against static libraries if they exist. Default is NO since most people will not use this.
IF( NOT DEFINED PREFER_STATIC_LIBRARIES )
  SET( PREFER_STATIC_LIBRARIES "NO" CACHE BOOL "Decides if CMake should prefer static libraries to dynamic libraries when both exist." )
  MARK_AS_ADVANCED(PREFER_STATIC_LIBRARIES)
ENDIF( NOT DEFINED PREFER_STATIC_LIBRARIES )

IF( PREFER_STATIC_LIBRARIES )
  SET( CMAKE_FIND_LIBRARY_SUFFIXES .a;${CMAKE_FIND_LIBRARY_SUFFIXES} )
ENDIF( PREFER_STATIC_LIBRARIES )

SET( MedX3D_COMPILE_FLAGS "-DMEDX3D_EXPORTS" )

INCLUDE( "${MedX3D_SOURCE_DIR}/MedX3DSourceFiles.txt" )

# Add the directory to INCLUDE_DIRECTORIES before any other statement to make sure that this header file is found first.
# This assumes that we always use "#include <path/include_header.h>" in our code even if the file is actually found in
# the same directory as the file that contains the include statement.
INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR}/include )
SET( MEDX3D_INCLUDE_DIR ${CMAKE_CURRENT_BINARY_DIR}/include ${MedX3D_SOURCE_DIR}/../include CACHE INTERNAL "Set to internal to propagate change" )

SET(optionalLibs)

INCLUDE_DIRECTORIES( ../include )

SET(requiredLibs)

# Version of MedX3D
SET( MEDX3D_MAJOR_VERSION 1 )
SET( MEDX3D_MINOR_VERSION 4 )
SET( MEDX3D_BUILD_VERSION 0 )

# Needed to convert from \ to / on windows. Not needed in the FindModules since
# call to macro takes care of that there.
SET( CONVERTED_H3D_ROOT "" )
IF( EXISTS $ENV{H3D_ROOT} )
  FILE( TO_CMAKE_PATH $ENV{H3D_ROOT} CONVERTED_H3D_ROOT )
ENDIF( EXISTS $ENV{H3D_ROOT} )
SET(CMAKE_MODULE_PATH  ${MedX3D_SOURCE_DIR}/modules ${CONVERTED_H3D_ROOT}/build/modules ${MedX3D_SOURCE_DIR}/../../H3DAPI/build/modules/)

IF( H3D_USE_DEPENDENCIES_ONLY )
  # The variables set here must be set by the CMakeLists.txt that sets H3D_USE_DEPENDENCIES_ONLY to true.
  INCLUDE_DIRECTORIES( ${EXTERNAL_INCLUDE_DIR} )
  INCLUDE_DIRECTORIES( ${H3DUTIL_INCLUDE_DIR} ) 
  INCLUDE_DIRECTORIES( ${HAPI_INCLUDE_DIR} ) 
  INCLUDE_DIRECTORIES( ${H3DAPI_INCLUDE_DIR} ) 
  
  SET( requiredLibs ${requiredLibs} H3DUtil HAPI H3DAPI )
ELSE( H3D_USE_DEPENDENCIES_ONLY )
  #H3DUtil
  FIND_PACKAGE(H3DUtil REQUIRED)

  IF(H3DUTIL_FOUND)
    INCLUDE_DIRECTORIES( ${H3DUTIL_INCLUDE_DIR} ) 
    SET(requiredLibs ${requiredLibs} ${H3DUTIL_LIBRARIES} )
  ENDIF(H3DUTIL_FOUND)

  #HAPI
  FIND_PACKAGE(HAPI REQUIRED)

  IF(HAPI_FOUND)
    INCLUDE_DIRECTORIES( ${HAPI_INCLUDE_DIR} ) 
    SET(requiredLibs ${requiredLibs} ${HAPI_LIBRARIES} )
  ENDIF(HAPI_FOUND)

  #H3DAPI
  FIND_PACKAGE(H3DAPI REQUIRED)

  IF(H3DAPI_FOUND)
    INCLUDE_DIRECTORIES( ${H3DAPI_INCLUDE_DIR} ) 
    SET(requiredLibs ${requiredLibs} ${H3DAPI_LIBRARIES} )
  ENDIF(H3DAPI_FOUND)
ENDIF( H3D_USE_DEPENDENCIES_ONLY )

# Find Glew library. Required to compile.
FIND_PACKAGE(GLEW)
IF(GLEW_FOUND)
  INCLUDE_DIRECTORIES( ${GLEW_INCLUDE_DIR} ) 
  SET(requiredLibs ${requiredLibs} ${GLEW_LIBRARIES} )
ENDIF(GLEW_FOUND)

# autogenerate MedX3D.h depending on the libraries available.
IF( EXISTS ${MedX3D_SOURCE_DIR}/../include/H3D/MedX3D/MedX3D.h )
  FILE( REMOVE ${MedX3D_SOURCE_DIR}/../include/H3D/MedX3D/MedX3D.h )
ENDIF( EXISTS ${MedX3D_SOURCE_DIR}/../include/H3D/MedX3D/MedX3D.h )
CONFIGURE_FILE( ${MedX3D_SOURCE_DIR}/../include/H3D/MedX3D/MedX3D.cmake ${CMAKE_CURRENT_BINARY_DIR}/include/H3D/MedX3D/MedX3D.h )

IF( NOT GENERATE_CPACK_PROJECT )
  # Install header files on non-windows system (e.g. Unix).
  INSTALL( FILES ${CMAKE_CURRENT_BINARY_DIR}/include/H3D/MedX3D/MedX3D.h
           DESTINATION ${MedX3D_SOURCE_DIR}/../include/H3D/MedX3D )
ENDIF( NOT GENERATE_CPACK_PROJECT )

IF(MSVC)
  # Add the MedX3D.rc resource file if Visual Studio
  SET( MedX3D_SRCS ${MedX3D_SRCS} ${CMAKE_CURRENT_BINARY_DIR}/MedX3D.rc )
ENDIF(MSVC)

IF( COMMAND cmake_policy )
  IF( POLICY CMP0003 )
    cmake_policy(SET CMP0003 OLD)
  ENDIF( POLICY CMP0003 )
ENDIF( COMMAND cmake_policy )
ADD_LIBRARY(MedX3D SHARED ${MedX3D_SRCS} ${MedX3D_HEADERS})

TARGET_LINK_LIBRARIES( MedX3D ${requiredLibs} ${optionalLibs} )

foreach( H3DUTIL_INCLUDE_DIR_TMP ${H3DUTIL_INCLUDE_DIR} )
  IF( EXISTS ${H3DUTIL_INCLUDE_DIR_TMP}/H3DUtil/H3DUtil.h )
    FILE( STRINGS ${H3DUTIL_INCLUDE_DIR_TMP}/H3DUtil/H3DUtil.h list_of_defines REGEX "#define THREAD_LOCK_DEBUG"  )
    LIST( LENGTH list_of_defines list_of_defines_length )
    IF( list_of_defines_length )
      if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
        execute_process( COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE GCC_VERSION)
        if (GCC_VERSION VERSION_GREATER 4.7 OR GCC_VERSION VERSION_EQUAL 4.7)
          add_definitions("-std=gnu++11")
        elseif(GCC_VERSION VERSION_GREATER 4.3 OR GCC_VERSION VERSION_EQUAL 4.3)
          add_definitions("-std=gnu++0x")
        else ()
          message(FATAL_ERROR "Enabling ENABLE_THREAD_LOCK_DEBUG requires C++11 support. This compiler lacks such support.")
        endif ()
      elseif (${MSVC_VERSION} LESS 1600 )
        message(FATAL_ERROR "Enabling ENABLE_THREAD_LOCK_DEBUG requires C++11 support. This compiler lacks such support.")
      endif ()
    ENDIF( list_of_defines_length )
  ENDIF( EXISTS ${H3DUTIL_INCLUDE_DIR_TMP}/H3DUtil/H3DUtil.h )
endforeach( H3DUTIL_INCLUDE_DIR_TMP )

# make the name of debug libraries end in _d.
SET_TARGET_PROPERTIES( MedX3D PROPERTIES DEBUG_POSTFIX "_d" )

IF(UNIX) 
  SET_TARGET_PROPERTIES( MedX3D PROPERTIES OUTPUT_NAME h3dmedx3d )
ENDIF(UNIX)

IF(MSVC)
  # Create variables
  SET( MedX3D_LINK_FLAGS_DEBUG "" )
  
  SET( H3D_MSVC_VERSION 6 )
  SET( TEMP_MSVC_VERSION 1299 )
  WHILE( ${MSVC_VERSION} GREATER ${TEMP_MSVC_VERSION} )
    MATH( EXPR H3D_MSVC_VERSION "${H3D_MSVC_VERSION} + 1" )
    MATH( EXPR TEMP_MSVC_VERSION "${TEMP_MSVC_VERSION} + 100" )
  ENDWHILE( ${MSVC_VERSION} GREATER ${TEMP_MSVC_VERSION} )
  
  # Treat wchar_t as built in type for all visual studio versions.
  # This is default for every version above 7 ( so far ) but we still set it for all.
  SET( MedX3D_COMPILE_FLAGS "${MedX3D_COMPILE_FLAGS} /Zc:wchar_t")
  
  IF( ${MSVC_VERSION} GREATER 1399 )
    # Remove compiler warnings about deprecation for visual studio versions 8 and above.
    SET( MedX3D_COMPILE_FLAGS "${MedX3D_COMPILE_FLAGS} -D_CRT_SECURE_NO_DEPRECATE" )
  ENDIF( ${MSVC_VERSION} GREATER 1399 )

  IF( ${MSVC_VERSION} GREATER 1499 )
    # Build using several threads for visual studio versions 9 and above.
    SET( MedX3D_COMPILE_FLAGS "${MedX3D_COMPILE_FLAGS} /MP" )
    # Remove link against default library for debug builds.
    SET( MedX3D_LINK_FLAGS_DEBUG "${MedX3D_LINK_FLAGS_DEBUG} /NODEFAULTLIB:msvcrt" )
  ENDIF( ${MSVC_VERSION} GREATER 1499 )

  SET_TARGET_PROPERTIES( MedX3D PROPERTIES OUTPUT_NAME ${PROJECT_NAME}_vc${H3D_MSVC_VERSION} )

  # Seems like MedX3D needs to have incremental linking shut off for vc8. Since this is
  # not the most important feature it is shut off for all visual studio versions.
  SET_TARGET_PROPERTIES( MedX3D PROPERTIES LINK_FLAGS_DEBUG "${MedX3D_LINK_FLAGS_DEBUG} /INCREMENTAL:NO" )

  SET( MEDX3D_SVN_VERSION "0" )
  # Find SubWCRev.exe
  FIND_FILE( SubWCRev
             NAMES "SubWCRev.exe"
             DOC   "Set to SubWCRev.exe that comes with TortoiseSVN. Used to find svn revision number." )
  MARK_AS_ADVANCED( SubWCRev )

  SET( MedX3D_is_working_copy 10 )
  IF( SubWCRev )
		EXECUTE_PROCESS( COMMAND ${SubWCRev} ${MedX3D_SOURCE_DIR}/../
										 RESULT_VARIABLE MedX3D_is_working_copy )
		IF( ${MedX3D_is_working_copy} EQUAL 0 )
		  SET( MEDX3D_SVN_VERSION "$WCREV$" )
		ENDIF( ${MedX3D_is_working_copy} EQUAL 0 )
  ENDIF( SubWCRev )

  # autogenerate MedX3D.rc depending on the version
  CONFIGURE_FILE( MedX3D.rc.cmake ${CMAKE_CURRENT_BINARY_DIR}/MedX3D.rc )
  
  ADD_CUSTOM_COMMAND( TARGET MedX3D
											PRE_BUILD
											COMMAND ${MedX3D_SOURCE_DIR}/UpdateResourceFile 
											ARGS MEDX3D ${CMAKE_CURRENT_BINARY_DIR}/MedX3D.rc ${MedX3D_SOURCE_DIR}/MedX3D.rc.cmake
											${MEDX3D_MAJOR_VERSION} ${MEDX3D_MINOR_VERSION}
											${MEDX3D_BUILD_VERSION} "${MEDX3D_SVN_VERSION}"
											"MedX3D_Output_Name"
											"$(TargetFileName)" )

  IF( SubWCRev AND ${MedX3D_is_working_copy} EQUAL 0 )
    # Update SVN revision in file.
    EXECUTE_PROCESS( COMMAND ${SubWCRev} ${MedX3D_SOURCE_DIR}/../ ${CMAKE_CURRENT_BINARY_DIR}/MedX3D.rc ${CMAKE_CURRENT_BINARY_DIR}/MedX3D.rc )

    ADD_CUSTOM_COMMAND( TARGET MedX3D 
                        PRE_BUILD 
                        COMMAND ${SubWCRev} 
                        ARGS ${MedX3D_SOURCE_DIR}/../ ${CMAKE_CURRENT_BINARY_DIR}/MedX3D.rc ${CMAKE_CURRENT_BINARY_DIR}/MedX3D.rc )
  ENDIF( SubWCRev AND ${MedX3D_is_working_copy} EQUAL 0)
ENDIF(MSVC)

SET( MEDX3D_FULL_VERSION ${MEDX3D_MAJOR_VERSION}.${MEDX3D_MINOR_VERSION}.${MEDX3D_BUILD_VERSION} ) 
SET_TARGET_PROPERTIES( MedX3D PROPERTIES VERSION ${MEDX3D_FULL_VERSION} )

# set compile flags for MedX3D project
SET_TARGET_PROPERTIES( MedX3D PROPERTIES COMPILE_FLAGS "${MedX3D_COMPILE_FLAGS}" )

IF( UNIX )
# Install header files on non-windows system (e.g. Unix).
INSTALL( FILES ${MedX3D_HEADERS}
         DESTINATION include/H3D/MedX3D )
ENDIF( UNIX )

SET( DEFAULT_BIN_INSTALL "bin" )
SET( DEFAULT_LIB_INSTALL "lib" )

IF( WIN32 )
  SET( DEFAULT_BIN_INSTALL "bin32" )
  SET( DEFAULT_LIB_INSTALL "lib32" )
  IF( CMAKE_SIZEOF_VOID_P EQUAL 8 )
    SET( DEFAULT_BIN_INSTALL "bin64" )
    SET( DEFAULT_LIB_INSTALL "lib64" )
  ENDIF( CMAKE_SIZEOF_VOID_P EQUAL 8 )
ENDIF( WIN32 )

# Install directories.
INSTALL( TARGETS MedX3D
         LIBRARY DESTINATION ${DEFAULT_LIB_INSTALL} COMPONENT MedX3D_cpack_runtime
         RUNTIME DESTINATION ${DEFAULT_BIN_INSTALL} COMPONENT MedX3D_cpack_runtime
         ARCHIVE DESTINATION ${DEFAULT_LIB_INSTALL} COMPONENT MedX3D_cpack_libraries)

IF( NOT DEFINED MedX3D_Demo_PROJECT )
  SET( MedX3D_Demo_PROJECT_DEFAULT "NO" )
  IF( H3D_USE_DEPENDENCIES_ONLY )
    SET( MedX3D_Demo_PROJECT_DEFAULT "YES" )
  ENDIF( H3D_USE_DEPENDENCIES_ONLY )
  SET( MedX3D_Demo_PROJECT "${H3DAPI_LOADER_PROJECTS_DEFAULT}" CACHE BOOL "If set to YES MedX3DDemo project will be included in the build." )
ENDIF( NOT DEFINED MedX3D_Demo_PROJECT )

IF( MedX3D_Demo_PROJECT )
  IF( H3D_USE_DEPENDENCIES_ONLY )
		IF(WIN32)
			FIND_PACKAGE(wxWidgetsWin)
			IF(wxWidgets_FOUND)
				INCLUDE_DIRECTORIES( ${wxWidgets_INCLUDE_DIR} ) 
				SET(requiredLibs ${requiredLibs} ${wxWidgets_LIBRARIES} )
			ENDIF(wxWidgets_FOUND)
		ENDIF(WIN32)

		IF(wxWidgets_FOUND)
		ELSE(wxWidgets_FOUND)
			SET(wxWidgets_USE_LIBS base core)
			FIND_PACKAGE(wxWidgets)
			IF(wxWidgets_FOUND)
				INCLUDE(${wxWidgets_USE_FILE})
				SET(requiredLibs ${requiredLibs} ${wxWidgets_LIBRARIES} )
			ENDIF(wxWidgets_FOUND)
		ENDIF(wxWidgets_FOUND)
	ENDIF( H3D_USE_DEPENDENCIES_ONLY )
  
  IF( ( NOT H3D_USE_DEPENDENCIES_ONLY ) OR wxWidgets_FOUND )
    STRING( REPLACE MedX3D MedX3D/MedX3DDemo MedX3DDemo_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} )
    MESSAGE( STATUS "Including MedX3D_Demo" )
    ADD_SUBDIRECTORY( ${MedX3D_SOURCE_DIR}/../demo/build
                      ${MedX3DDemo_BINARY_DIR} )
    SET( INSTALL_RUNTIME_AND_LIBRARIES_ONLY_DEPENDENCIES ${INSTALL_RUNTIME_AND_LIBRARIES_ONLY_DEPENDENCIES} MedX3DDemo)
  ELSE( ( NOT H3D_USE_DEPENDENCIES_ONLY ) OR wxWidgets_FOUND )
		MESSAGE( WARNING "wxWidgets was not found. MedX3DDemo will not be generated." )
	ENDIF( ( NOT H3D_USE_DEPENDENCIES_ONLY ) OR wxWidgets_FOUND )
ENDIF( MedX3D_Demo_PROJECT )

IF (EXISTS "${MedX3D_SOURCE_DIR}/../plugin")
  IF( NOT DEFINED MedX3D_Plugin_PROJECTS )
    SET( MedX3D_Plugin_PROJECTS "NO" CACHE BOOL "If set to YES the MedX3D plugin projects will be included in this build." )
  ENDIF( NOT DEFINED MedX3D_Plugin_PROJECTS )
  
  IF( MedX3D_Plugin_PROJECTS )
    STRING( REPLACE MedX3D MedX3D/MedX3DPlugin MedX3DPlugin_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} )
    MESSAGE( STATUS "Including MedX3D plugins" )
    ADD_SUBDIRECTORY( ${MedX3D_SOURCE_DIR}/../plugin/build
                      ${MedX3DPlugin_BINARY_DIR} )
    SET( INSTALL_RUNTIME_AND_LIBRARIES_ONLY_DEPENDENCIES ${INSTALL_RUNTIME_AND_LIBRARIES_ONLY_DEPENDENCIES} MedX3DPlugin )
  ENDIF( MedX3D_Plugin_PROJECTS )
ENDIF (EXISTS "${MedX3D_SOURCE_DIR}/../plugin")

IF( H3D_USE_DEPENDENCIES_ONLY )
  SET( INSTALL_RUNTIME_AND_LIBRARIES_ONLY_DEPENDENCIES ${INSTALL_RUNTIME_AND_LIBRARIES_ONLY_DEPENDENCIES} PARENT_SCOPE )
ELSE( H3D_USE_DEPENDENCIES_ONLY )
	INCLUDE ( ${MedX3D_SOURCE_DIR}/MedX3DCPack.cmake)
ENDIF( H3D_USE_DEPENDENCIES_ONLY )
