include_directories(
  ${PROJECT_SOURCE_DIR}/runtime/src
  ${PROJECT_SOURCE_DIR}/runtime/src/atn
  ${PROJECT_SOURCE_DIR}/runtime/src/dfa
  ${PROJECT_SOURCE_DIR}/runtime/src/misc
  ${PROJECT_SOURCE_DIR}/runtime/src/support
  ${PROJECT_SOURCE_DIR}/runtime/src/tree
  ${PROJECT_SOURCE_DIR}/runtime/src/tree/pattern
  ${PROJECT_SOURCE_DIR}/runtime/src/tree/xpath
)


file(GLOB libantlrcpp_SRC
  "${PROJECT_SOURCE_DIR}/runtime/src/*.cpp"
  "${PROJECT_SOURCE_DIR}/runtime/src/atn/*.cpp"
  "${PROJECT_SOURCE_DIR}/runtime/src/dfa/*.cpp"
  "${PROJECT_SOURCE_DIR}/runtime/src/misc/*.cpp"
  "${PROJECT_SOURCE_DIR}/runtime/src/support/*.cpp"
  "${PROJECT_SOURCE_DIR}/runtime/src/tree/*.cpp"
  "${PROJECT_SOURCE_DIR}/runtime/src/tree/pattern/*.cpp"
  "${PROJECT_SOURCE_DIR}/runtime/src/tree/xpath/*.cpp"
)
add_definitions(-DANTLR4CPP_STATIC)
set(ANTLR4_WITH_STATIC_CRT OFF)
add_library(antlr4_shared SHARED ${libantlrcpp_SRC})
add_library(antlr4_static STATIC ${libantlrcpp_SRC})
set(LIB_OUTPUT_DIR ${CMAKE_BINARY_DIR}/lib) # put generated libraries here.
message(STATUS "Output libraries to ${LIB_OUTPUT_DIR}")

# make sure 'make' works fine even if ${LIB_OUTPUT_DIR} is deleted.
add_custom_target(make_lib_output_dir ALL
    COMMAND ${CMAKE_COMMAND} -E make_directory ${LIB_OUTPUT_DIR}
    )

add_dependencies(antlr4_shared make_lib_output_dir)
add_dependencies(antlr4_static make_lib_output_dir)

find_package(utf8cpp QUIET)

set(INSTALL_utf8cpp FALSE)

if (utf8cpp_FOUND)
  target_link_libraries(antlr4_shared utf8cpp)
  target_link_libraries(antlr4_static utf8cpp)
else()

  # older utf8cpp doesn't define the package above
  find_path(utf8cpp_HEADER utf8.h
    PATH_SUFFIXES utf8cpp
    )

  if (utf8cpp_HEADER)
    include_directories(${utf8cpp_HEADER})
  else()
    include(${CMAKE_ROOT}/Modules/ExternalProject.cmake)
    set(THIRDPARTY_DIR ${CMAKE_BINARY_DIR}/runtime/thirdparty)
    set(UTFCPP_DIR ${THIRDPARTY_DIR}/utfcpp)
    ExternalProject_Add(
      utf8cpp
      GIT_REPOSITORY        "https://github.com/nemtrif/utfcpp"
      GIT_TAG               "v3.1.1"
      SOURCE_DIR            ${UTFCPP_DIR}
      UPDATE_DISCONNECTED   1
      CMAKE_ARGS            -DCMAKE_INSTALL_PREFIX=${UTFCPP_DIR}/install -DUTF8_TESTS=off -DUTF8_SAMPLES=off
      STEP_TARGETS          build
      )    

    include_directories(
      ${UTFCPP_DIR}/install/include/utf8cpp
      ${UTFCPP_DIR}/install/include/utf8cpp/utf8
      )

    add_dependencies(antlr4_shared utf8cpp)
    add_dependencies(antlr4_static utf8cpp)
    set(INSTALL_utf8cpp TRUE)
  endif()
endif()

if(CMAKE_SYSTEM_NAME MATCHES "Linux")
  target_link_libraries(antlr4_shared ${UUID_LIBRARIES})
  target_link_libraries(antlr4_static ${UUID_LIBRARIES})
elseif(APPLE)
  target_link_libraries(antlr4_shared ${COREFOUNDATION_LIBRARY})
  target_link_libraries(antlr4_static ${COREFOUNDATION_LIBRARY})
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
  set(disabled_compile_warnings "/wd4251")
else()
  set(disabled_compile_warnings "-Wno-overloaded-virtual")
endif()


if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
  set(disabled_compile_warnings "${disabled_compile_warnings} -Wno-dollar-in-identifier-extension -Wno-four-char-constants")
elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU" OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Intel")
  set(disabled_compile_warnings "${disabled_compile_warnings} -Wno-multichar")
endif()

set(extra_share_compile_flags "")
set(extra_static_compile_flags "")
if(WIN32)
  set(extra_share_compile_flags "-DANTLR4CPP_EXPORTS")
  set(extra_static_compile_flags "-DANTLR4CPP_STATIC")
endif(WIN32)
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
  if(WITH_STATIC_CRT)
    target_compile_options(antlr4_shared PRIVATE "/MT$<$<CONFIG:Debug>:d>")
    target_compile_options(antlr4_static PRIVATE "/MT$<$<CONFIG:Debug>:d>")
  else()
    target_compile_options(antlr4_shared PRIVATE "/MD$<$<CONFIG:Debug>:d>")
    target_compile_options(antlr4_static PRIVATE "/MD$<$<CONFIG:Debug>:d>")
  endif()
endif()

set(static_lib_suffix "")
if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
  set(static_lib_suffix "-static")
endif()

if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
  set(extra_share_compile_flags "-DANTLR4CPP_EXPORTS -MP /wd4251")
  set(extra_static_compile_flags "-DANTLR4CPP_STATIC -MP")
endif()

set_target_properties(antlr4_shared
                      PROPERTIES VERSION   ${ANTLR_VERSION}
                                 SOVERSION ${ANTLR_VERSION}
                                 OUTPUT_NAME antlr4-runtime
                                 LIBRARY_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
                                 # TODO: test in windows. DLL is treated as runtime.
                                 # see https://cmake.org/cmake/help/v3.0/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.html
                                 RUNTIME_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
                                 ARCHIVE_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
                                 COMPILE_FLAGS "${disabled_compile_warnings} ${extra_share_compile_flags}")

set_target_properties(antlr4_static
                      PROPERTIES VERSION   ${ANTLR_VERSION}
                                 SOVERSION ${ANTLR_VERSION}
                                 OUTPUT_NAME "antlr4-runtime${static_lib_suffix}"
                                 ARCHIVE_OUTPUT_DIRECTORY ${LIB_OUTPUT_DIR}
                                 COMPILE_FLAGS "${disabled_compile_warnings} ${extra_static_compile_flags}")

install(TARGETS antlr4_shared
        DESTINATION lib
        EXPORT antlr4-targets)
install(TARGETS antlr4_static
        DESTINATION lib
        EXPORT antlr4-targets)

install(DIRECTORY "${PROJECT_SOURCE_DIR}/runtime/src/"
        DESTINATION "include/antlr4-runtime"
        COMPONENT dev
        FILES_MATCHING PATTERN "*.h"
        )

if (INSTALL_utf8cpp)
  install(FILES "${UTFCPP_DIR}/source/utf8.h"
	  DESTINATION "include/antlr4-runtime")
  install(DIRECTORY "${UTFCPP_DIR}/source/utf8"
	  DESTINATION "include/antlr4-runtime"
	  COMPONENT dev
	  FILES_MATCHING PATTERN "*.h"
	  )
endif()