###############################################################################
# 
#  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/>.
#
###############################################################################

# Include the resource in the Win32 executable.
IF(WIN32)
	SET(WINDOWS_RESOURCES resources/ovito.rc)
ENDIF(WIN32)

# Builds the main executable of the application
ADD_EXECUTABLE(${PROJECT_NAME} MACOSX_BUNDLE Main.cpp ${WINDOWS_RESOURCES})

# The executable directly depends on the core modules.
TARGET_LINK_LIBRARIES(${PROJECT_NAME} Base Mesh Core)

# If we build a monolithic executable that includes all plugins then
# we have to make it dependent on these too.
#
# When statically linking the plugin libraries the linker will eliminate
# unreferenced static objects in these libraries. To prevent this from
# happening we have to use the -whole-archive linker option. 
IF(OVITO_MONOLITHIC_BUILD)

	# This macro adds a static library target to an executable target and makes sure that
	# the library is linked completely into the executable without removal of unreferenced
	# objects.
	MACRO(LINK_WHOLE_LIBRARY _targetName _libraryTarget)
		GET_TARGET_PROPERTY(EXE_LINKER_OPTIONS ${_targetName} LINK_FLAGS)
		IF(NOT EXE_LINKER_OPTIONS)
			SET(EXE_LINKER_OPTIONS "")
		ENDIF(NOT EXE_LINKER_OPTIONS)	
		GET_TARGET_PROPERTY(TARGET_LOCATION ${_libraryTarget} LOCATION)
		SET(EXE_LINKER_OPTIONS "${EXE_LINKER_OPTIONS} -Wl,-whole-archive ${TARGET_LOCATION} -Wl,-no-whole-archive ")
		SET_TARGET_PROPERTIES(${_targetName} PROPERTIES LINK_FLAGS ${EXE_LINKER_OPTIONS})
		TARGET_LINK_LIBRARIES(${_targetName} ${_libraryTarget})
	ENDMACRO(LINK_WHOLE_LIBRARY)

	LINK_WHOLE_LIBRARY(${PROJECT_NAME} Core)
	IF(OVITO_BUILD_PLUGIN_SCRIPTING)
		LINK_WHOLE_LIBRARY(${PROJECT_NAME} Scripting)
	ENDIF(OVITO_BUILD_PLUGIN_SCRIPTING)
	IF(OVITO_BUILD_PLUGIN_SCRIPTING_GUI)
		LINK_WHOLE_LIBRARY(${PROJECT_NAME} ScriptingGUI)
	ENDIF(OVITO_BUILD_PLUGIN_SCRIPTING_GUI)
	IF(OVITO_BUILD_PLUGIN_POVRAY)
		LINK_WHOLE_LIBRARY(${PROJECT_NAME} POVRay)
	ENDIF(OVITO_BUILD_PLUGIN_POVRAY)
	IF(OVITO_BUILD_PLUGIN_POVRAY)
		LINK_WHOLE_LIBRARY(${PROJECT_NAME} Tachyon)
	ENDIF(OVITO_BUILD_PLUGIN_POVRAY)
	IF(OVITO_BUILD_PLUGIN_STDOBJECTS)
		LINK_WHOLE_LIBRARY(${PROJECT_NAME} StdObjects)
	ENDIF(OVITO_BUILD_PLUGIN_STDOBJECTS)
	IF(OVITO_BUILD_PLUGIN_ATOMVIZ)
		LINK_WHOLE_LIBRARY(${PROJECT_NAME} AtomViz)
	ENDIF(OVITO_BUILD_PLUGIN_ATOMVIZ)
	IF(OVITO_BUILD_PLUGIN_CRYSTALANALYSIS)
		LINK_WHOLE_LIBRARY(${PROJECT_NAME} CrystalAnalysis)
	ENDIF(OVITO_BUILD_PLUGIN_CRYSTALANALYSIS)		
	
ENDIF(OVITO_MONOLITHIC_BUILD)

# Link the target against the Qt libraries.
TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${QT_LIBRARIES})

# This executable will be part of the installation package.
INSTALL(TARGETS ${PROJECT_NAME} DESTINATION "${OVITO_RELATIVE_BINARY_DIRECTORY}")

# Copy the application's Linux desktop file to the system's application directory.
IF(UNIX AND NOT APPLE)
	INSTALL(FILES "resources/ovito.desktop" DESTINATION "share/applications")
ENDIF(UNIX AND NOT APPLE)

IF(APPLE)
	CMAKE_MINIMUM_REQUIRED(VERSION 2.8)

	SET(APPS "\${CMAKE_INSTALL_PREFIX}/${MACOSX_BUNDLE_NAME}.app")
	
	# Install the Info.plist file.
	#CONFIGURE_FILE("resources/Info.plist" "${OVITO_BINARY_DIRECTORY}/${MACOSX_BUNDLE_NAME}.app/Contents/Info.plist")
	SET_TARGET_PROPERTIES(${PROJECT_NAME} PROPERTIES MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/resources/Info.plist")

	# Install needed Qt plugins by copying directories from the qt installation
	# One can cull what gets copied by using 'REGEX "..." EXCLUDE'
	SET(plugin_dest_dir "${MACOSX_BUNDLE_NAME}.app/Contents/MacOS")
	SET(qtconf_dest_dir "${MACOSX_BUNDLE_NAME}.app/Contents/Resources")
	INSTALL(DIRECTORY "${QT_PLUGINS_DIR}/imageformats" DESTINATION ${plugin_dest_dir}/plugins COMPONENT Runtime)

	# Copy the application icon into the resource directory.
	INSTALL(FILES "${CMAKE_CURRENT_SOURCE_DIR}/resources/ovito.icns" DESTINATION "${OVITO_RELATIVE_SHARE_DIRECTORY}")

	# Install a qt.conf file.
	# This inserts some cmake code into the install script to write the file
	INSTALL(CODE "
	    file(WRITE \"\${CMAKE_INSTALL_PREFIX}/${qtconf_dest_dir}/qt.conf\" \"[Paths]\\nPlugins = MacOS/plugins/\")
	    " COMPONENT Runtime)

	# Use BundleUtilities to get all other dependencies for the application to work.
	# It takes a bundle or executable along with possible plugins and inspects it
	# for dependencies.  If they are not system dependencies, they are copied.

	# directories to look for dependencies
	SET(DIRS ${QT_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} "${CMAKE_INSTALL_PREFIX}/${OVITO_RELATIVE_PLUGINS_DIRECTORY}" "${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/plugins/imageformats")

	# Now the work of copying dependencies into the bundle/package
	# The quotes are escaped and variables to use at install time have their $ escaped
	# An alternative is the do a configure_file() on a script and use install(SCRIPT  ...).
	# Note that the image plugins depend on QtSvg and QtXml, and it got those copied
	# over.
	INSTALL(CODE "
		# Returns the path that others should refer to the item by when the item is embedded inside a bundle.
		# This ensures that all plugin libraries go into the plugins/ directory of the bundle.
		FUNCTION(gp_item_default_embedded_path_override item default_embedded_path_var)
		    MESSAGE(\"gp_item_default_embedded_path_override item=\${item}\")
			# Let everything that is already in the bundle stay where it comes from.
	    	if(item MATCHES \"^.*/.*\\\\${MACOSX_BUNDLE_NAME}.app/.*$\")
			    MESSAGE(\"basepath= \${CMAKE_INSTALL_PREFIX}/${MACOSX_BUNDLE_NAME}.app/Contents/MacOS/\")
				FILE(RELATIVE_PATH relpath \"\${CMAKE_INSTALL_PREFIX}/${MACOSX_BUNDLE_NAME}.app/Contents/MacOS/\" \"\${item}\")
			    MESSAGE(\"relpath=\${relpath}\")
				GET_FILENAME_COMPONENT(relpath2 \${relpath} PATH)
			    MESSAGE(\"relpath2=\${relpath2}\")
			    SET(path \"@executable_path/\${relpath2}\")
			endif(item MATCHES \"^.*/.*\\\\${MACOSX_BUNDLE_NAME}.app/.*$\")
			SET(\${default_embedded_path_var} \"\${path}\" PARENT_SCOPE)
		ENDFUNCTION(gp_item_default_embedded_path_override)
		file(GLOB_RECURSE QTPLUGINS
			\"\${CMAKE_INSTALL_PREFIX}/${plugin_dest_dir}/plugins/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
		file(GLOB_RECURSE OVITO_PLUGINS
			\"\${CMAKE_INSTALL_PREFIX}/${OVITO_RELATIVE_PLUGINS_DIRECTORY}/*${CMAKE_SHARED_LIBRARY_SUFFIX}\")
		set(BUNDLE_LIBS \${QTPLUGINS} \${OVITO_PLUGINS})
		include(BundleUtilities)
		fixup_bundle(\"${APPS}\" \"\${BUNDLE_LIBS}\" \"${DIRS}\")
		" COMPONENT Runtime)
	    	
	# To Create a package, one can run "cpack -G DragNDrop CPackConfig.cmake" on Mac OS X
	# where CPackConfig.cmake is created by including CPack.
	SET(CPACK_BINARY_DRAGNDROP ON)		

ENDIF(APPLE)

