cmake_minimum_required(VERSION 2.6)

INCLUDE(CheckIncludeFiles)

SET(PROJECT_NAME "Urgo1")

PROJECT(${PROJECT_NAME})



## allow more human readable "if then else" constructs
SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS TRUE)


##################################
## Set build_type if not set
IF (NOT CMAKE_BUILD_TYPE)
  SET(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel." FORCE)
ENDIF()

##################################
## Set module path
SET(CMAKE_MODULE_PATH  "${CMAKE_SOURCE_DIR}/girl++/cmake/Modules;${CMAKE_SOURCE_DIR}/girlTools/cmake/Modules;${CMAKE_SOURCE_DIR}/ise++/cmake/Modules;${CMAKE_MODULE_PATH}" )

IF (NOT CMAKE_MODULE_PATH)
  SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} CACHE PATH "Path for CMake modules")
ENDIF()


IF (NOT BUILD_SHARED_LIBS)
   SET(BUILD_SHARED_LIBS OFF CACHE BOOL "build shared libs or not")
ENDIF()

##########################
## Check compiler  

#REM: clang detection
# clang is only supported by CMake version >= 2.8.2
# For CMake version < 2.8.2, when clang compiler is used : 
# CMAKE_COMPILER_IS_GNUCC is true
# CMAKE_CXX_COMPILER_ID is GNU

# CHECK_SYMBOL_EXISTS is only available in CMake >= 2.8
# thus we can not do CHECK_SYMBOL_EXISTS(__clang__ "" CLANG_COMPILER)


string(REGEX MATCH ".*clang.*" USE_CLANG ${CMAKE_CXX_COMPILER})
IF (NOT USE_CLANG)
   IF ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
      SET(USE_CLANG TRUE)
   ENDIF()
ENDIF(NOT USE_CLANG)

string(REGEX MATCH ".*icpc.*" USE_ICPC ${CMAKE_CXX_COMPILER})

IF(CMAKE_COMPILER_IS_GNUCC) #may be GCC or llvm-gcc or clang
  IF(NOT USE_CLANG)
    EXEC_PROGRAM( ${CMAKE_CXX_COMPILER} ARGS "-dumpversion" OUTPUT_VARIABLE GCC_VERSION )
    STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]" "\\1" GCC_MAJOR_VERSION "${GCC_VERSION}")
    STRING(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]" "\\1" GCC_MINOR_VERSION "${GCC_VERSION}")
  ENDIF()
ENDIF(CMAKE_COMPILER_IS_GNUCC)

IF (USE_CLANG)
  EXEC_PROGRAM( ${CMAKE_CXX_COMPILER} ARGS "--version" OUTPUT_VARIABLE CLANG_VERBOSE_VERSION )
  #TODO: regex to get directly CLANG_VERSION
  STRING(REGEX REPLACE "[^0-9]*([0-9]+)\\.[0-9]+(\\.[0-9]+)?.*" "\\1" CLANG_VERSION_MAJOR ${CLANG_VERBOSE_VERSION})
  STRING(REGEX REPLACE "[^0-9]*[0-9]+\\.([0-9]+)(\\.[0-9]+)?.*" "\\1" CLANG_VERSION_MINOR ${CLANG_VERBOSE_VERSION})
  SET(CLANG_VERSION "${CLANG_VERSION_MAJOR}.${CLANG_VERSION_MINOR}")
ENDIF(USE_CLANG)

IF (USE_ICPC)
  EXEC_PROGRAM( ${CMAKE_CXX_COMPILER} ARGS "-dumpversion" OUTPUT_VARIABLE ICPC_VERSION )
  STRING(REGEX REPLACE "^([0-9]+)\\.[0-9]+\\.[0-9]" "\\1" ICPC_MAJOR_VERSION "${ICPC_VERSION}")
  STRING(REGEX REPLACE "^[0-9]+\\.([0-9]+)\\.[0-9]" "\\1" ICPC_MINOR_VERSION "${ICPC_VERSION}")
ENDIF()


##########################
## Set some compiler flags 

ADD_DEFINITIONS(-DGIRL_DLL -DGIRL_DLL_EXPORTS) 

IF(CMAKE_COMPILER_IS_GNUCC) #may be GCC or clang

  # With GCC, always set flags to have most warnings
  ADD_DEFINITIONS(-Wall -Wextra -ansi -pedantic)

  IF(NOT USE_CLANG)
    IF(${GCC_MAJOR_VERSION} MATCHES "4")
      # If we have gcc version 4.x, set visibility flags
      ADD_DEFINITIONS(-DGCC_HASCLASSVISIBILITY -fvisibility=hidden)
    ENDIF()

    #-Wunused-but-set-variable is available with gcc 4.5.1 on Fedora (14)
    # but not available with gcc 4.5.2 on Ubuntu (11.04)
    # Thus we can not test with IF(${GCC_VERSION} VERSION_GREATER 4.5.0)
    INCLUDE(CheckCXXCompilerFlag)
    CHECK_CXX_COMPILER_FLAG(-Wunused-but-set-variable HAS_WARNING_UNUSED_BUT_SET_VARIABLE)
    if (HAS_WARNING_UNUSED_BUT_SET_VARIABLE)
      ADD_DEFINITIONS(-Wunused-but-set-variable)
      #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wunused-but-set-variable")
    ENDIF()

  ENDIF()
  ###??? useless to add   -DGIRL_DLL -DGIRL_DLL_EXPORTS ? see girl/CMakeLists.txt SET_TARGET_PROPERTIES(...

ENDIF(CMAKE_COMPILER_IS_GNUCC)

IF(USE_ICPC)

  # With ICPC (Intel C++ compiler) 11
  # -pedantic is not supported, 
  # -Wextra is supported but very verbose
  # -Wunused-but-set-variable is not supported
  
  ADD_DEFINITIONS(-Wall -ansi) 

  IF(${ICPC_VERSION} VERSION_GREATER "11") #at least 12. Is it right ?
    ADD_DEFINITIONS(-DGCC_HASCLASSVISIBILITY -fvisibility=hidden)
  ENDIF()


ENDIF(USE_ICPC)


##########################
## Set level of asserts 

IF(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
  ADD_DEFINITIONS("-DNDEBUG1")
ELSEIF(CMAKE_BUILD_TYPE STREQUAL "Release")
  ADD_DEFINITIONS("-DNDEBUG -DNDEBUG1")
ENDIF()


########################################################################
## Look for shared_ptr implementation

IF(CMAKE_COMPILER_IS_GNUCC)
  IF(NOT USE_CLANG)
    IF(${GCC_VERSION} VERSION_GREATER 4.0.0)

      SET(HAVE_TR1_MEMORY 1)
      #ADD_DEFINITIONS(-DHAVE_TR1_MEMORY)
    ENDIF()
  ENDIF(NOT USE_CLANG)
ENDIF(CMAKE_COMPILER_IS_GNUCC)

IF(USE_CLANG)
  SET(MIN_CLANG_VERSION_FOR_TR1_MEMORY 2.8)  #at least 2.9 
  # It seems that version number is not the same on MacOSX
  IF (APPLE)
    SET(MIN_CLANG_VERSION_FOR_TR1_MEMORY 2.0) #at least 2.1
  ENDIF()
  IF(${CLANG_VERSION} VERSION_GREATER ${MIN_CLANG_VERSION_FOR_TR1_MEMORY}) 
    SET(HAVE_TR1_MEMORY 1)
  ENDIF()
ENDIF(USE_CLANG)

IF(USE_ICPC)
  IF(${ICPC_VERSION} VERSION_GREATER "11") #at least 12. Is it right ?
     SET(HAVE_TR1_MEMORY 1)
  ENDIF()
ENDIF(USE_ICPC)

IF(NOT HAVE_TR1_MEMORY)
    MESSAGE(SEND_ERROR "no shared ptr implementation available!!!!")
ENDIF()

########################################################################
## Look for hash map (unordered_map) implementation

IF(CMAKE_COMPILER_IS_GNUCC)
  IF(NOT USE_CLANG)
    # Only gcc version > 4.0.1 have const-correct tr1::unordered_map
    # see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23053
    IF(${GCC_VERSION} VERSION_GREATER 4.0.1)
      SET(HAVE_TR1_UNORDERED_MAP 1)
      SET(HASH_MAP_USES_TR1_UNORDERED_MAP 1)
      #ADD_DEFINITIONS(-DHASH_MAP_USES_TR1_UNORDERED_MAP)
    ELSE()
      SET(HASH_MAP_USES_EXT_HASH_MAP 1)
    ENDIF()
  ENDIF()
ENDIF(CMAKE_COMPILER_IS_GNUCC)

IF(USE_CLANG)
  SET(MIN_CLANG_VERSION_FOR_TR1_UNORDERED_MAP 2.8)  #at least 2.9 
  # It seems that version number is not the same on MacOSX
  IF (APPLE)
    SET(MIN_CLANG_VERSION_FOR_TR1_UNORDERED_MAP 2.0) #at least 2.1
  ENDIF()
   IF(${CLANG_VERSION} VERSION_GREATER ${MIN_CLANG_VERSION_FOR_TR1_UNORDERED_MAP})
     SET(HAVE_TR1_UNORDERED_MAP 1)
     SET(HASH_MAP_USES_TR1_UNORDERED_MAP 1)
   ENDIF() 
ENDIF(USE_CLANG)

IF(USE_ICPC)
  IF(${ICPC_VERSION} VERSION_GREATER "11") #at least 12. Is it right ?
     SET(HAVE_TR1_UNORDERED_MAP 1)
     SET(HASH_MAP_USES_TR1_UNORDERED_MAP 1)
  ENDIF()
ENDIF(USE_ICPC)

IF(MSVC)
    MESSAGE("will use Visual Studio C++ hash map implementation")
    ## TODO: check MSVC version !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ENDIF()

#######################################################################
## Look for unordered_set implementation

IF(CMAKE_COMPILER_IS_GNUCC)
  IF(NOT USE_CLANG)
    # Only gcc version > 4.0.1 have const-correct tr1::unordered_set
    # see http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23053
    EXEC_PROGRAM(${CMAKE_CXX_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE cxx_COMPILER_VERSION)
    IF(${cxx_COMPILER_VERSION} VERSION_GREATER 4.0.1)
      SET(HAVE_TR1_UNORDERED_SET 1)
      SET(UNORDERED_SET_USES_TR1_UNORDERED_SET 1)
      #ADD_DEFINITIONS(-DUNORDERED_SET_USES_TR1_UNORDERED_SET)
    ELSE()
      SET(UNORDERED_SET_USES_EXT_HASH_SET 1)
    ENDIF()
  ENDIF()
ENDIF(CMAKE_COMPILER_IS_GNUCC)

IF(USE_CLANG)
  SET(MIN_CLANG_VERSION_FOR_TR1_UNORDERED_SET 2.8)  #at least 2.9 
  # It seems that version number is not the same on MacOSX
  IF (APPLE)
    SET(MIN_CLANG_VERSION_FOR_TR1_UNORDERED_SET 2.0) #at least 2.1
  ENDIF()
   IF(${CLANG_VERSION} VERSION_GREATER ${MIN_CLANG_VERSION_FOR_TR1_UNORDERED_SET}) 
      SET(HAVE_TR1_UNORDERED_SET 1)
      SET(UNORDERED_SET_USES_TR1_UNORDERED_SET 1)
   ENDIF() 
ENDIF(USE_CLANG)

IF(USE_ICPC)
  IF(${ICPC_VERSION} VERSION_GREATER "11") #at least 12. Is it right ?
    SET(HAVE_TR1_UNORDERED_SET 1)
    SET(UNORDERED_SET_USES_TR1_UNORDERED_SET 1)
  ENDIF()
ENDIF(USE_ICPC)

IF(MSVC)
    MESSAGE("will use Visual Studio C++ hash map implementation")
    ## TODO: check MSVC version !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ENDIF()


########################################################################
# Find packages

FIND_PACKAGE(ZLIB REQUIRED)
IF (ZLIB_FOUND)
   SET(GIRLTOOLS_DEFS "${GIRLTOOLS_DEFS} -DWITH_ZLIB")
   #ADD_DEFINITIONS(-DWITH_ZLIB)
ENDIF()

## OpenCV
FIND_PACKAGE(OpenCV REQUIRED)

## libpng
IF(NOT APPLE)
FIND_PACKAGE(PNG REQUIRED)
ELSE(NOT APPLE)
SET(PNG_INCLUDE_DIRS "/Users/Domenger/tools/opencv-2.4.8/3rdparty/libpng/")
SET(PNG_INCLUDE_DIRS "/Users/mansencal/tools/opencv-2.4.9/3rdparty/libpng/ ${PNG_INCLUDE_DIRS}")
ENDIF(NOT APPLE)



########################################################################

## girlConfig.h
SET(girl_CONFIG_FILE ${CMAKE_CURRENT_BINARY_DIR}/girl++/girl/girlConfig.h)
CONFIGURE_FILE(girl++/girl/config.h.in.cmake ${girl_CONFIG_FILE})
## we install girl_CONFIG_FILE by putting it in public headers in girl++/girl/CMakeLists.txt
# and  not with 
# INSTALL(FILES ${girl_CONFIG_FILE} DESTINATION include/${girl_major_minor}/girl)

ADD_DEFINITIONS(-DGIRL_HAVE_CONFIG_H)

########################################################################
### Hide some variables
IF(APPLE)
  MARK_AS_ADVANCED(CMAKE_OSX_ARCHITECTURES)
  MARK_AS_ADVANCED(CMAKE_OSX_DEPLOYMENT_TARGET)
  MARK_AS_ADVANCED(CMAKE_OSX_SYSROOT)
ENDIF(APPLE)

########################################################################

#set include paths

SET(GIRL_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/girl++)
SET(GIRL_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/girl++) #for girl/girlConfig.h
SET(GIRLTOOLS_INCLUDE_DIRS ${GIRL_INCLUDE_PATH} ${GIRL_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIRS} ${OpenCV_INCLUDE_DIRS}) 
SET(GIRLTOOLS_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/girlTools)
SET(ISE_INCLUDE_DIRS ${GIRLTOOLS_INCLUDE_DIRS} ${GIRLTOOLS_INCLUDE_PATH})
SET(ISE_INCLUDE_PATH ${PROJECT_SOURCE_DIR}/ise++)


# set library names

SET(girl_major_minor girl-1.0)
SET(girlTools_major_minor girlTools-1.0)
SET(ise_major_minor ise-0.2)


#set libraries dependancies


SET(GIRL_LINK_LIBS "")


#SET(GIRLTOOLS_LINK_LIBS "${GIRL_LIBRARIES};${OpenCV_LIBS}")

#In OpenCV_LIBS, we have opencv libraries both for debug and other configurations
#It may look like :
#"debug;opencv_core;optimized;opencv_core;debug;opencv_imgproc;optimized;opencv_imgproc;"
#We want to remove "debug" and "optimized" keywords 
# and fill GIRLTOOLS_EXTRA_LIBS only with the correct libraries !

#There is probably a better way to do that : 

SET(NextIsDebug 0)
SET(NextIsOptim 0)
FOREACH(lib ${OpenCV_LIBS})
  SET(notDone 1)
  IF(${NextIsOptim})
    SET(OpenCV_LIBS_DEFAULT "${OpenCV_LIBS_DEFAULT};${lib}")
    SET(notDone 0)
  ENDIF()
  IF (${NextIsDebug})
    SET(OpenCV_LIBS_DEBUG "${OpenCV_LIBS_DEBUG};${lib}")
    SET(notDone 0)
  ENDIF()
  SET(NextIsOptim 0)
  SET(NextIsDebug 0)
  
  IF (${notDone})
    IF (${lib} STREQUAL "debug")
      SET(NextIsDebug 1)
    ELSEIF (${lib} STREQUAL "optimized")
      SET(NextIsOptim 1)
    ELSEIF (${lib} STREQUAL "general")
      SET(NextIsDebug 1)
      SET(NextIsOptim 1)
    ELSE()
      SET(OpenCV_LIBS_DEFAULT "${OpenCV_LIBS_DEFAULT};${lib}")
      SET(OpenCV_LIBS_DEBUG "${OpenCV_LIBS_DEBUG};${lib}")
    ENDIF()
  ENDIF()
ENDFOREACH()

SET(GIRLTOOLS_LINK_LIBS "${GIRL_LINK_LIBS};${girl_major_minor};${OpenCV_LIBS};${ZLIB_LIBRARIES}")



SET(ISE_LINK_LIBS "${GIRLTOOLS_LINK_LIBS};${girlTools_major_minor}" )

SET(SRC_INCLUDE_DIRS ${PNG_INCLUDE_DIRS})
SET(SRC_LINK_LIBS "${ISE_LINK_DIRS};${PNG_LIBRARIES};${ise_major_minor}")


########################################################################

ADD_SUBDIRECTORY(girl++)
ADD_SUBDIRECTORY(girlTools)
ADD_SUBDIRECTORY(ise++)

ADD_SUBDIRECTORY(src)
