#
#  Copyright (c) 2002-2015 Nick Gnedin 
#  All rights reserved.
#
#  This file may be distributed and/or modified under the terms of the
#  GNU General Public License version 2 as published by the Free Software
#  Foundation and appearing in the file LICENSE.GPL included in the
#  packaging of this file.
#
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.8)

IF(COMMAND cmake_policy)
	cmake_policy(SET CMP0003 NEW)
ENDIF(COMMAND cmake_policy)


SET(src ..)
PROJECT(IFrIT)

SET(Option:StereoSupport 1 CACHE BOOL "Enable OpenGL support for displaying stereo (disable this option if you see flicker)")

#
#  Portability options
#
SET(Port:SearchOGL 0 CACHE BOOL "Search for OpenGL (normally should be found automatically)")
SET(Port:SearchX11 0 CACHE BOOL "Search for X11 (normally should be found automatically)")
SET(Port:NoLongLong  0 CACHE BOOL "Do not use long long type")
SET(Port:Debian  0 CACHE BOOL "Do not use long long type")
MARK_AS_ADVANCED(Port:SearchOGL Port:SearchX11 Port:NoLongLong)

IF(NOT CMAKE_BUILD_TYPE)
       SET(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)

#
# ---------------------------------------------------------------------------
#
# Configuration
#
# ---------------------------------------------------------------------------
#
#  Shells
#
IF(WIN32)
	OPTION(Shell:CL "Include command-line shell" OFF)
ELSE(WIN32)
	OPTION(Shell:CL "Include command-line shell" ON)
ENDIF(WIN32)
OPTION(Shell:QT "Include Qt-based GUI shell" ON)
OPTION(Shell:OS "Include off-screen shell" ON)

SET(tty_shells)
SET(gui_shells)

IF(Shell:CL)
	SET(tty_shells ${tty_shells} cl)
ENDIF(Shell:CL)

IF(Shell:OS)
	SET(tty_shells ${tty_shells} os)
ENDIF(Shell:OS)

IF(Shell:QT)
	SET(gui_shells ${gui_shells} qt)
ENDIF(Shell:QT)

IF(NOT tty_shells AND NOT gui_shells)
	MESSAGE(FATAL_ERROR "At least one shell must be selected.")
ENDIF(NOT tty_shells AND NOT gui_shells)

#
#  Scripts
#
OPTION(Script:PY "Use Python as scripting language" ON)

SET(scripts)

IF(Script:PY)
	SET(scripts ${scripts} python)
ENDIF(Script:PY)

IF(NOT scripts)
	MESSAGE("No scripting language is selected - IFrIT will not be able to use scripts.")
ENDIF(NOT scripts)

IF(Shell:OS AND NOT scripts)
	MESSAGE(FATAL_ERROR "The off-screen shell will not work without a script.")
ENDIF(Shell:OS AND NOT scripts)

#
#  Find max extension flag
#
SET(maxNum 1)
FILE(READ ${src}/configure/iextensiondefines.h f)

STRING(REGEX MATCHALL "#define IEXTENSION_[A-Z0-9_]*[ \t]*[0-9]*" m ${f})
IF(m)
	STRING(REGEX REPLACE "#define IEXTENSION_[A-Z0-9_]*[ \t]*([0-9]*)" "\\1;" num ${m})
	SET(num ${num}0)
	FOREACH(n ${num})
		IF(n GREATER ${maxNum})
			SET(maxNum ${n})
		ENDIF(n GREATER ${maxNum})
	ENDFOREACH(n ${num})
ENDIF(m)

#
#  Configure extensions
#
SET(extensions)
FILE(GLOB dir ${src}/build/install.*.cpp)

IF(dir)
	FOREACH(s ${dir})
		STRING(REGEX REPLACE "^.*install\\.([A-Z0-9_]*)\\.cpp" "\\1" e ${s}) 
		OPTION(Extension:${e} "Include ${e} extension" ON)
		IF(Extension:${e})
			set(extensions ${extensions} ${e})
		ENDIF(Extension:${e})
#
#  Check that the define for this extension has been set already.
#			
		STRING(REGEX MATCH "#define IEXTENSION_${e}[ \t]*[0-9]*" m ${f})
		IF(NOT m)

			MESSAGE("Extension ${e} has not been defined in configure/iextensiondefines.h.\n I will define it for you.")
			SET(maxNum 2*${maxNum})
			FILE(APPEND ${src}/configure/iextensiondefines.h "#define IEXTENSION_${e} ${maxNum}\n")

		ENDIF(NOT m)

	ENDFOREACH(s ${dir})
ENDIF(dir)

#
# ---------------------------------------------------------------------------
#
#  Find dependencies
#
# ---------------------------------------------------------------------------
#
# Find VTK
FIND_PACKAGE(VTK REQUIRED)
IF(NOT VTK_FOUND)
	MESSAGE(FATAL_ERROR " VTK is not found. Please check that VTKDIR variables is set properly.")
ENDIF(NOT VTK_FOUND)
INCLUDE(${VTK_USE_FILE})

IF(VTK_USE_VOLUMEPRO AND VTK_HAVE_VP1000)
	OPTION(CustomVP1000 "Include custom support for VP1000" ON)
ENDIF(VTK_USE_VOLUMEPRO AND VTK_HAVE_VP1000)

# Find OpenGL
IF(Port:SearchOGL)
	FIND_PACKAGE(OPENGL REQUIRED)
	IF(NOT OPENGL_FOUND)
		MESSAGE(FATAL_ERROR " OpenGL is not found. Please set advanced variables OPENGL_INCLUDE_DIR and OPENGL_LIBRARIES.")
	ENDIF(NOT OPENGL_FOUND)
	INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})
ENDIF(Port:SearchOGL)

# Find X11
IF(UNIX AND Port:SearchX11)
	FIND_PACKAGE(X11 REQUIRED)
	IF(NOT X11_FOUND)
		MESSAGE(FATAL_ERROR " X11 is not found. Please set advanced variables X11_X11_INCLUDE_PATH and X11_LIBRARIES.")
	ENDIF(NOT X11_FOUND)
	INCLUDE_DIRECTORIES(${X11_X11_INCLUDE_PATH})
ENDIF(UNIX AND Port:SearchX11)

IF(Shell:QT)
	# Find Qt
	SET(QT_REQUIRED 1)
	INCLUDE(${CMAKE_ROOT}/Modules/FindQt.cmake)
	INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR})
	IF(QT4_INSTALLED)
		INCLUDE_DIRECTORIES(${QT_INCLUDE_DIR}/QtCore)
	ENDIF(QT4_INSTALLED)
	ADD_DEFINITIONS(${QT_DEFINITIONS})
ENDIF(Shell:QT)

IF(Script:PY)
	# Find Python
	SET(Python_ADDITIONAL_VERSIONS 3.4 3.3 3.2 3.1 3.0)
	INCLUDE(${CMAKE_ROOT}/Modules/FindPythonLibs.cmake)
	IF(PYTHONLIBS_FOUND)
		IF(PYTHONLIBS_VERSION_STRING STRLESS "2.7.0")
			MESSAGE(FATAL_ERROR " IFrIT needs Python 2.7 and higher. Please upgrade your Python installation.")
		ENDIF(PYTHONLIBS_VERSION_STRING STRLESS "2.7.0")
		INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_DIRS})

		SET(BuildPythonModule 0 CACHE BOOL "Build and install a shared library for Python import. That requires that all VTK, Qt, and Python libraries are built as shared objects.")

	ELSE(PYTHONLIBS_FOUND)
		MESSAGE(FATAL_ERROR " Python is not found. Install Python on your system or uncheck Script:PY option")
	ENDIF(PYTHONLIBS_FOUND)
ENDIF(Script:PY)

#
# ---------------------------------------------------------------------------
#
#  Create the project
#
# ---------------------------------------------------------------------------
#
SET(my_shl 0)
SET(my_scr 0)
SET(my_ext 0)
#
#  Core
#
FILE(GLOB sources ${src}/configure/*.cpp ${src}/core/*.cpp ${src}/help/*.cpp)
INCLUDE_DIRECTORIES(${src}/configure ${src}/core ${src}/help ${src}/docs)

#
#  Shells
#
IF(gui_shells)
	FILE(GLOB tmp ${src}/shells/configure/*.cpp ${src}/shells/generic/*.cpp ${src}/shells/base/*.cpp)
	IF(tmp)
		SET(sources ${sources} ${tmp})
		INCLUDE_DIRECTORIES(${src}/shells/configure ${src}/shells/generic ${src}/shells/base)
	ENDIF(tmp)
ENDIF(gui_shells)

FOREACH(s ${tty_shells} ${gui_shells})
	FILE(GLOB tmp ${src}/shells/${s}/*.cpp)
	IF(tmp)
		SET(sources ${sources} ${tmp})
		INCLUDE_DIRECTORIES(${src}/shells/${s})
		STRING(TOUPPER ${s} us)
		SET(my_shl ${my_shl}+ISHELL_${us})
	ENDIF(tmp)
ENDFOREACH(s)

#
#  Scripts
#
IF(scripts)
	FILE(GLOB tmp ${src}/scripts/configure/*.cpp)
	IF(tmp)
		SET(sources ${sources} ${tmp})
		INCLUDE_DIRECTORIES(${src}/scripts/configure)
	ENDIF(tmp)
ENDIF(scripts)

FOREACH(s ${scripts})
	FILE(GLOB tmp ${src}/scripts/${s}/*.cpp)
	IF(tmp)
		SET(sources ${sources} ${tmp})
		INCLUDE_DIRECTORIES(${src}/scripts/${s})
		STRING(TOUPPER ${s} us)
		SET(my_scr ${my_scr}+ISCRIPT_${us})
	ENDIF(tmp)
ENDFOREACH(s)

#
#  Extensions
#
FOREACH(e ${extensions})
	SET(my_ext ${my_ext}+IEXTENSION_${e})
ENDFOREACH(e)

FILE(GLOB tmp ${src}/core/imultiviewrendertool.cpp)
IF(tmp)
	SET(my_ext ${my_ext}+IEXTENSION_MV)
ENDIF(tmp)

#
#  Special
#
IF(Shell:QT)
	SET(qtdir ${src}/shells/qt)
	SET(qthdr ${qtdir}/iqtwidgettexteditorsubject.h ${qtdir}/iqtwidgethelper.h ${qtdir}/iqtrenderwindowsubject.h ${qtdir}/iqtmenuwindowsubject.h ${qtdir}/iqtmainwindowsubject.h ${qtdir}/iqtframesubject.h)
	SET(tmp)
	QT_WRAP_CPP(dummy tmp ${qthdr})
	SET(sources ${sources} ${tmp})
ENDIF(Shell:QT)

IF(CustomVP1000)
	FILE(GLOB tmp ${src}/special/vp1000/*.cpp)
	IF(tmp)
		SET(sources ${sources} ${tmp})
		INCLUDE_DIRECTORIES(${src}/special/vp1000)
		ADD_DEFINITIONS(-DI_CUSTOM_VP1000)
	ENDIF(tmp)
ENDIF(CustomVP1000)

IF(Extension:ART)
	FILE(GLOB tmp ${src}/special/artio/*.c)
	IF(tmp)
		SET(sources ${sources} ${tmp})
		INCLUDE_DIRECTORIES(${src}/special/artio)
	ENDIF(tmp)
ENDIF(Extension:ART)


ADD_DEFINITIONS(-DI_EXTERNAL_CONFIGURATION)

IF(CMAKE_BUILD_TYPE MATCHES "Debug")
	ADD_DEFINITIONS(-DI_DEBUG -DI_CHECK)
ENDIF(CMAKE_BUILD_TYPE MATCHES "Debug")

#
#  Edition
#
FILE(GLOB tmp ${src}/configure/edition*.cpp)
IF(tmp) 
	ADD_DEFINITIONS(-DI_EDITION)
ENDIF(tmp) 

FILE(GLOB tmp ${src}/configure/iconfiguresettings.ext) 
CONFIGURE_FILE(${tmp} ${tmp}.h @ONLY)

IF(NOT Option:StereoSupport)
	ADD_DEFINITIONS(-DI_NO_STEREO)
ENDIF(NOT Option:StereoSupport)

#
#  Portability
#
IF(Port:NoLongLong)
	ADD_DEFINITIONS(-DI_NO_LONG_LONG)
ENDIF(Port:NoLongLong)
IF(Port:Debian)
	ADD_DEFINITIONS(-DI_PORT_DEBIAN)
ENDIF(Port:Debian)

#
#  Add libraries
#
FUNCTION(link target)
TARGET_LINK_LIBRARIES(${target} ${VTK_LIBRARIES}) 

IF(Port:SearchOGL)
	TARGET_LINK_LIBRARIES(${target} ${OPENGL_LIBRARIES}) 
ENDIF(Port:SearchOGL)

IF(UNIX AND Port:SearchX11)
	TARGET_LINK_LIBRARIES(${target} ${X11_LIBRARIES})
ENDIF(UNIX AND Port:SearchX11)

IF(Shell:QT)
	IF(QT_LIBRARIES)
		TARGET_LINK_LIBRARIES(${target} ${QT_LIBRARIES}) 
	ENDIF(QT_LIBRARIES)
	IF(QT4_INSTALLED)
		TARGET_LINK_LIBRARIES(${target} ${QT_QTCORE_LIBRARY} ${QT_QTGUI_LIBRARY} ${QT_QT3SUPPORT_LIBRARY} ${QT_QTOPENGL_LIBRARY}) 
		IF (WIN32)
			FIND_LIBRARY(QT_QTMAIN_LIBRARY qtmain ${QT_LIBRARY_DIR} DOC "This Library is only needed by and included with Qt on MSWindows. It should be NOTFOUND, undefined or IGNORE otherwise.")
			IF(QT_QTMAIN_LIBRARY)
				TARGET_LINK_LIBRARIES(${target} ${QT_QTMAIN_LIBRARY}) 
			ELSE(QT_QTMAIN_LIBRARY)
				MESSAGE(FATAL_ERROR " Qt Main library qtmain.lib is not found.")
			ENDIF(QT_QTMAIN_LIBRARY)
		ENDIF (WIN32)
	ENDIF(QT4_INSTALLED)
ENDIF(Shell:QT)

IF(Script:PY)
	TARGET_LINK_LIBRARIES(${target} ${PYTHON_LIBRARIES})
	IF(UNIX)
		TARGET_LINK_LIBRARIES(${target} util)
	ENDIF(UNIX)
ENDIF(Script:PY)
ENDFUNCTION(link)

#
#  Create targets
#
FILE(GLOB dir install.*.cpp)

ADD_LIBRARY(temp STATIC ${sources})
SET_TARGET_PROPERTIES(temp PROPERTIES POSITION_INDEPENDENT_CODE true)
link(temp)

IF(tty_shells)
	ADD_EXECUTABLE(ifrit ifrit.cpp ${dir})
ELSE(tty_shells)
	ADD_EXECUTABLE(ifrit WIN32 ifrit.cpp ${dir})
ENDIF(tty_shells)
SET_TARGET_PROPERTIES(ifrit PROPERTIES RUNTIME_OUTPUT_DIRECTORY ..)
TARGET_LINK_LIBRARIES(ifrit temp)

INSTALL(TARGETS ifrit RUNTIME DESTINATION bin)

IF(BuildPythonModule AND PYTHON_INCLUDE_DIRS)
	ADD_LIBRARY(python SHARED python.cpp ${dir})
	SET_TARGET_PROPERTIES(python PROPERTIES PREFIX "")
	SET_TARGET_PROPERTIES(python PROPERTIES OUTPUT_NAME ifrit)
	SET_TARGET_PROPERTIES(python PROPERTIES LIBRARY_OUTPUT_DIRECTORY ..)
	TARGET_LINK_LIBRARIES(python temp)

	STRING(REGEX REPLACE "libpython([0-9]\\.[0-9])[m]*\\.[a-z]*" "python\\1/site-packages" dir ${PYTHON_LIBRARIES})
	IF(EXISTS ${dir})
		INSTALL(TARGETS python LIBRARY DESTINATION ${dir})
	ELSE(EXISTS ${dir})
		MESSAGE(ERROR " Unable to find the installation directory " ${dir} " for Python module. Python module will not be installed.")
	ENDIF(EXISTS ${dir})

ENDIF(BuildPythonModule AND PYTHON_INCLUDE_DIRS)

