cmake_minimum_required(VERSION 2.8.7)
project(caveproductions)

#-------------------------------------------------------------------------------
# options
#-------------------------------------------------------------------------------

option(NETWORKING "Enable networking" ON)
option(UNITTESTS "Builds with unittests" ON)
option(TOOLS "Builds with tools" ON)
option(VERBOSE "Print debug information" OFF)
option(COVERAGE "Compile with test coverage" OFF)
option(USE_CCACHE "Use ccache" ON)
# The build system will search for system libs, if it can't find them (e.g. via pkg-config)
# it will take those that are bundled under src/libs. If you don't want that for some reason,
# you can set this to ON and the libs dir will not be taken into account at all.
option(FORCE_USE_SYSTEM_LIBS "Use system libs" OFF)
option(CAVEEXPRESS "Build caveexpress" ON)
option(CAVEPACKER "Build cavepacker" ON)
option(MINIRACER "Build miniracer" OFF)
option(SANITIZER "Build with sanitizer support if available" ON)

#-------------------------------------------------------------------------------
# end options
#-------------------------------------------------------------------------------

if (NOT CMAKE_BUILD_TYPE)
	set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Compile Type" FORCE)
endif()
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release MinSizeRel RelWithDebInfo)

if (${CMAKE_BUILD_TYPE} MATCHES "Debug")
	set(RELEASE False)
else()
	set(RELEASE True)
endif()

set(ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE STRING "Root dir")
message(STATUS "Place binaries in ${ROOT_DIR}")
# First for the generic no-config case (e.g. with mingw)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${ROOT_DIR})
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/lib)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/lib)

# Second, for multi-config builds (e.g. msvc)
foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES})
	string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG)
	set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${ROOT_DIR})
	set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/lib)
	set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/lib)
endforeach()
set(DEFAULT_LUAC_EXECUTABLE luac)
set(CP_CMAKE_DIR ${PROJECT_SOURCE_DIR}/cmake)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CP_CMAKE_DIR})
set(CMAKE_VERBOSE_MAKEFILE ${VERBOSE})
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

if (${CMAKE_EXTRA_GENERATOR} MATCHES "Eclipse CDT4")
	message(STATUS "Generate eclipse projects")
	set(CMAKE_ECLIPSE_GENERATE_LINKED_RESOURCES OFF)
	set(CMAKE_ECLIPSE_GENERATE_SOURCE_PROJECT ON)
	set(CMAKE_ECLIPSE_VERSION "4.3" CACHE STRING "Eclipse version")
	set(CMAKE_CXX_COMPILER_ARG1 "-std=c++11" CACHE STRING "C++ version for Eclipse")
endif()

include(${CP_CMAKE_DIR}/macros.cmake)

if (COVERAGE)
	if ((CP_GCC OR CP_CLANG) AND NOT RELEASE)
		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
		set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g -O0 -fprofile-arcs -ftest-coverage")
	elseif (RELEASE)
		message(WARNING "Skip coverage, you attempt to compile in release mode")
	else()
		message(WARNING "Skip coverage, you don't compile with gcc or clang")
	endif()
endif()

cp_message("ROOT_DIR: ${ROOT_DIR}")
cp_message("CMAKE_MODULE_PATH: ${CMAKE_MODULE_PATH}")
cp_message("PROJECT_SOURCE_DIR: ${PROJECT_SOURCE_DIR}")
message(STATUS "CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}")
message(STATUS "CMAKE_HOST_SYSTEM_NAME: ${CMAKE_HOST_SYSTEM_NAME}")

#-------------------------------------------------------------------------------
# variables
#-------------------------------------------------------------------------------

if (${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
	set(WINDOWS 1)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Android")
	set(LINUX 1)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
	set(DARWIN 1)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
	set(LINUX 1)
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Emscripten")
	set(EMSCRIPTEN 1)
else()
	message(WARNING "Unknown host system: ${CMAKE_SYSTEM_NAME}. Default to linux")
	set(LINUX 1)
endif()

include(${CP_CMAKE_DIR}/pack.cmake)
include(CPack)

# on mac it e.g. finds the gui launcher - this is not what we want - find a proper way to handle this
if (NOT ${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Darwin")
	find_host_program(TEXTUREPACKER_BIN NAMES TexturePacker)
	if (TEXTUREPACKER_BIN)
		execute_process(COMMAND ${TEXTUREPACKER_BIN} --format CaveExpress ERROR_VARIABLE TEXTURE_PACKER_EXPORTER)
		if (TEXTURE_PACKER_EXPORTER MATCHES "Unknown format")
			message(STATUS "Found TexturePacker: ${TEXTUREPACKER_BIN}")
			message(WARNING "but without the needed exporter. Find it in contrib/assets/png-packed/exporter. Check out the HOWTO.md in that directory.")
			unset(TEXTUREPACKER_BIN)
		else()
			message(STATUS "Found TexturePacker: ${TEXTUREPACKER_BIN}")
		endif()
	else()
		message(STATUS "Could not find TexturePacker")
	endif()
endif()
if (NOT CMAKE_TOOLCHAIN_FILE)
	if (WINDOWS)
		include(${CP_CMAKE_DIR}/toolchains/windows-toolchain.cmake)
	elseif (DARWIN)
		include(${CP_CMAKE_DIR}/toolchains/darwin-toolchain.cmake)
	else()
		include(${CP_CMAKE_DIR}/toolchains/linux-toolchain.cmake)
	endif()
endif()

if (ANDROID)
	include(${CP_CMAKE_DIR}/android.cmake)
elseif (IOS)
	include(${CP_CMAKE_DIR}/ios.cmake)
elseif (DARWIN)
	include(${CP_CMAKE_DIR}/darwin.cmake)
elseif (WINDOWS)
#	include(${CP_CMAKE_DIR}/windows.cmake)
elseif (NACL)
	include(${CP_CMAKE_DIR}/nacl.cmake)
elseif (EMSCRIPTEN)
	include(${CP_CMAKE_DIR}/emscripten.cmake)
endif()

if (PKGDATADIR)
	add_definitions(-DPKGDATADIR="${PKGDATADIR}")
	message(STATUS "You specified a package data dir - the game will append the game name to this directory.")
	message(STATUS "So you get e.g. ${PKGDATADIR}/caveexpress as final directory.")
endif()

if (NOT NETWORKING)
	add_definitions(-DNONETWORK=1)
endif()

if (NOT CMAKE_BUILD_TYPE)
	if (RELEASE)
		set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Compile Type" FORCE)
	else()
		set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Compile Type" FORCE)
	endif()
	set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release)
endif()

find_host_program(CCACHE "ccache")
if (CCACHE)
	if (USE_CCACHE)
		message(STATUS "Using ccache")
		set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE})
		set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
	endif()
else()
	message(STATUS "ccache not found")
endif()

configure_file(${ROOT_DIR}/src/config.h.in ${CMAKE_BINARY_DIR}/cp-config.h)
include_directories(${CMAKE_BINARY_DIR})

include_directories(src)
include_directories(src/modules)
# Packagers might want to remove this
if (EXISTS "${ROOT_DIR}/src/libs/" AND NOT FORCE_USE_SYSTEM_LIBS)
	if (UNITTESTS)
		include_directories(src/libs/gtest)
		include_directories(src/libs/gtest/include)
	endif()

	add_subdirectory(src/libs)
else()
	include(FindPkgConfig)
	PKG_SEARCH_MODULE(SDL2 REQUIRED sdl2<=2.0.3)
	PKG_SEARCH_MODULE(SDL2IMAGE REQUIRED SDL2_image>=2.0.0)
	PKG_SEARCH_MODULE(LUA5.2 REQUIRED lua5.2)
	PKG_SEARCH_MODULE(BOX2D REQUIRED box2d>=2.3.0)
	PKG_SEARCH_MODULE(SQLITE3 REQUIRED sqlite3)
	include_directories(${SDL2_INCLUDE_DIRS} ${SDL2IMAGE_INCLUDE_DIRS})
endif()

# TODO move into lib cmakefiles
if (LUA5.2_FOUND)
	add_definitions(-DHAVE_LUA_H)
endif()
if (UNITTESTS)
	enable_testing()
endif()
add_subdirectory(src/modules)
if (CAVEPACKER)
	add_subdirectory(src/cavepacker)
endif()
if (CAVEEXPRESS)
	add_subdirectory(src/caveexpress)
endif()
if (MINIRACER)
	add_subdirectory(src/miniracer)
endif()
if (UNITTESTS)
	add_subdirectory(src/tests)
endif()
