###############################################################################
# 
#  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.6 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)

# Support for pre-compiled headers.
OPTION(OVITO_USE_PRECOMPILED_HEADERS "Enable the generation of precompiled headers to speed up compilation." "ON")
INCLUDE("cmake/PCHSupport.cmake")

# 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)

############## Tachyon Renderer Plugin ###############
IF(OVITO_BUILD_PLUGIN_TACHYON)
	ADD_SUBDIRECTORY(src/tachyon)
ELSE(OVITO_BUILD_PLUGIN_TACHYON)
	FILE(REMOVE ${OVITO_PLUGINS_DIRECTORY}/Tachyon.manifest.xml)
ENDIF(OVITO_BUILD_PLUGIN_TACHYON)

############ 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" "Network")
		LIST(APPEND REQUIRED_DLLS "${QT_BINARY_DIR}/Qt${component}${QT_DLL_DEBUG_SUFFIX}${QT_VERSION_MAJOR}.dll")
	ENDFOREACH(component "Core" "Gui" "OpenGL" "Help" "Xml" "Network")
	
	# Gather required Boost library DLLs.
	FOREACH(LIB_NAME ${Boost_LIBRARIES})
		IF("${LIB_NAME}" STREQUAL "optimized")
			IF("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
				SET(SKIP_NEXT_LIB NO)
			ELSE()
				SET(SKIP_NEXT_LIB YES)
			ENDIF()
		ELSEIF("${LIB_NAME}" STREQUAL "debug")
			IF("${CMAKE_BUILD_TYPE}" STREQUAL "Debug")
				SET(SKIP_NEXT_LIB NO)
			ELSE()
				SET(SKIP_NEXT_LIB YES)
			ENDIF()
		ELSEIF(NOT SKIP_NEXT_LIB)
			STRING(REPLACE ".lib" ".dll" DLL_NAME ${LIB_NAME})
			LIST(APPEND REQUIRED_DLLS "${DLL_NAME}")
			IF(DLL_NAME MATCHES "boost_iostreams")
				STRING(REPLACE "boost_iostreams" "boost_zlib" DLL_NAME ${DLL_NAME})
				STRING(REPLACE "/build/" "/build/zlib/" DLL_NAME ${DLL_NAME})
				LIST(APPEND REQUIRED_DLLS "${DLL_NAME}")
			ENDIF(DLL_NAME MATCHES "boost_iostreams")
		ENDIF()
	ENDFOREACH(LIB_NAME ${Boost_LIBRARIES})		
	
	# Copy library DLLs to output directory.
	FOREACH(dll ${REQUIRED_DLLS})
		MESSAGE("Installing DLL library ${dll} in output directory.")
		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)
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)
CONFIGURE_FILE("cmake/Plugins.cmake" "${PROJECT_BINARY_DIR}/cmake/" COPYONLY)
CONFIGURE_FILE("cmake/FileUtilities.cmake" "${PROJECT_BINARY_DIR}/cmake/" COPYONLY)

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