PROJECT(odemx CXX)
cmake_minimum_required(VERSION 2.6)
cmake_policy(VERSION 2.6)
option(CMAKE_COLOR_MAKEFILE "color makefiles" ON)

#############################
#### configure includes  ####
#############################
# we need to do that here, as the order of the includes may be significant.
# if cmake uses the install directory as an include path before including
# the local source include paths, then it will favor those paths.
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include)

ENABLE_TESTING()

if("${BUILD_SHARED_LIBS_OLD}" MATCHES "")
    set(BUILD_SHARED_LIBS_OLD INTERNAL OFF)
endif()

#############################
####  default config     ####
#############################

option(BUILD_SHARED_LIBS "build odemx, poco and gsl static" OFF)
option(BUILD_EXAMPLES "build odemx examples" OFF)
option(WITH_ODBC "compile with odbc suport" OFF)
option(ENABLE_UNIT_TESTS "enable unit tests" OFF)
option(GENERATE_DOXYGEN "Generate Doxygen API documentation" OFF)
option(BUILD_ONLY_DOCUMENTATION "Build only Doxygen documentation" OFF)

# paths
set(INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/install CACHE PATH "install path of odemx. e.g.: /usr/local")
set(CMAKE_INSTALL_PREFIX ${INSTALL_PREFIX} CACHE INTERNAL " user INSTALL_PREFIX " FORCE)
set(Example_PREFIX bin/examples CACHE PATH "path to the example binaries")

if(BUILD_SHARED_LIBS)
    set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_SHARED_LIBRARY_SUFFIX};${CMAKE_STATIC_LIBRARY_SUFFIX}")
else(BUILD_SHARED_LIBS)
    set(CMAKE_FIND_LIBRARY_SUFFIXES "${CMAKE_STATIC_LIBRARY_SUFFIX};${CMAKE_SHARED_LIBRARY_SUFFIX}")
endif(BUILD_SHARED_LIBS)

if(NOT BUILD_ONLY_DOCUMENTATION)
#  FLAGS
#   NOTE: We assume that somebody who is building ODEMx for MSYS uses the
#   install_contrib.sh script as well. Therefore, we set the default values of the
#   required libs to the same values as they are set on UNIX. If the user requires to set
#   the variables to differing values, he must do that by himself.
	if(WIN32 AND NOT (${MSYS}))

	    set(CXX_FLAGS ""
			CACHE STRING " CXX flags")
    	set(CXX_DEBUG_FLAGS ""
			CACHE STRING " CXX Debug Flags")
	    set(CXX_RELEASE_FLAGS ""
			CACHE STRING " CXX Release Flags")
    	set(EXTERNAL_LIBS "") 

	    set(GSL_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/external/contrib/gsl-1.13/gsl/win32
			CACHE PATH "Path to gsl build dir e.g. gsl/win32" )
    	set(POCO_INSTALL_PREFIX ${CMAKE_CURRENT_SOURCE_DIR}/external/contrib/poco/
			CACHE PATH "PATH to poco build dir")
	    set(UNITTEST_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/external/contrib/UnitTest++"
		    CACHE PATH "PATH to the UnitTest++ lib")

	else()

    	set(CXX_FLAGS "-Wall -Wno-sign-compare"
			CACHE STRING " CXX flags")
	    set(CXX_DEBUG_FLAGS "-g3"
			CACHE STRING " additional debug flags ")
    	set(CXX_RELEASE_FLAGS "-O3 -DNDEBUG"
			CACHE STRING " additional release flags" )
	    set(EXTERNAL_LIBS "") 

    	set(GSL_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
			CACHE PATH "Path to gsl build dir e.g. gsl/win32" )
	    set(POCO_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}
			CACHE PATH "PATH to poco build dir")
	    set(UNITTEST_PREFIX "${CMAKE_CURRENT_SOURCE_DIR}/external/contrib/UnitTest++"
		    CACHE PATH "PATH to the UnitTest++ lib")
	endif()

	find_library(RT rt)
	if("${RT}" MATCHES "RT-NOTFOUND")
		set(RT_PRESENT OFF)
	else ("${RT}" MATCHES "RT-NOTFOUND")
		set(RT_PRESENT ON)
	endif ("${RT}" MATCHES "RT-NOTFOUND")

	find_library(PTHREAD pthread)
	find_library(DL dl)

##############################
####      CppLog          ####
##############################

	add_subdirectory(external/CppLog)
	include_directories(${CMAKE_CURRENT_SOURCE_DIR}/external/CppLog/include/)

##############################
####  Resource Generator  ####
##############################

    add_subdirectory(external/genResources)

##############################
####        poco          ####
##############################

	if(NOT "${BUILD_SHARED_LIBS}" MATCHES "${BUILD_SHARED_LIBS_OLD}")
        set( POCO_SQLite INTERNAL "POCO_SQLite-NOTFOUND")
        set( POCO_XML INTERNAL "POCO_XML-NOTFOUND")
        set( POCO_DATA INTERNAL "POCO_DATA-NOTFOUND")
        set( POCO_FOUNDATION INTERNAL "POCO_FOUNDATION-NOTFOUND")
	endif()

	find_library(POCO_SQLite PocoSQLite HINTS ${CMAKE_INSTALL_PREFIX}/lib ${POCO_INSTALL_PREFIX}/lib ${POCO_INSTALL_PREFIX}/bin)
	find_library(POCO_XML PocoXML ${CMAKE_INSTALL_PREFIX}/lib ${POCO_INSTALL_PREFIX}/lib ${POCO_INSTALL_PREFIX}/bin)
	find_library(POCO_DATA PocoData ${CMAKE_INSTALL_PREFIX}/lib ${POCO_INSTALL_PREFIX}/lib ${POCO_INSTALL_PREFIX}/bin)
	find_library(POCO_FOUNDATION PocoFoundation ${CMAKE_INSTALL_PREFIX}/lib ${POCO_INSTALL_PREFIX}/lib ${POCO_INSTALL_PREFIX}/bin)

	set(EXTERNAL_LIBS ${EXTERNAL_LIBS}
				${POCO_SQLite}
				${POCO_XML}
				${POCO_DATA}
				${POCO_FOUNDATION} )
	INCLUDE_DIRECTORIES(${POCO_INSTALL_PREFIX}/include)
	INCLUDE_DIRECTORIES(${POCO_INSTALL_PREFIX}/Foundation/include)
	INCLUDE_DIRECTORIES(${POCO_INSTALL_PREFIX}/XML/include)
	INCLUDE_DIRECTORIES(${POCO_INSTALL_PREFIX}/Data/include)
	INCLUDE_DIRECTORIES(${POCO_INSTALL_PREFIX}/Data/SQLite/include)

##############################
####         gsl          ####
##############################

	if(NOT "${BUILD_SHARED_LIBS}" MATCHES "${BUILD_SHARED_LIBS_OLD}")
	set(GSL INTERNAL "GSL-NOTFOUND")
	set(GSL_CBLAS INTERNAL "GSL_CBLAS_LIB-NOTFOUND")
	endif()
	find_library(GSL gsl
			 HINTS ${CMAKE_INSTALL_PREFIX}/lib ${GSL_INSTALL_PREFIX}/lib ${GSL_INSTALL_PREFIX}/bin)
	find_library(GSL_CBLAS gslcblas
			HINTS ${CMAKE_INSTALL_PREFIX}/lib ${GSL_INSTALL_PREFIX}/lib ${GSL_INSTALL_PREFIX}/bin )

	set (EXTERNAL_LIBS ${EXTERNAL_LIBS} ${GSL} ${GSL_CBLAS})

	INCLUDE_DIRECTORIES(${GSL_INSTALL_PREFIX}/include)

##############################
####         system libs  ####
##############################
	if( NOT "${PTHREAD}" MATCHES "PTHREAD-NOTFOUND")
		set (EXTERNAL_LIBS ${EXTERNAL_LIBS} pthread)
	endif()
	if( NOT "${DL}" MATCHES "DL-NOTFOUND")
		set (EXTERNAL_LIBS ${EXTERNAL_LIBS} dl )
	endif()
	if ( RT_PRESENT ) 
		set (EXTERNAL_LIBS ${EXTERNAL_LIBS} rt)
	endif (RT_PRESENT)

############################## 
####         odemx        ####
##############################

	add_subdirectory(include)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_BINARY_DIR}/include)

include (ODEMX_Source.cmake)
include (ODEMX_Resources.cmake)

FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/include/odemx/resources ${CMAKE_BINARY_DIR}/src/resources)

foreach(resource ${RESOURCES})

string(REGEX REPLACE "[^A-Za-z0-9]"
         "_" RESOURCENAME
         ${resource} )

ADD_CUSTOM_COMMAND(
    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/resources/${RESOURCENAME}.cpp 
           ${CMAKE_CURRENT_BINARY_DIR}/include/odemx/resources/${RESOURCENAME}.h
    COMMAND genResources ${RESOURCENAME} ${CMAKE_CURRENT_SOURCE_DIR}/resources/${resource} ${CMAKE_CURRENT_BINARY_DIR}
    DEPENDS resources/${resource}
    )
set(SRCFILES ${SRCFILES} ${CMAKE_CURRENT_BINARY_DIR}/src/resources/${RESOURCENAME}.cpp)

SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_BINARY_DIR}/src/resources/${RESOURCENAME}.cpp PROPERTIES GENERATED 1)

INSTALL(FILES
   ${CMAKE_CURRENT_BINARY_DIR}/include/odemx/resources/${RESOURCENAME}.h
   DESTINATION include/odemx/resources )

endforeach(resource)

# configure default target
ADD_LIBRARY(odemx ${SRCFILES} )
target_link_libraries(odemx ${EXTERNAL_LIBS})
set_target_properties (odemx
  PROPERTIES DEBUG_POSTFIX D
)

# configure test target
# EXCLUDE_FROM_ALL: Build only on request. Don't include in all target.
ADD_LIBRARY(odemxT EXCLUDE_FROM_ALL ${SRCFILES})
target_link_libraries(odemxT ${EXTERNAL_LIBS})
set_target_properties(odemxT
                PROPERTIES
                COMPILE_FLAGS "-DODEMX_USE_OBSERVATION -DODEMX_USE_TRACE -DODEMX_USE_CONTINUOUS"
                DEFINE_SYMBOL ODEMX_USE_OBSERVATION
                DEFINE_SYMBOL ODEMX_USE_TRACE
                DEFINE_SYMBOL ODEMX_USE_CONTINUOUS
)


##############
# install odemx lib and resources
##############
install(TARGETS odemx
  DESTINATION lib
)

##############################
####    UnitTests         ####
##############################
	if(ENABLE_UNIT_TESTS)
		
	if(NOT "${BUILD_SHARED_LIBS}" MATCHES "${BUILD_SHARED_LIBS_OLD}")
		set(UNITTESTLIB INTERNAL "UNITTESTLIN-NOTFOUND")
	endif()
		find_library(UNITTESTLIB NAMES "UnitTest++" "UnitTest++.vsnet2005" "UnitTest++.vsnet2008"
			HINTS ${CMAKE_INSTALL_PREFIX} ${UNITTEST_PREFIX} ${UNITTEST_PREFIX}/Release ${UNITTEST_PREFIX}/Debug )
	 
	INCLUDE_DIRECTORIES(${UNITTEST_PREFIX}/src)
		add_subdirectory(test)
	endif(ENABLE_UNIT_TESTS)


##############################
####      examples        ####
##############################

	if(BUILD_EXAMPLES)
		add_subdirectory(examples)
	endif()

	set(BUILD_SHARED_LIBS_OLD INTERNAL ${BUILD_SHARED_LIBS})

else ()
	set(GENERATE_DOXYGEN ON)
	message(WARNING "Generating only documentation, as requested by setting
	BUILD_ONLY_DOCUMENTATION")
endif()
##############################
####         doxygen      ####
##############################
# check if doxygen is even installed
find_package(Doxygen)
if (DOXYGEN_FOUND STREQUAL "NO")
	message(WARNING "Doxygen not found. Please get a copy http://www.doxygen.org")
else (DOXYGEN_FOUND STREQUAL "NO")
    if (NOT GENERATE_DOXYGEN)
        message (WARNING "Won't generate doxygen documentation as requested.")
    else (NOT GENERATE_DOXYGEN)

        # prepare doxygen configuration file
        configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxygen/Doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)

        # add doxygen as target
        add_custom_target(doxygen ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)

        # cleanup $build/api-doc on "make clean"
        set_property(DIRECTORY APPEND PROPERTY
            ADDITIONAL_MAKE_CLEAN_FILES doc)

        # add doxygen as dependency to doc-target
        get_target_property(DOC_TARGET doc TYPE)
        if(NOT DOC_TARGET)
            add_custom_target(doc)
        endif()
        add_dependencies(doc doxygen)

	foreach(resource ${RESOURCES})

		string(REGEX REPLACE "[^A-Za-z0-9]"
         		"_" RESOURCENAME
         		${resource} )
		add_dependencies(doxygen ${CMAKE_CURRENT_BINARY_DIR}/include/odemx/resources/${RESOURCENAME}.h)

	endforeach(resource)


        # install HTML API documentation and manual pages
        set(DOC_PATH "share/odemx/doc" CACHE PATH "Install path to the documentation. If it is relative, then it will be installed to <INSTALL_PREFIX/DOC_PATH>")

        # set up an empty directory, in case the user didn't call make doc before calling
        # make install
        INSTALL(CODE "FILE(MAKE_DIRECTORY \${CMAKE_CURRENT_BINARY_DIR}/doc/html)")

        install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/html
            DESTINATION ${DOC_PATH}
            PATTERN "*/.svn*" EXCLUDE
            )

        # install man pages into packages, scope is now project root..
        #install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/api-doc/man/man3
        #         DESTINATION share/man/man3/
        #       )
    endif (NOT GENERATE_DOXYGEN)
endif (DOXYGEN_FOUND STREQUAL "NO")
