# CMakeLists.txt for ALURE
CMAKE_MINIMUM_REQUIRED(VERSION 2.4)

IF(COMMAND CMAKE_POLICY)
    CMAKE_POLICY(SET CMP0003 NEW)
ENDIF(COMMAND CMAKE_POLICY)


INCLUDE(CheckCCompilerFlag)
INCLUDE(CheckFunctionExists)
INCLUDE(CheckIncludeFile)
INCLUDE(CheckIncludeFiles)
INCLUDE(CheckLibraryExists)
INCLUDE(FindPkgConfig)
INCLUDE(UsePkgConfig)

PROJECT(ALURE)

IF(WIN32)
    SET(LIBNAME ALURE32)
ELSE(WIN32)
    SET(LIBNAME alure)
ENDIF(WIN32)

SET(LIB_MAJOR_VERSION "1")
SET(LIB_MINOR_VERSION "0")
SET(LIB_BUILD_VERSION "72")
SET(LIB_VERSION "${LIB_MAJOR_VERSION}.${LIB_MINOR_VERSION}.${LIB_BUILD_VERSION}")
IF(NOT DEFINED LIB_INSTALL_DIR)
    SET(LIB_INSTALL_DIR "lib")
ENDIF(NOT DEFINED LIB_INSTALL_DIR)


INCLUDE_DIRECTORIES(include "${ALURE_BINARY_DIR}")


OPTION(NO_SHARED "Build a static library instead of shared" OFF)

IF(NOT CMAKE_BUILD_TYPE)
    SET(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
        "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel."
        FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)
IF(NOT DEFINED CMAKE_DEBUG_POSTFIX)
    SET(CMAKE_DEBUG_POSTFIX "" CACHE STRING
        "Library postfix for debug builds. Normally left blank."
        FORCE)
ENDIF(NOT DEFINED CMAKE_DEBUG_POSTFIX)


ADD_DEFINITIONS(-DALURE_BUILD_LIBRARY -DHAVE_CONFIG_H)

IF(MSVC)
    # ???
ELSE(MSVC)
    IF(NOT WIN32)
        CHECK_C_COMPILER_FLAG(-fvisibility=hidden HAVE_GCC_VISIBILITY)
        IF(HAVE_GCC_VISIBILITY)
            ADD_DEFINITIONS(-fvisibility=hidden)
        ENDIF(HAVE_GCC_VISIBILITY)
    ENDIF(NOT WIN32)

    CHECK_C_COMPILER_FLAG(-Wextra HAVE_WEXTRA)
    IF(HAVE_WEXTRA)
        ADD_DEFINITIONS(-Wextra)
    ENDIF(HAVE_WEXTRA)
    ADD_DEFINITIONS(-Wall)
ENDIF(MSVC)


OPTION(DYNLOAD "Enable dynamic run-time loading of libraries" ON)

CHECK_INCLUDE_FILE(windows.h HAVE_WINDOWS_H -D_WIN32_WINNT=0x0500)
IF(NOT HAVE_WINDOWS_H)
    CHECK_FUNCTION_EXISTS(nanosleep HAVE_NANOSLEEP)
    IF(NOT HAVE_NANOSLEEP)
        MESSAGE(FATAL_ERROR "No sleep function found!")
    ENDIF(NOT HAVE_NANOSLEEP)

    IF(DYNLOAD)
        CHECK_INCLUDE_FILE(dlfcn.h HAVE_DLFCN_H)
        IF(HAVE_DLFCN_H)
            CHECK_LIBRARY_EXISTS(dl dlopen "" HAVE_LIBDL)
            IF(HAVE_LIBDL)
                SET(HAS_DLOPEN 1)
                SET(EXTRA_LIBS dl ${EXTRA_LIBS})
            ENDIF(HAVE_LIBDL)
        ENDIF(HAVE_DLFCN_H)
    ENDIF(DYNLOAD)
ELSE(NOT HAVE_WINDOWS_H)
    IF(DYNLOAD)
        SET(HAS_LOADLIBRARY 1)
    ENDIF(DYNLOAD)
ENDIF(NOT HAVE_WINDOWS_H)


OPTION(SNDFILE "SoundFile support (for various formats)" ON)
OPTION(VORBIS  "VorbisFile support (for Ogg Vorbis)"  ON)
OPTION(FLAC    "FLAC support (for FLAC and Ogg FLAC)" ON)

IF(WIN32)
    ADD_DEFINITIONS(-D_WIN32)

    IF(CMAKE_SIZEOF_VOID_P MATCHES "8")
        SET(WIN_TYPE Win64)
        SET(XBITS x64)
    ELSE(CMAKE_SIZEOF_VOID_P MATCHES "8")
        SET(WIN_TYPE Win32)
        SET(XBITS x86)
    ENDIF(CMAKE_SIZEOF_VOID_P MATCHES "8")

    SET(OPENAL_SEARCH_PATHS
        ENV ALSDK_DIR
        ENV MINGDIR
        "C:/Program Files/OpenAL 1.1 SDK"
        "C:/Program Files (x86)/OpenAL 1.1 SDK"
        "E:/Programs/Dev/OpenAL"
        "E:/Program Files (x86)/OpenAL 1.1 SDK" )

    FIND_PATH(OPENAL_INCLUDE_DIR al.h
              PATHS ${OPENAL_SEARCH_PATHS}
              PATH_SUFFIXES include include/AL )
    IF(OPENAL_INCLUDE_DIR)
        INCLUDE_DIRECTORIES(${OPENAL_INCLUDE_DIR})
        FIND_LIBRARY(OPENAL_LIBRARIES OpenAL32
                     PATHS ${OPENAL_SEARCH_PATHS}
                     PATH_SUFFIXES lib libs/${WIN_TYPE} )
    ENDIF(OPENAL_INCLUDE_DIR)

    IF(NOT OPENAL_LIBRARIES)
        MESSAGE(FATAL_ERROR "OpenAL not found!\nPlease try setting the ALSDK_DIR environment variable and try again.")
    ENDIF(NOT OPENAL_LIBRARIES)

    MESSAGE(STATUS "OpenAL include: ${OPENAL_INCLUDE_DIR}")
    MESSAGE(STATUS "OpenAL lib: ${OPENAL_LIBRARIES}")
ELSE(WIN32)
    PKG_CHECK_MODULES(OPENAL openal)
    IF(NOT OPENAL_FOUND)
        IF(APPLE)
            CHECK_INCLUDE_FILE(OpenAL/al.h HAVE_OPENAL_AL_H)
            IF(HAVE_OPENAL_AL_H)
                SET(OPENAL_LIBRARIES "-framework OpenAL")
                SET(HAS_OPENAL 1)
            ENDIF(HAVE_OPENAL_AL_H)
        ELSE(APPLE)
            CHECK_INCLUDE_FILE(AL/al.h HAVE_AL_AL_H)
            IF(HAVE_AL_AL_H)
                CHECK_LIBRARY_EXISTS(openal alcOpenDevice "" HAS_OPENAL)
                IF(HAS_OPENAL)
                    SET(OPENAL_LIBRARIES openal)
                ENDIF(HAS_OPENAL)
            ENDIF(HAVE_AL_AL_H)
        ENDIF(APPLE)
        IF(NOT HAS_OPENAL)
            MESSAGE(FATAL_ERROR "OpenAL not found!")
        ENDIF(NOT HAS_OPENAL)
    ELSE(NOT OPENAL_FOUND)
        INCLUDE_DIRECTORIES(${OPENAL_INCLUDE_DIRS})
        LINK_DIRECTORIES(${OPENAL_LIBRARY_DIRS})
    ENDIF(NOT OPENAL_FOUND)
ENDIF(WIN32)

# SndFile support
IF(SNDFILE)
    PKG_CHECK_MODULES(SNDFILE sndfile)
    IF(NOT SNDFILE_FOUND)
        CHECK_INCLUDE_FILE(sndfile.h HAVE_SNDFILE_H)
        IF(HAVE_SNDFILE_H)
            # Libraries will be loaded dynamicly at runtime if possible; don't
            # link them here
            IF(HAS_DLOPEN OR HAS_LOADLIBRARY)
                SET(HAS_SNDFILE 1)
            ELSE(HAS_DLOPEN OR HAS_LOADLIBRARY)
                CHECK_LIBRARY_EXISTS(sndfile sf_open "" HAS_SNDFILE)
                IF(HAS_SNDFILE)
                    SET(SNDFILE_LIBRARIES "sndfile")
                ENDIF(HAS_SNDFILE)
            ENDIF(HAS_DLOPEN OR HAS_LOADLIBRARY)
        ENDIF(HAVE_SNDFILE_H)
    ELSE(NOT SNDFILE_FOUND)
        SET(HAS_SNDFILE 1)
        INCLUDE_DIRECTORIES(${SNDFILE_INCLUDE_DIRS})
        IF(HAS_DLOPEN OR HAS_LOADLIBRARY)
            SET(SNDFILE_LIBRARIES "")
        ELSE(HAS_DLOPEN OR HAS_LOADLIBRARY)
            LINK_DIRECTORIES(${SNDFILE_LIBRARY_DIRS})
        ENDIF(HAS_DLOPEN OR HAS_LOADLIBRARY)
    ENDIF(NOT SNDFILE_FOUND)
ELSE(SNDFILE)
    SET(SNDFILE_LIBRARIES "")
ENDIF(SNDFILE)

# Vorbis support
IF(VORBIS)
    PKG_CHECK_MODULES(VORBISFILE vorbisfile)
    IF(NOT VORBISFILE_FOUND)
        CHECK_INCLUDE_FILE(vorbis/vorbisfile.h HAVE_VORBIS_VORBISFILE_H)
        IF(HAVE_VORBIS_VORBISFILE_H)
            IF(HAS_DLOPEN OR HAS_LOADLIBRARY)
                SET(HAS_VORBISFILE 1)
            ELSE(HAS_DLOPEN OR HAS_LOADLIBRARY)
                CHECK_LIBRARY_EXISTS(vorbisfile ov_open "" HAS_VORBISFILE)
                IF(HAS_VORBISFILE)
                    SET(VORBISFILE_LIBRARIES "vorbisfile")
                ENDIF(HAS_VORBISFILE)
            ENDIF(HAS_DLOPEN OR HAS_LOADLIBRARY)
        ENDIF(HAVE_VORBIS_VORBISFILE_H)
    ELSE(NOT VORBISFILE_FOUND)
        SET(HAS_VORBISFILE 1)
        INCLUDE_DIRECTORIES(${VORBISFILE_INCLUDE_DIRS})
        IF(HAS_DLOPEN OR HAS_LOADLIBRARY)
            SET(VORBISFILE_LIBRARIES "")
        ELSE(HAS_DLOPEN OR HAS_LOADLIBRARY)
            LINK_DIRECTORIES(${VORBISFILE_LIBRARY_DIRS})
        ENDIF(HAS_DLOPEN OR HAS_LOADLIBRARY)
    ENDIF(NOT VORBISFILE_FOUND)
ELSE(VORBIS)
    SET(VORBISFILE_LIBRARIES "")
ENDIF(VORBIS)

# FLAC support
IF(FLAC)
    PKG_CHECK_MODULES(LIBFLAC flac)
    IF(NOT LIBFLAC_FOUND)
        CHECK_INCLUDE_FILE(FLAC/all.h HAVE_FLAC_ALL_H)
        IF(HAVE_FLAC_ALL_H)
            IF(HAS_DLOPEN OR HAS_LOADLIBRARY)
                SET(HAS_FLAC 1)
            ELSE(HAS_DLOPEN OR HAS_LOADLIBRARY)
                CHECK_LIBRARY_EXISTS(FLAC FLAC__stream_decoder_new "" HAS_FLAC)
                IF(HAS_FLAC)
                    SET(LIBFLAC_LIBRARIES "FLAC")
                ENDIF(HAS_FLAC)
            ENDIF(HAS_DLOPEN OR HAS_LOADLIBRARY)
        ENDIF(HAVE_FLAC_ALL_H)
    ELSE(NOT LIBFLAC)
        SET(HAS_FLAC 1)
        INCLUDE_DIRECTORIES(${LIBFLAC_INCLUDE_DIRS})
        IF(HAS_DLOPEN OR HAS_LOADLIBRARY)
            SET(LIBFLAC_LIBRARIES "")
        ELSE(HAS_DLOPEN OR HAS_LOADLIBRARY)
            LINK_DIRECTORIES(${LIBFLAC_LIBRARY_DIRS})
        ENDIF(HAS_DLOPEN OR HAS_LOADLIBRARY)
    ENDIF(NOT LIBFLAC_FOUND)
ELSE(FLAC)
    SET(LIBFLAC_LIBRARIES "")
ENDIF(FLAC)


# For alure.pc.in
SET(prefix ${CMAKE_INSTALL_PREFIX})
SET(exec_prefix "\${prefix}")
SET(libdir "\${exec_prefix}/${LIB_INSTALL_DIR}")
SET(bindir "\${exec_prefix}/bin")
SET(includedir "\${prefix}/include")
SET(PKG_CONFIG_REQUIRES openal)
SET(PACKAGE_VERSION "${LIB_VERSION}")

# End configuration
CONFIGURE_FILE(
    "${ALURE_SOURCE_DIR}/config.h.in"
    "${ALURE_BINARY_DIR}/config.h")
CONFIGURE_FILE(
    "${ALURE_SOURCE_DIR}/alure.pc.in"
    "${ALURE_BINARY_DIR}/alure.pc"
    @ONLY)


SET(ALURE_OBJS  src/alure.cpp
                src/buffer.cpp
                src/stream.cpp
)

IF(NOT NO_SHARED)
    #build a shared library
    ADD_LIBRARY(${LIBNAME} SHARED ${ALURE_OBJS})
    SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES VERSION ${LIB_VERSION}
                                                SOVERSION ${LIB_MAJOR_VERSION})
    IF(WIN32)
        SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES PREFIX "")
    ENDIF(WIN32)
    TARGET_LINK_LIBRARIES(${LIBNAME} ${OPENAL_LIBRARIES} ${SNDFILE_LIBRARIES} ${VORBISFILE_LIBRARIES} ${LIBFLAC_LIBRARIES} ${EXTRA_LIBS})
ELSE(NOT NO_SHARED)
    #build a static library
    ADD_LIBRARY(${LIBNAME} STATIC ${ALURE_OBJS})
    SET_TARGET_PROPERTIES(${LIBNAME} PROPERTIES VERSION ${LIB_VERSION})
ENDIF(NOT NO_SHARED)


ADD_EXECUTABLE(alureplay examples/alureplay.c)
TARGET_LINK_LIBRARIES(alureplay ${LIBNAME} ${OPENAL_LIBRARIES} ${SNDFILE_LIBRARIES} ${VORBISFILE_LIBRARIES} ${LIBFLAC_LIBRARIES} ${EXTRA_LIBS} stdc++)

ADD_EXECUTABLE(alurestream examples/alurestream.c)
TARGET_LINK_LIBRARIES(alurestream ${LIBNAME} ${OPENAL_LIBRARIES} ${SNDFILE_LIBRARIES} ${VORBISFILE_LIBRARIES} ${LIBFLAC_LIBRARIES} ${EXTRA_LIBS} stdc++)


FIND_PROGRAM(NATDOCS_BIN NaturalDocs)
IF(NATDOCS_BIN)
    ADD_CUSTOM_TARGET(docs
                      "${NATDOCS_BIN}" -i "${ALURE_SOURCE_DIR}/src" -o HTML "${ALURE_SOURCE_DIR}/docs/html" -p "${ALURE_SOURCE_DIR}/docs/naturaldocs" -s Default CustomStyle
                      COMMENT "Building NaturalDocs documentation..." VERBATIM)
ELSE(NATDOCS_BIN)
    MESSAGE(STATUS "\nNaturalDocs not found; building documentation is disabled")
ENDIF(NATDOCS_BIN)


#add an install target here
IF(APPLE)
    SET(INCPATH OpenAL)
ELSE(APPLE)
    SET(INCPATH AL)
ENDIF(APPLE)

INSTALL(DIRECTORY "${ALURE_SOURCE_DIR}/docs/html"
        DESTINATION share/doc/alure
)
INSTALL(TARGETS ${LIBNAME}
        RUNTIME DESTINATION bin
        LIBRARY DESTINATION ${LIB_INSTALL_DIR}
        ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
)
INSTALL(FILES include/AL/alure.h
        DESTINATION "include/${INCPATH}"
)
INSTALL(FILES "${ALURE_BINARY_DIR}/alure.pc"
        DESTINATION lib/pkgconfig
)


MESSAGE(STATUS "\n********************** Configured options **********************")
IF(NO_SHARED)
    MESSAGE(STATUS "Building static library")
ELSE(NO_SHARED)
    MESSAGE(STATUS "Building shared library")
ENDIF(NO_SHARED)
MESSAGE(STATUS "")
IF(HAS_DLOPEN OR HAS_LOADLIBRARY)
    MESSAGE(STATUS "Dynamic loading of support libs: enabled")
ELSE(HAS_DLOPEN OR HAS_LOADLIBRARY)
    MESSAGE(STATUS "Dynamic loading of support libs: disabled")
ENDIF(HAS_DLOPEN OR HAS_LOADLIBRARY)
MESSAGE(STATUS "")
IF(HAS_SNDFILE)
    MESSAGE(STATUS "SndFile support: enabled")
ELSE(HAS_SNDFILE)
    MESSAGE(STATUS "SndFile support: disabled")
ENDIF(HAS_SNDFILE)
IF(HAS_VORBISFILE)
    MESSAGE(STATUS "VorbisFile support: enabled")
ELSE(HAS_VORBISFILE)
    MESSAGE(STATUS "VorbisFile support: disabled")
ENDIF(HAS_VORBISFILE)
IF(HAS_FLAC)
    MESSAGE(STATUS "FLAC support: enabled")
ELSE(HAS_FLAC)
    MESSAGE(STATUS "FLAC support: disabled")
ENDIF(HAS_FLAC)
MESSAGE(STATUS "")
