###############################################################################
# 
#  Copyright (2008) Alexander Stukowski
#
#  This file is part of OVITO (Open Visualization Tool).
#
#  OVITO is free software; you can redistribute it and/or modify
#  it under the terms of the GNU General Public License as published by
#  the Free Software Foundation; either version 2 of the License, or
#  (at your option) any later version.
#
#  OVITO is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################

PROJECT(ovito)

# Make sure we have a new version of CMake
CMAKE_MINIMUM_REQUIRED(VERSION 2.4 FATAL_ERROR)
IF(COMMAND cmake_policy)
	CMAKE_POLICY(SET CMP0003 NEW)
	IF(POLICY CMP0011)
		CMAKE_POLICY(SET CMP0011 NEW)
	ENDIF(POLICY CMP0011)
ENDIF(COMMAND cmake_policy)

# Force out-of-source build
STRING(COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" OVITO_IN_SOURCE)
IF(OVITO_IN_SOURCE)
	MESSAGE(FATAL_ERROR "OVITO requires an out of source build. Please create a separate build directory and run 'cmake path_to_ovito [options]' there.")
ENDIF(OVITO_IN_SOURCE)

# Select the Release build configuration by default.
IF(NOT CMAKE_BUILD_TYPE)
	SET(CMAKE_BUILD_TYPE "Release")
ENDIF(NOT CMAKE_BUILD_TYPE)

# This CMake file defines the options that control which parts of the application will be built.
INCLUDE(OvitoConfig.cmake)

# This is the base directory for all included header files.
INCLUDE_DIRECTORIES(${OVITO_INCLUDE_PATHS})

# Place all compiled libraries into OVITO's library directory.
SET(LIBRARY_OUTPUT_PATH "${OVITO_LIBRARY_DIRECTORY}")

# Get the current revision number from the Subversion repository.
FIND_PACKAGE(Subversion)
IF(Subversion_FOUND)
	Subversion_WC_INFO(${PROJECT_SOURCE_DIR} OVITO_PROJ)
	# The current revision number is made accessible from the source code through the OVITO_PROJ_REPOSITORY_REVISION macro.
	ADD_DEFINITIONS("-DOVITO_PROJ_REPOSITORY_REVISION=${OVITO_PROJ_WC_REVISION}")
ELSE(Subversion_FOUND)
	ADD_DEFINITIONS("-DOVITO_PROJ_REPOSITORY_REVISION=0")
ENDIF(Subversion_FOUND)

# Use pre-compiled headers
OPTION(OVITO_USE_PRECOMPILED_HEADERS "Enable the generation of precompiled headers to speed up compilation." "ON")
SET(PCH_INCLUDE_FILE "cmake/PCHSupport_${CMAKE_MAJOR_VERSION}${CMAKE_MINOR_VERSION}.cmake")
IF(NOT EXISTS "${CMAKE_SOURCE_DIR}/${PCH_INCLUDE_FILE}")
	IF(OVITO_USE_PRECOMPILED_HEADERS)
		MESSAGE(FATAL_ERROR "The use of precompiled headers to build OVITO is not supported with this version of CMake. Please set the OVITO_USE_PRECOMPILED_HEADERS option to OFF.")
	ENDIF(OVITO_USE_PRECOMPILED_HEADERS)
ELSE(NOT EXISTS "${CMAKE_SOURCE_DIR}/${PCH_INCLUDE_FILE}")
	INCLUDE(${PCH_INCLUDE_FILE})
ENDIF(NOT EXISTS "${CMAKE_SOURCE_DIR}/${PCH_INCLUDE_FILE}")

# Build base module.
ADD_SUBDIRECTORY(src/base)

# Build mesh module.
ADD_SUBDIRECTORY(src/mesh)

# Build core module.
ADD_SUBDIRECTORY(src/core)

########## Build Plugins ##############

# Place all plugins libraries into the plugin directory.
FILE(MAKE_DIRECTORY ${OVITO_PLUGINS_DIRECTORY})
INSTALL(DIRECTORY DESTINATION ${OVITO_RELATIVE_PLUGINS_DIRECTORY})
SET(LIBRARY_OUTPUT_PATH "${OVITO_PLUGINS_DIRECTORY}")

########## Scripting Plugin ############
IF(OVITO_BUILD_PLUGIN_SCRIPTING)
	ADD_SUBDIRECTORY(src/scripting)
ELSE(OVITO_BUILD_PLUGIN_SCRIPTING)	
	FILE(REMOVE ${OVITO_PLUGINS_DIRECTORY}/Scripting.manifest.xml)
ENDIF(OVITO_BUILD_PLUGIN_SCRIPTING)

########## Scripting GUI Plugin ############
IF(OVITO_BUILD_PLUGIN_SCRIPTING_GUI)
	ADD_SUBDIRECTORY(src/scripting_gui)
ELSE(OVITO_BUILD_PLUGIN_SCRIPTING_GUI)	
	FILE(REMOVE ${OVITO_PLUGINS_DIRECTORY}/ScriptingGUI.manifest.xml)
ENDIF(OVITO_BUILD_PLUGIN_SCRIPTING_GUI)

############## POVRay Plugin ################
IF(OVITO_BUILD_PLUGIN_POVRAY)
	ADD_SUBDIRECTORY(src/povray)
ELSE(OVITO_BUILD_PLUGIN_POVRAY)	
	FILE(REMOVE ${OVITO_PLUGINS_DIRECTORY}/POVRay.manifest.xml)
ENDIF(OVITO_BUILD_PLUGIN_POVRAY)

############ StdObjects Plugin ##############
IF(OVITO_BUILD_PLUGIN_STDOBJECTS)
	ADD_SUBDIRECTORY(src/stdobjects)
ELSE(OVITO_BUILD_PLUGIN_STDOBJECTS)
	FILE(REMOVE ${OVITO_PLUGINS_DIRECTORY}/StdObjects.manifest.xml)
ENDIF(OVITO_BUILD_PLUGIN_STDOBJECTS)

############## AtomViz Plugin ###############
IF(OVITO_BUILD_PLUGIN_ATOMVIZ)
	ADD_SUBDIRECTORY(src/atomviz)
ELSE(OVITO_BUILD_PLUGIN_ATOMVIZ)	
	FILE(REMOVE ${OVITO_PLUGINS_DIRECTORY}/AtomViz.manifest.xml)
ENDIF(OVITO_BUILD_PLUGIN_ATOMVIZ)

############## CrystalAnalysis Plugin ###############
IF(OVITO_BUILD_PLUGIN_CRYSTALANALYSIS)
	ADD_SUBDIRECTORY(src/crystalanalysis)
ELSE(OVITO_BUILD_PLUGIN_CRYSTALANALYSIS)	
	FILE(REMOVE ${OVITO_PLUGINS_DIRECTORY}/CrystalAnalysis.manifest.xml)
ENDIF(OVITO_BUILD_PLUGIN_CRYSTALANALYSIS)

################# Main executable ####################

# Place the executable into the "bin" output directory.
SET(EXECUTABLE_OUTPUT_PATH ${OVITO_BINARY_DIRECTORY})
ADD_SUBDIRECTORY(src/mainexec)

################# Third-party DLLs ####################

# On Window the third-party library DLLs are usually not part of the system. 
# We need to copy them to the OVITO directory.
IF(WIN32)
	# Gather required Qt library DLLs.
	IF(CMAKE_BUILD_TYPE STREQUAL "Debug")
		SET(QT_DLL_DEBUG_SUFFIX "d")
	ENDIF(CMAKE_BUILD_TYPE STREQUAL "Debug")
	FOREACH(component "Core" "Gui" "OpenGL" "Help" "Xml")
		LIST(APPEND REQUIRED_DLLS "${QT_BINARY_DIR}/Qt${component}${QT_DLL_DEBUG_SUFFIX}${QT_VERSION_MAJOR}.dll")
	ENDFOREACH(component "Core" "Gui" "OpenGL" "Help" "Xml")
	
	# Gather required Boost library DLLs.
	SET(LIBLIST ${Boost_LIBRARIES})
	LIST(LENGTH LIBLIST LIBLIST_COUNT)
	WHILE(LIBLIST_COUNT)
		LIST(GET LIBLIST 0 LIB_NAME)
		SET(USE_LIB FALSE)
		IF(LIB_NAME STREQUAL "optimized" AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
			SET(USE_LIB TRUE)
		ENDIF(LIB_NAME STREQUAL "optimized" AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
		IF(LIB_NAME STREQUAL "debug" AND CMAKE_BUILD_TYPE STREQUAL "Debug")
			SET(USE_LIB TRUE)
		ENDIF(LIB_NAME STREQUAL "debug" AND CMAKE_BUILD_TYPE STREQUAL "Debug")			
		IF(USE_LIB)
			LIST(REMOVE_AT LIBLIST 0)
			LIST(GET LIBLIST 0 LIB_NAME)
			STRING(REPLACE ".lib" ".dll" DLL_NAME ${LIB_NAME})
			LIST(APPEND REQUIRED_DLLS "${DLL_NAME}")
			IF(DLL_NAME MATCHES "boost_iostreams")
				STRING(REPLACE "iostreams" "zlib" DLL_NAME ${DLL_NAME})
				LIST(APPEND REQUIRED_DLLS "${DLL_NAME}")
			ENDIF(DLL_NAME MATCHES "boost_iostreams")
		ENDIF(USE_LIB)
		LIST(REMOVE_AT LIBLIST 0)
		LIST(LENGTH LIBLIST LIBLIST_COUNT)
	ENDWHILE(LIBLIST_COUNT)		
	
	# Copy library DLLs to output directory.
	FOREACH(dll ${REQUIRED_DLLS})
		CONFIGURE_FILE("${dll}" "${OVITO_BINARY_DIRECTORY}" COPYONLY)
		INSTALL(FILES "${dll}" DESTINATION "${OVITO_RELATIVE_BINARY_DIRECTORY}")
	ENDFOREACH(dll ${REQUIRED_DLLS})
ENDIF(WIN32)

################# Auxiliary files #######################

# Copy example files to output directory
COPY_DIRECTORY_WITHOUT_SVN("${CMAKE_SOURCE_DIR}/examples" "${OVITO_SHARE_DIRECTORY}/examples")
INSTALL(DIRECTORY "${OVITO_SHARE_DIRECTORY}/examples/" DESTINATION "${OVITO_RELATIVE_SHARE_DIRECTORY}/examples/")

################## Build documentation #####################

IF(OVITO_BUILD_DOCUMENTATION)
	INCLUDE(cmake/Documentation.cmake)
	ADD_DEPENDENCIES(ovito documentation)
	INSTALL(FILES "${OVITO_SHARE_DIRECTORY}/doc/manual/assistant/documentation.qhc" DESTINATION "${OVITO_RELATIVE_SHARE_DIRECTORY}/doc/manual/assistant/")
	INSTALL(FILES "${OVITO_SHARE_DIRECTORY}/doc/manual/assistant/documentation.qch" DESTINATION "${OVITO_RELATIVE_SHARE_DIRECTORY}/doc/manual/assistant/")
	INSTALL(DIRECTORY "${OVITO_SHARE_DIRECTORY}/doc/manual/html/" DESTINATION "${OVITO_RELATIVE_SHARE_DIRECTORY}/doc/manual/html/" PATTERN ".svn" EXCLUDE)
ENDIF(OVITO_BUILD_DOCUMENTATION)

#### Publish build configuration files for use by plugins #####

# Copy the CMAKE config files to destination directory.
# These are used to publish the current build settings to independent plugin projects
# that want to link to the OVITO core project. 
FILE(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/cmake")
CONFIGURE_FILE("OvitoConfig.cmake" "${PROJECT_BINARY_DIR}/" COPYONLY)
CONFIGURE_FILE("cmake/Version.cmake" "${PROJECT_BINARY_DIR}/cmake/" COPYONLY)
CONFIGURE_FILE("cmake/CompileQtResource.cmake" "${PROJECT_BINARY_DIR}/cmake/" COPYONLY)

######################### Setup CPack #######################
INCLUDE(cmake/Installation.cmake)
