#
# Try to find CUDA compiler, runtime libraries, and include path.
# Once done this will define
#
# CUDA_FOUND
# CUDA_INCLUDE_PATH
# CUDA_RUNTIME_LIBRARY
# CUDA_COMPILER
#
# It will also define the following macro:
#
# WRAP_CUDA
#

IF (WIN32)
	FIND_PROGRAM (CUDA_COMPILER nvcc.exe
		$ENV{CUDA_BIN_PATH}
		DOC "The CUDA Compiler")
ELSE(WIN32)
	FIND_PROGRAM (CUDA_COMPILER nvcc
		$ENV{CUDA_BIN_PATH}
		/usr/local/cuda/bin
		DOC "The CUDA Compiler")
ENDIF(WIN32)

IF (CUDA_COMPILER)
	GET_FILENAME_COMPONENT (CUDA_COMPILER_DIR ${CUDA_COMPILER} PATH)
	GET_FILENAME_COMPONENT (CUDA_COMPILER_SUPER_DIR ${CUDA_COMPILER_DIR} PATH)
ELSE (CUDA_COMPILER)
	SET (CUDA_COMPILER_DIR .)
	SET (CUDA_COMPILER_SUPER_DIR ..)
ENDIF (CUDA_COMPILER)

FIND_PATH (CUDA_INCLUDE_PATH cuda_runtime.h
	$ENV{CUDA_INC_PATH}
	${CUDA_COMPILER_SUPER_DIR}/include
	${CUDA_COMPILER_DIR}
	DOC "The directory where CUDA headers reside")

FIND_LIBRARY (CUDA_RUNTIME_LIBRARY
	NAMES cudart
	PATHS
	$ENV{CUDA_LIB_PATH}
	${CUDA_COMPILER_SUPER_DIR}/lib
	${CUDA_COMPILER_DIR}
	DOC "The CUDA runtime library")

IF (CUDA_INCLUDE_PATH AND CUDA_RUNTIME_LIBRARY)
	SET (CUDA_FOUND TRUE)
ELSE (CUDA_INCLUDE_PATH AND CUDA_RUNTIME_LIBRARY)
	SET (CUDA_FOUND FALSE)
ENDIF (CUDA_INCLUDE_PATH AND CUDA_RUNTIME_LIBRARY)

SET (CUDA_LIBRARIES ${CUDA_RUNTIME_LIBRARY})

MARK_AS_ADVANCED (CUDA_FOUND CUDA_COMPILER CUDA_RUNTIME_LIBRARY)


#SET(CUDA_OPTIONS "-ncfe")
SET(CUDA_OPTIONS "--host-compilation=C")

IF (CUDA_EMULATION)
	SET (CUDA_OPTIONS "${CUDA_OPTIONS} -deviceemu")
ENDIF (CUDA_EMULATION)


# Get include directories.
MACRO(GET_CUDA_INC_DIRS _cuda_INC_DIRS)
	SET(${_cuda_INC_DIRS})
	GET_DIRECTORY_PROPERTY(_inc_DIRS INCLUDE_DIRECTORIES)

	FOREACH(_current ${_inc_DIRS})
		SET(${_cuda_INC_DIRS} ${${_cuda_INC_DIRS}} "-I" ${_current})
	ENDFOREACH(_current ${_inc_DIRS})
	
	SET(${_cuda_INC_DIRS} ${${_cuda_INC_DIRS}} "-I" ${CUDA_INCLUDE_PATH})

#	IF (CMAKE_SYTEM_INCLUDE_PATH)
#		SET(${_cuda_INC_DIRS} ${${_cuda_INC_DIRS}} "-I" ${CMAKE_SYSTEM_INCLUDE_PATH})
#	ENDIF (CMAKE_SYTEM_INCLUDE_PATH)
#	IF (CMAKE_INCLUDE_PATH)
#		SET(${_cuda_INC_DIRS} ${${_cuda_INC_DIRS}} "-I" ${CMAKE_INCLUDE_PATH})
#	ENDIF (CMAKE_INCLUDE_PATH)

ENDMACRO(GET_CUDA_INC_DIRS)


# Get file dependencies.
MACRO (GET_CUFILE_DEPENDENCIES dependencies file)
	GET_FILENAME_COMPONENT(filepath ${file} PATH)
	
	#  parse file for dependencies
	FILE(READ "${file}" CONTENTS)
	#STRING(REGEX MATCHALL "#[ \t]*include[ \t]+[<\"][^>\"]*" DEPS "${CONTENTS}")
	STRING(REGEX MATCHALL "#[ \t]*include[ \t]+\"[^\"]*" DEPS "${CONTENTS}")
	
	SET(${dependencies})
	
	FOREACH(DEP ${DEPS})
		STRING(REGEX REPLACE "#[ \t]*include[ \t]+\"" "" DEP "${DEP}")

		FIND_PATH(PATH_OF_${DEP} ${DEP}
			${filepath})

		IF(NOT ${PATH_OF_${DEP}} STREQUAL PATH_OF_${DEP}-NOTFOUND)
			#MESSAGE("${file} : ${PATH_OF_${DEP}}/${DEP}")
			SET(${dependencies} ${${dependencies}} ${PATH_OF_${DEP}}/${DEP})
		ENDIF(NOT ${PATH_OF_${DEP}} STREQUAL PATH_OF_${DEP}-NOTFOUND)
		
	ENDFOREACH(DEP)

ENDMACRO (GET_CUFILE_DEPENDENCIES)


# WRAP_CUDA(outfile ...)
MACRO (WRAP_CUDA outfiles)
	GET_CUDA_INC_DIRS(cuda_includes)
	#MESSAGE(${cuda_includes})

	FOREACH (CUFILE ${ARGN})
		GET_FILENAME_COMPONENT (CUFILE ${CUFILE} ABSOLUTE)
		GET_FILENAME_COMPONENT (CFILE ${CUFILE} NAME_WE)
		SET (CFILE ${CMAKE_CURRENT_BINARY_DIR}/${CFILE}.gen.cpp)

		GET_CUFILE_DEPENDENCIES(CUDEPS ${CUFILE})
		#MESSAGE("${CUDEPS}")

		ADD_CUSTOM_COMMAND (
			OUTPUT ${CFILE}
			COMMAND ${CUDA_COMPILER}
			ARGS -cuda ${cuda_includes} ${CUDA_OPTIONS} -o ${CFILE} ${CUFILE}
			MAIN_DEPENDENCY ${CUFILE}
			DEPENDS ${CUDEPS})

		#MACRO_ADD_FILE_DEPENDENCIES(${CUFILE} ${CFILE})

		SET (${outfiles} ${${outfiles}} ${CFILE})
	ENDFOREACH (CUFILE)
	
	SET_SOURCE_FILES_PROPERTIES(${outfiles} PROPERTIES GENERATED 1)
	
ENDMACRO (WRAP_CUDA)
