# - Find INTEL IPP library
#
# This module finds the Intel IPP libraries.
# It uses the emerged static libraries.
# You should call ippStaticInit before calling ipp functions.
#
# This module sets the following variables:
#  IPP_FOUND
#  IPP_INCLUDE_DIR
#  IPP_IOMP5_LIBRARIES
#  IPP_CORE_LIBRARIES
#  IPP_AC_LIBRARIES
#  IPP_CC_LIBRARIES
#  IPP_CP_LIBRARIES
#  IPP_CV_LIBRARIES
#  IPP_DC_LIBRARIES
#  IPP_DI_LIBRARIES
#  IPP_GEN_LIBRARIES
#  IPP_I_LIBRARIES
#  IPP_J_LIBRARIES
#  IPP_M_LIBRARIES
#  IPP_R_LIBRARIES
#  IPP_S_LIBRARIES
#  IPP_SC_LIBRARIES
#  IPP_SR_LIBRARIES
#  IPP_CH_LIBRARIES
#  IPP_VC_LIBRARIES
#  IPP_VM_LIBRARIES


# Do nothing if IPP_FOUND was set before!
IF (NOT IPP_FOUND)

SET(IPP_INCLUDE_DIR)
SET(IPP_CORE_LIBRARIES)
SET(IPP_IOMP5_LIBRARIES)
SET(IPP_AC_LIBRARIES)
SET(IPP_CC_LIBRARIES)
SET(IPP_CP_LIBRARIES)
SET(IPP_CV_LIBRARIES)
SET(IPP_DC_LIBRARIES)
SET(IPP_DI_LIBRARIES)
SET(IPP_GEN_LIBRARIES)
SET(IPP_I_LIBRARIES)
SET(IPP_J_LIBRARIES)
SET(IPP_M_LIBRARIES)
SET(IPP_R_LIBRARIES)
SET(IPP_S_LIBRARIES)
SET(IPP_SC_LIBRARIES)
SET(IPP_SR_LIBRARIES)
SET(IPP_CH_LIBRARIES)
SET(IPP_VC_LIBRARIES)
SET(IPP_VM_LIBRARIES)

# Prints diagnostics
# SET(_verbose TRUE)

# Intel Compiler Suite
SET(INTEL_COMPILER_DIR CACHE STRING
  "Root directory of the Intel Compiler Suite")
SET(INTEL_IPP_DIR CACHE STRING
  "Root directory of the IPP Library (standalone)")

# Checks
CHECK_TYPE_SIZE("void*" SIZE_OF_VOIDP)
IF ("${SIZE_OF_VOIDP}" EQUAL 8)
  SET(iccvers "intel64")
  SET(ipp64 "em64t")
  SET(ippvers "em64t")
  SET(ipplibs "emerged${ipp64}" "merged${ipp64}_t")
ELSE ("${SIZE_OF_VOIDP}" EQUAL 8)
  SET(iccvers "ia32")
  SET(ipp64 "")
  SET(ippvers "ia32")
  SET(ipplibs "emerged" "merged_t")
ENDIF ("${SIZE_OF_VOIDP}" EQUAL 8)

# Paths
SET(saved_CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH})
SET(saved_CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH})
IF (INTEL_COMPILER_DIR)
  # TODO: diagnostic if dir does not exist
  SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
    "${INTEL_COMPILER_DIR}/lib/${iccvers}")
  IF (NOT INTEL_IPP_DIR)
    SET(INTEL_IPP_DIR "${INTEL_COMPILER_DIR}/ipp")
  ENDIF (NOT INTEL_IPP_DIR)
ENDIF (INTEL_COMPILER_DIR)
IF (INTEL_IPP_DIR)
  # TODO: diagnostic if dir does not exist
  SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH}
    "${INTEL_IPP_DIR}/${ippvers}/include")
  SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH}
    "${INTEL_IPP_DIR}/${ippvers}/lib")
ENDIF (INTEL_IPP_DIR)

# Include files
FIND_PATH(IPP_INCLUDE_DIR ipps.h)
MARK_AS_ADVANCED(IPP_INCLUDE_DIR)

# Start searching
IF (NOT IPP_IOMP5_LIBRARIES)
  FIND_LIBRARY(IPP_IOMP5_LIBRARIES "iomp5") 
  MARK_AS_ADVANCED(IPP_IOMP5_LIBRARIES)
ENDIF (NOT IPP_IOMP5_LIBRARIES)

IF (NOT IPP_CORE_LIBRARIES)
  FOREACH(em64t ${em64ts} "")
    IF (NOT IPP_CORE_LIBRARIES)
      FIND_LIBRARY(IPP_CORE_LIBRARIES "ippcore${ipp64}")
      MARK_AS_ADVANCED(IPP_CORE_LIBRARIES)
    ENDIF(NOT IPP_CORE_LIBRARIES)
  ENDFOREACH(em64t)
ENDIF (NOT IPP_CORE_LIBRARIES)

# Find all ipp libraries
IF (IPP_CORE_LIBRARIES)
  MACRO(IPP_FIND_LIBRARIES _name _lname)
    IF (NOT IPP_${_name}_LIBRARIES)
      MARK_AS_ADVANCED(IPP_${_name}_LIBRARIES)
      FOREACH(ipplib ${ipplibs})
        FIND_LIBRARY(IPP_LIBRARY_${_lname}_${ipplib} "ipp${_lname}${ipplib}")
        MARK_AS_ADVANCED(IPP_LIBRARY_${_lname}_${ipplib})
        IF (IPP_LIBRARY_${_lname}_${ipplib})
          SET(IPP_${_name}_LIBRARIES 
            ${IPP_${_name}_LIBRARIES} ${IPP_LIBRARY_${_lname}_${ipplib}})
        ENDIF (IPP_LIBRARY_${_lname}_${ipplib})
      ENDFOREACH(ipplib)
    ENDIF (NOT IPP_${_name}_LIBRARIES)
  ENDMACRO(IPP_FIND_LIBRARIES)
  IPP_FIND_LIBRARIES(AC ac)
  IPP_FIND_LIBRARIES(CC cc)
  IPP_FIND_LIBRARIES(CP cp)
  IPP_FIND_LIBRARIES(CV cv)
  IPP_FIND_LIBRARIES(DC dc)
  IPP_FIND_LIBRARIES(DI di)
  IPP_FIND_LIBRARIES(GEN gen)
  IPP_FIND_LIBRARIES(I i)
  IPP_FIND_LIBRARIES(J j)
  IPP_FIND_LIBRARIES(M m)
  IPP_FIND_LIBRARIES(R r)
  IPP_FIND_LIBRARIES(S s)
  IPP_FIND_LIBRARIES(SC sc)
  IPP_FIND_LIBRARIES(SR sr)
  IPP_FIND_LIBRARIES(CH ch)
  IPP_FIND_LIBRARIES(VC vc)
  IPP_FIND_LIBRARIES(VM vm)
ENDIF (IPP_CORE_LIBRARIES)

# Dependencies
IF (IPP_CORE_LIBRARIES)
  MACRO(IPP_ADD_DEPENDENCIES _LIB _DEP)
    IF (IPP_${_LIB}_LIBRARIES)
      FOREACH(n ${_DEP})
        IF (IPP_${n}_LIBRARIES)
          SET(IPP_${_LIB}_LIBRARIES ${IPP_${_LIB}_LIBRARIES} ${IPP_${n}_LIBRARIES})
        ENDIF (IPP_${n}_LIBRARIES)
      ENDFOREACH(n)
    ENDIF (IPP_${_LIB}_LIBRARIES)
  ENDMACRO(IPP_ADD_DEPENDENCIES)
  IPP_ADD_DEPENDENCIES(AC  "DC;S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(CC  "I;S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(CP  "CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(CV  "I;S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(DC  "S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(DI  "CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(GEN "S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(I   "S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(J   "I;S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(M   "I;S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(R   "I;S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(S   "CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(SC  "S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(SR  "S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(CH  "S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(VC  "I;S;CORE;IOMP5")
  IPP_ADD_DEPENDENCIES(VM  "CORE;IOMP5")
ENDIF (IPP_CORE_LIBRARIES)

# Final 
SET(CMAKE_LIBRARY_PATH ${saved_CMAKE_LIBRARY_PATH})
SET(CMAKE_INCLUDE_PATH ${saved_CMAKE_INCLUDE_PATH})
IF (IPP_CORE_LIBRARIES)
  SET(IPP_FOUND TRUE)
ELSE (IPP_CORE_LIBRARIES)
  SET(IPP_FOUND FALSE)
ENDIF (IPP_CORE_LIBRARIES)

IF(_verbose)
  MESSAGE(STATUS "  IPP_FOUND=${IPP_FOUND}")
  MESSAGE(STATUS "  IPP_INCLUDE_DIR=${IPP_INCLUDE_DIR}")
  MESSAGE(STATUS "  IPP_IOMP5_LIBRARIES=${IPP_IOMP5_LIBRARIES}")
  MESSAGE(STATUS "  IPP_CORE_LIBRARIES=${IPP_CORE_LIBRARIES}")
  MESSAGE(STATUS "  IPP_AC_LIBRARIES=${IPP_AC_LIBRARIES}")
  MESSAGE(STATUS "  IPP_CC_LIBRARIES=${IPP_CC_LIBRARIES}")
  MESSAGE(STATUS "  IPP_CP_LIBRARIES=${IPP_CP_LIBRARIES}")
  MESSAGE(STATUS "  IPP_CV_LIBRARIES=${IPP_CV_LIBRARIES}")
  MESSAGE(STATUS "  IPP_DC_LIBRARIES=${IPP_DC_LIBRARIES}")
  MESSAGE(STATUS "  IPP_DI_LIBRARIES=${IPP_DI_LIBRARIES}")
  MESSAGE(STATUS "  IPP_GEN_LIBRARIES=${IPP_GEN_LIBRARIES}")
  MESSAGE(STATUS "  IPP_I_LIBRARIES=${IPP_I_LIBRARIES}")
  MESSAGE(STATUS "  IPP_J_LIBRARIES=${IPP_J_LIBRARIES}")
  MESSAGE(STATUS "  IPP_M_LIBRARIES=${IPP_M_LIBRARIES}")
  MESSAGE(STATUS "  IPP_R_LIBRARIES=${IPP_R_LIBRARIES}")
  MESSAGE(STATUS "  IPP_S_LIBRARIES=${IPP_S_LIBRARIES}")
  MESSAGE(STATUS "  IPP_SC_LIBRARIES=${IPP_SC_LIBRARIES}")
  MESSAGE(STATUS "  IPP_SR_LIBRARIES=${IPP_SR_LIBRARIES}")
  MESSAGE(STATUS "  IPP_CH_LIBRARIES=${IPP_CH_LIBRARIES}")
  MESSAGE(STATUS "  IPP_VC_LIBRARIES=${IPP_VC_LIBRARIES}")
  MESSAGE(STATUS "  IPP_VM_LIBRARIES=${IPP_VM_LIBRARIES}")
ENDIF(_verbose)

# Standard termination
IF(NOT IPP_FOUND AND IPP_FIND_REQUIRED)
  MESSAGE(FATAL_ERROR "IPP library not found. Please specify library  location")
ENDIF(NOT IPP_FOUND AND IPP_FIND_REQUIRED)
IF(NOT IPP_FIND_QUIETLY)
  IF(IPP_FOUND)
    MESSAGE(STATUS "IPP library found")
  ELSE(IPP_FOUND)
    MESSAGE(STATUS "IPP library not found")
  ENDIF(IPP_FOUND)
ENDIF(NOT IPP_FIND_QUIETLY)


# Do nothing if IPP_FOUND was set before!
ENDIF (NOT IPP_FOUND)
