# The BEGIN_PKG  macro prepare the generation of a cpack package. 
#  It set a lot of CPACK variable, but do not perform the CPACK generation.
# After calling CONFIGURE_PACKAGE you can call  CREATE_PACKAGE to actually generate the cpack file.
#
# 	BEGIN_PKG( packageName
#					[ DESCRIPTION descritpiron]
#					[USE_SVN_REVISION  | PACKAGE_VERSION major minor patch]
#					[FILES_DIRECTORY direcotry]
#					[EXTERNAL_LIB path_to_cmake_project]
#					[ENV_VARIABLE name]
#					[ENV_FOLDER relative_folder]	
#					[PACKAGE_MODIFY_PATH] 
#					[SOURCE_IGNORE_FILES pat pat ...] 
#					[SOURCE])
#
# 	packageName is the name of the package to create.
#	DESCRITPION is a string that describe the package
#	USE_SVN_REVISION Use the svn revision of the root cmake dir for version.
# 	PACKAGE_VERSION is list of 3 variable corresponding to the major, minor and patch version of the package
#	EXTERNAL_LIB is a path to a cmake project installing some externals libs. 
#	(Nb: the "package" target will try to do "cmake ${EXTERNAL_LIB}")
# 	ENV_VARIABLE is the name of an environnemnt variable that will be add to the user environment variables
# 	ENV_FOLDER contain a path relativ to the install path. This is the value that will be added to ENV_VARIABLE
# 	PACKAGE_MODIFY_PATH => NSIS will add a pannel to ask if you want to add the program in the PATH.
#   	SOURCE_IGNORE_FILES  a list of patern of files to ignore (not tested)
#	SOURCE create a source package (not tested)
#
#
#     ADD_INSTALL_TYPE(typename
#                            [DISPLAY_NAME name])   
#
#     ADD_COMPONENT_GROUP(groupname
#                              [DISPLAY_NAME name]
#                              [DESCRIPTION description]
#                              [PARENT_GROUP parent]
#                              [EXPANDED]
#                              [BOLD_TITLE])
#SET(CPACK_PACKAGE_VENDOR "")
#SET(CPACK_NSIS_HELP_LINK "")
#SET(CPACK_NSIS_URL_INFO_ABOUT "")
#SET(CPACK_NSIS_CONTACT "")	
#                      
#   END_PKG()
# The END_PKG macro create a previously configured package, and clean-up the CPACK variable if asked.
# It also add a target "package" that take care of making all the package using the cmake command.
# The cpack generated files are ${CPACK_PACKAGE_NAME}.cpack
# 
# The PARSE_ARGUMENTS macro is from http://www.cmake.org/Wiki/CMakeMacroParseArguments



# Argument-parsing macro from http://www.cmake.org/Wiki/CMakeMacroParseArguments
MACRO(PARSE_ARGUMENTS prefix arg_names option_names)
  SET(DEFAULT_ARGS)
  FOREACH(arg_name ${arg_names})    
    SET(${prefix}_${arg_name})
  ENDFOREACH(arg_name)
  #FOREACH(option ${option_names})
  #  SET(${prefix}_${option} FALSE)
  #ENDFOREACH(option)

  SET(current_arg_name DEFAULT_ARGS)
  SET(current_arg_list)
  FOREACH(arg ${ARGN})            
    SET(larg_names ${arg_names})    
    LIST(FIND larg_names "${arg}" is_arg_name)                   
    IF (is_arg_name GREATER -1)
      SET(${prefix}_${current_arg_name} ${current_arg_list})
      SET(current_arg_name ${arg})
      SET(current_arg_list)
    ELSE (is_arg_name GREATER -1)
      SET(loption_names ${option_names})    
      LIST(FIND loption_names "${arg}" is_option)            
      IF (is_option GREATER -1)
	     SET(${prefix}_${arg} TRUE)
      ELSE (is_option GREATER -1)
	     SET(current_arg_list ${current_arg_list} ${arg})
      ENDIF (is_option GREATER -1)
    ENDIF (is_arg_name GREATER -1)
  ENDFOREACH(arg)
  SET(${prefix}_${current_arg_name} ${current_arg_list})
ENDMACRO(PARSE_ARGUMENTS)

MACRO(BEGIN_PKG PACKAGE_NAME)
PARSE_ARGUMENTS("${PACKAGE_NAME}" 
				"DESCRIPTION;PACKAGE_VERSION;FILES_DIRECTORY;EXTERNAL_LIB;ENV_VARIABLE;ENV_FOLDER;SOURCE_IGNORE_FILES" 
				"PACKAGE_MODIFY_PATH;SOURCE;USE_SVN_REVISION" 
				${ARGN})

# General Config
IF(NOT CPACK_GENERATOR)
	IF(WIN32 AND NOT UNIX)
		SET(CPACK_GENERATOR "NSIS")
	ELSE(WIN32 AND NOT UNIX)
		SET(CPACK_GENERATOR "TGZ")
	ENDIF(WIN32 AND NOT UNIX)
ENDIF(NOT CPACK_GENERATOR)

SET(CPACK_PACKAGE_NAME ${PACKAGE_NAME})

# sources
IF(${PACKAGE_NAME}_SOURCE)
	SET(SRC_POSTFIX "-src")
	SET(CPACK_SOURCE_OUTPUT_CONFIG_FILE ${PACKAGE_NAME}${SRC_POSTFIX}.cpack)
	IF(NOT ${PACKAGE_NAME}_SOURCE_IGNORE_FILES)
		SET(CPACK_SOURCE_IGNORE_FILES "/CVS/;/.svn/")
	ELSE()
		SET(CPACK_SOURCE_IGNORE_FILES ${PACKAGE_NAME}_SOURCE_IGNORE_FILES)
	ENDIF()
ENDIF(${PACKAGE_NAME}_SOURCE)

SET(CPACK_OUTPUT_CONFIG_FILE ${PACKAGE_NAME}${SRC_POSTFIX}.cpack)

SET(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_BINARY_DIR};${CMAKE_PROJECT_NAME};ALL;/")

# External lib
IF (${PACKAGE_NAME}_EXTERNAL_LIB)
	SET(CPACK_INSTALL_CMAKE_PROJECTS "${CMAKE_BINARY_DIR};${CMAKE_PROJECT_NAME};ALL;/" 
									  "${${PACKAGE_NAME}_EXTERNAL_LIB};ExternalLibs;ALL;/")
ENDIF(${PACKAGE_NAME}_EXTERNAL_LIB)

# Package Description
IF (${PACKAGE_NAME}_DESCRIPTION)
	SET(CPACK_PACKAGE_DESCRIPTION "${${PACKAGE_NAME}_DESCRIPTION}")
	SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${${PACKAGE_NAME}_DESCRIPTION}")
ELSE (${PACKAGE_NAME}_DESCRIPTION)
	SET(CPACK_PACKAGE_DESCRIPTION "This is ${PACKAGE_NAME}.")
	SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "This is ${PACKAGE_NAME}.")
ENDIF (${PACKAGE_NAME}_DESCRIPTION)

#Version
SET(CPACK_PACKAGE_VERSION_MAJOR "0")
SET(CPACK_PACKAGE_VERSION_MINOR "0")
SET(CPACK_PACKAGE_VERSION_PATCH "0")
IF(${PACKAGE_NAME}_USE_SVN_REVISION)
	FIND_PACKAGE(Subversion)
	Subversion_WC_INFO(${CMAKE_SOURCE_DIR} SDK)
	SET(CPACK_PACKAGE_VERSION_MAJOR "SVN")
	SET(CPACK_PACKAGE_VERSION_MINOR "r")
	SET(CPACK_PACKAGE_VERSION_PATCH "${SDK_WC_LAST_CHANGED_REV}")
ENDIF(${PACKAGE_NAME}_USE_SVN_REVISION)
IF (${PACKAGE_NAME}_PACKAGE_VERSION)
	LIST(GET ${PACKAGE_NAME}_PACKAGE_VERSION 0 CPACK_PACKAGE_VERSION_MAJOR)
	LIST(GET ${PACKAGE_NAME}_PACKAGE_VERSION 1 CPACK_PACKAGE_VERSION_MINOR)
	LIST(GET ${PACKAGE_NAME}_PACKAGE_VERSION 2 CPACK_PACKAGE_VERSION_PATCH)
ENDIF (${PACKAGE_NAME}_PACKAGE_VERSION)

# Add some ressources file for the licence etc ...
IF (NOT ${PACKAGE_NAME}_FILES_DIRECTORY)
	SET(${PACKAGE_NAME}_FILES_DIRECTORY ".")
ENDIF(NOT ${PACKAGE_NAME}_FILES_DIRECTORY)
IF(EXISTS "${${PACKAGE_NAME}_FILES_DIRECTORY}/Licence.txt")
	SET(CPACK_RESOURCE_FILE_LICENSE "${${PACKAGE_NAME}_FILES_DIRECTORY}/Licence.txt")
ENDIF()
IF(EXISTS "${${PACKAGE_NAME}_FILES_DIRECTORY}/README.txt")
	SET(CPACK_RESOURCE_FILE_README "${${PACKAGE_NAME}_FILES_DIRECTORY}/README.txt")
	SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CPACK_RESOURCE_FILE_README}")
ENDIF()
IF(EXISTS "${${PACKAGE_NAME}_FILES_DIRECTORY}/DESCRIPTION.txt")
	SET(CPACK_PACKAGE_DESCRIPTION_FILE "${${PACKAGE_NAME}_FILES_DIRECTORY}/DESCRIPTION.txt")
ENDIF()
IF(EXISTS "${${PACKAGE_NAME}_FILES_DIRECTORY}/Welcome.txt")
	SET(CPACK_RESOURCE_FILE_WELCOME "${${PACKAGE_NAME}_FILES_DIRECTORY}/Welcome.txt")
ENDIF()

# Set the file name (without extension)
SET(CPACK_PACKAGE_FILE_NAME "${PACKAGE_NAME}-${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}${SRC_POSTFIX}")

# NSIS datas
SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${CMAKE_PROJECT_NAME}${SRC_POSTFIX}")
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${CMAKE_PROJECT_NAME}${SRC_POSTFIX}")
IF(${PACKAGE_NAME}_ENV_VARIABLE)
	SET(DQUOTE \\\" )
	SET(ANTISLASH "\\\\")
	set(CPACK_NSIS_EXTRA_INSTALL_COMMANDS "execWait 'cmd ${ANTISLASH}/c IF EXIST ${DQUOTE}%CD%${ANTISLASH}${${PACKAGE_NAME}_ENV_FOLDER}${DQUOTE} ( REG ADD ${DQUOTE}HKEY_CURRENT_USER${ANTISLASH}Environment${DQUOTE} /v ${${PACKAGE_NAME}_ENV_VARIABLE} /d ${DQUOTE}%CD:${ANTISLASH}=/%/${${PACKAGE_NAME}_ENV_FOLDER}${DQUOTE} /f ) '")
	set(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "execWait 'REG DELETE HKEY_CURRENT_USER${ANTISLASH}Environment /v ${${PACKAGE_NAME}_ENV_VARIABLE} /f'")
ENDIF(${PACKAGE_NAME}_ENV_VARIABLE)
IF(${${PACKAGE_NAME}_PACKAGE_MODIFY_PATH})
	SET(CPACK_NSIS_MODIFY_PATH true)
ENDIF()
ENDMACRO()

MACRO(ADD_COMPONENT compname)
	STRING(TOUPPER ${compname} ADDCOMP_UNAME)
	SET(PACKAGE_COMPONENTS_NAMES ${PACKAGE_COMPONENTS_NAMES} ${ADDCOMP_UNAME})
	PARSE_ARGUMENTS("CPACK_COMPONENT_${ADDCOMP_UNAME}" 
			"DISPLAY_NAME;COMPONENTS;DESCRIPTION;GROUP;DEPENDS;INSTALL_TYPES;ARCHIVE_FILE" 
			"HIDDEN;REQUIRED;DISABLED;DOWNLOADED" 
			${ARGN})
SET(CPACK_COMPONENTS_ALL ${CPACK_COMPONENTS_ALL} ${compname})
ENDMACRO()

MACRO(ADD_COMPONENT_GROUP grpname)
	STRING(TOUPPER ${grpname} ADDGRP_UNAME)
	SET(PACKAGE_GROUP_NAMES ${PACKAGE_GROUP_NAMES} ${ADDGRP_UNAME})
	PARSE_ARGUMENTS(CPACK_COMPONENT_GROUP_${ADDGRP_UNAME}
	"DISPLAY_NAME;DESCRIPTION"
	"EXPANDED;BOLD_TITLE"
	${ARGN})
ENDMACRO()

# Macro that adds an installation type to the CPack installer
MACRO(ADD_INSTALL_TYPE insttype)
  STRING(TOUPPER ${insttype} INSTTYPE_UNAME)
  SET(PACKAGE_INSTALL_NAMES ${PACKAGE_INSTALL_NAMES} ${INSTTYPE_UNAME})
  cpack_parse_arguments(CPACK_INSTALL_TYPE_${INSTTYPE_UNAME}
    "DISPLAY_NAME"
    ""
    ${ARGN})
ENDMACRO()

MACRO(END_PKG)
IF(CPACK_PACKAGE_NAME)
	PARSE_ARGUMENTS("${CPACK_PACKAGE_NAME}" 
					"" 
					"CLEANUP_CPACK_VARIABLES" 
					${ARGN})

	# Find the package real file name
	SET(PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.exe")
	IF(CPACK_GENERATOR MATCHES "DEB")
		SET(PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.deb")
	ENDIF(CPACK_GENERATOR MATCHES "DEB")
	IF(CPACK_GENERATOR MATCHES "NSIS")
		SET(PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.exe")
	ENDIF(CPACK_GENERATOR MATCHES "NSIS")
	IF(CPACK_GENERATOR MATCHES "RPM")
		SET(PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.rpm")
	ENDIF(CPACK_GENERATOR MATCHES "RPM")
	IF(CPACK_GENERATOR MATCHES "TBZ2")
		SET(PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.tar.bz")
	ENDIF(CPACK_GENERATOR MATCHES "TBZ2")
	IF(CPACK_GENERATOR MATCHES "TGZ")
		SET(PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.tar.gz")
	ENDIF(CPACK_GENERATOR MATCHES "TGZ")
	IF(CPACK_GENERATOR MATCHES "TZ")
		SET(PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.tz")
	ENDIF(CPACK_GENERATOR MATCHES "TZ")
	IF(CPACK_GENERATOR MATCHES "ZIP")
		SET(PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}.zip")
	ENDIF(CPACK_GENERATOR MATCHES "ZIP")

	#Create the cpack package file
	INCLUDE(CPack)

	# Create the target and dependancies
	IF (${CPACK_PACKAGE_NAME}_EXTERNAL_LIB)
		ADD_CUSTOM_COMMAND( OUTPUT "${PACKAGE_FILE_NAME}"
							COMMAND "cpack" "--config" "${CPACK_OUTPUT_CONFIG_FILE}" 
							DEPENDS "${${CPACK_PACKAGE_NAME}_EXTERNAL_LIB}/CMakeCache.txt" "${CMAKE_BINARY_DIR}/${CPACK_OUTPUT_CONFIG_FILE}" 
							WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
							VERBATIM)
		ADD_CUSTOM_COMMAND( OUTPUT "${${CPACK_PACKAGE_NAME}_EXTERNAL_LIB}/CMakeCache.txt"
							COMMAND "cmake" "-G" "${CMAKE_GENERATOR}" "." 
							DEPENDS "${${CPACK_PACKAGE_NAME}_EXTERNAL_LIB}/CMakeLists.txt"
							WORKING_DIRECTORY "${${CPACK_PACKAGE_NAME}_EXTERNAL_LIB}"
							VERBATIM)

	ELSE(${CPACK_PACKAGE_NAME}_EXTERNAL_LIB)
		ADD_CUSTOM_COMMAND( OUTPUT "${PACKAGE_FILE_NAME}"
							COMMAND "cpack" "--config" "${CPACK_OUTPUT_CONFIG_FILE}" 
							DEPENDS "${CMAKE_BINARY_DIR}/${CPACK_OUTPUT_CONFIG_FILE}"
							WORKING_DIRECTORY "${CMAKE_BINARY_DIR}"
							VERBATIM)
	ENDIF(${CPACK_PACKAGE_NAME}_EXTERNAL_LIB)

	IF (NOT A_PACKAGE_HAS_BEEN_CREATED)
		ADD_CUSTOM_TARGET("pkg" DEPENDS "ALL_PACKAGE_DONE" )
		ADD_CUSTOM_COMMAND(OUTPUT "ALL_PACKAGE_DONE" DEPENDS "${PACKAGE_FILE_NAME}")
		SET_SOURCE_FILES_PROPERTIES("ALL_PACKAGE_DONE" PROPERTIES SYMBOLIC true)
		SET(A_PACKAGE_HAS_BEEN_CREATED true)
	ELSE()
		ADD_CUSTOM_COMMAND(OUTPUT "ALL_PACKAGE_DONE" DEPENDS "${PACKAGE_FILE_NAME}" APPEND)
	ENDIF()


	SET(${CPACK_PACKAGE_NAME}_PACKAGE_MODIFY_PATH)
	SET(${CPACK_PACKAGE_NAME}_ENV_FOLDER)
	SET(${CPACK_PACKAGE_NAME}_ENV_VARIABLE)
	SET(${CPACK_PACKAGE_NAME}_COMPONENTS)
	SET(${CPACK_PACKAGE_NAME}_EXTERNAL_LIB)
	SET(${CPACK_PACKAGE_NAME}_DESCRIPTION)
	SET(${CPACK_PACKAGE_NAME}_PACKAGE_VERSION)
	FOREACH(PACKAGE_COMPONENTS_NAME ${PACKAGE_COMPONENTS_NAMES})
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_DISPLAY_NAME)
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_COMPONENTS)
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_DESCRIPTION)
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_GROUP)
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_DEPENDS)
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_INSTALL_TYPES)
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_ARCHIVE_FILE)
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_HIDDEN)
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_REQUIRED)
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_DISABLED)
		SET(CPACK_COMPONENT_${PACKAGE_COMPONENTS_NAME}_DOWNLOADED)
	ENDFOREACH()
	FOREACH(PACKAGE_GROUP_NAME ${PACKAGE_GROUP_NAMES})
		SET(CPACK_COMPONENT_${PACKAGE_GROUP_NAME}_DISPLAY_NAME)
		SET(CPACK_COMPONENT_${PACKAGE_GROUP_NAME}_DESCRIPTION)
		SET(CPACK_COMPONENT_${PACKAGE_GROUP_NAME}_EXPANDED)
		SET(CPACK_COMPONENT_${PACKAGE_GROUP_NAME}_BOLD_TITLE)
	ENDFOREACH()
	FOREACH(PACKAGE_INSTALL_NAME ${PACKAGE_INSTALL_NAMES})
		SET(CPACK_COMPONENT_${PACKAGE_INSTALL_NAME}_DISPLAY_NAME)
	ENDFOREACH()
	SET(PACKAGE_COMPONENTS_NAMES)
	SET(PACKAGE_GROUP_NAMES)
	SET(PACKAGE_INSTALL_NAMES)

	SET(CPACK_COMPONENTS_ALL)
	SET(CPACK_SET_DESTDIR)
	SET(CPACK_SOURCE_CYGWIN)
	SET(CPACK_SOURCE_GENERATOR)
	SET(CPACK_SOURCE_TBZ2)
	SET(CPACK_SOURCE_TGZ)
	SET(CPACK_SOURCE_TZ)
	SET(CPACK_SOURCE_ZIP)
	SET(CPACK_SYSTEM_NAME)
	SET(CPACK_TOPLEVEL_TAG)
	SET(CPACK_SOURCE_TOPLEVEL_TAG)
	SET(CPACK_SOURCE_INSTALLED_DIRECTORIES)
	SET(CPACK_IGNORE_FILES)
	SET(CPACK_INSTALLED_DIRECTORIES)
	SET(CPACK_GENERATOR)
	SET(CPACK_PACKAGE_VENDOR)
	SET(CPACK_NSIS_HELP_LINK)
	SET(CPACK_NSIS_URL_INFO_ABOUT)
	SET(CPACK_NSIS_CONTACT)
	SET(CPACK_PACKAGE_VERSION_MAJOR)
	SET(CPACK_PACKAGE_VERSION_MINOR)
	SET(CPACK_PACKAGE_VERSION_PATCH)
	SET(CPACK_PACKAGE_DESCRIPTION_FILE)
	SET(CPACK_PACKAGE_FILE_NAME)
	SET(CPACK_PACKAGE_INSTALL_DIRECTORY)
	SET(CPACK_PACKAGE_NAME)
	SET(CPACK_RESOURCE_FILE_LICENSE)
	SET(CPACK_RESOURCE_FILE_README)
	SET(CPACK_RESOURCE_FILE_WELCOME)
	SET(CPACK_SOURCE_OUTPUT_CONFIG_FILE)
	SET(CPACK_OUTPUT_CONFIG_FILE)
	SET(CPACK_SOURCE_IGNORE_FILES)
	SET(CPACK_PACKAGE_INSTALL_REGISTRY_KEY)
	SET(CPACK_NSIS_EXTRA_INSTALL_COMMANDS)
	SET(CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS)
	SET(CPACK_INSTALL_CMAKE_PROJECTS)
	SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY)
	SET(CPACK_PACKAGE_EXECUTABLES)
	SET(CPACK_NSIS_MUI_ICON)
	SET(CPACK_NSIS_MUI_UNIICON)
	SET(CPACK_PACKAGE_ICON)
	SET(CPACK_NSIS_MODIFY_PATH)
	SET(CPACK_NSIS_DISPLAY_NAME)
	SET(CPACK_NSIS_INSTALLED_ICON_NAME)
	SET(CPACK_NSIS_COMPRESSOR)
	SET(CPACK_NSIS_CREATE_ICONS_EXTRA)
	SET(CPACK_NSIS_DELETE_ICONS_EXTRA)	
ENDIF(CPACK_PACKAGE_NAME)
ENDMACRO(END_PKG)
