# This is an example script for use with CMake projects for locating and configuring
# the nanopb library.
#
# The following varialbes have to be set:
#
#   NANOPB_SRC_ROOT_FOLDER  - Path to nanopb source folder
#
# The following variables can be set and are optional:
#
#
#   PROTOBUF_SRC_ROOT_FOLDER - When compiling with MSVC, if this cache variable is set
#                              the protobuf-default VS project build locations
#                              (vsprojects/Debug & vsprojects/Release) will be searched
#                              for libraries and binaries.
#
#   NANOPB_IMPORT_DIRS       - List of additional directories to be searched for
#                              imported .proto files.
#
#   NANOPB_GENERATE_CPP_APPEND_PATH - By default -I will be passed to protoc
#                                     for each directory where a proto file is referenced.
#                                     Set to FALSE if you want to disable this behaviour.
#
# Defines the following variables:
#
#   NANOPB_FOUND - Found the nanopb library (source&header files, generator tool, protoc compiler tool)
#   NANOPB_INCLUDE_DIRS - Include directories for Google Protocol Buffers
#
# The following cache variables are also available to set or use:
#   NANOPB_GENERATOR_EXECUTABLE - The nanopb generator
#   PROTOBUF_PROTOC_EXECUTABLE - The protoc compiler
#
#  ====================================================================
#
# NANOPB_GENERATE_CPP (public function)
#   SRCS = Variable to define with autogenerated
#          source files
#   HDRS = Variable to define with autogenerated
#          header files
#   ARGN = proto files
#
#  ====================================================================
#  Example:
#
#   set(NANOPB_SRC_ROOT_FOLDER "/path/to/nanopb")
#   set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${NANOPB_SRC_ROOT_FOLDER}/cmake)
#   find_package( Nanopb REQUIRED )
#   include_directories(${NANOPB_INCLUDE_DIRS})
#
#   NANOPB_GENERATE_CPP(PROTO_SRCS PROTO_HDRS foo.proto)
#
#   include_directories(${CMAKE_CURRENT_BINARY_DIR})
#   add_executable(bar bar.cc ${PROTO_SRCS} ${PROTO_HDRS})
#
#  ====================================================================

#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2009-2011 Philip Lowman <philip@yhbt.com>
# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in the
#   documentation and/or other materials provided with the distribution.
#
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
#   nor the names of their contributors may be used to endorse or promote
#   products derived from this software without specific prior written
#   permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
#=============================================================================
#
# Changes
# 2013.01.31 - Pavlo Ilin - used Modules/FindProtobuf.cmake from cmake 2.8.10 to
#                           write FindNanopb.cmake
#
#=============================================================================


function(NANOPB_GENERATE_CPP SRCS HDRS)
  if(NOT ARGN)
    return()
  endif()

  if(NANOPB_GENERATE_CPP_APPEND_PATH)
    # Create an include path for each file specified
    foreach(FIL ${ARGN})
      get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
      get_filename_component(ABS_PATH ${ABS_FIL} PATH)

      list(FIND _nanobp_include_path ${ABS_PATH} _contains_already)
      if(${_contains_already} EQUAL -1)
          list(APPEND _nanobp_include_path -I ${ABS_PATH})
      endif()
    endforeach()
  else()
    set(_nanobp_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
  endif()

  if(DEFINED NANOPB_IMPORT_DIRS)
    foreach(DIR ${NANOPB_IMPORT_DIRS})
      get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
      list(FIND _nanobp_include_path ${ABS_PATH} _contains_already)
      if(${_contains_already} EQUAL -1)
          list(APPEND _nanobp_include_path -I ${ABS_PATH})
      endif()
    endforeach()
  endif()

  set(${SRCS})
  set(${HDRS})
  get_filename_component(GENERATOR_PATH ${NANOPB_GENERATOR_EXECUTABLE} PATH)

  foreach(FIL ${ARGN})
    get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
    get_filename_component(FIL_WE ${FIL} NAME_WE)

    list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.c")
    list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")

    add_custom_command(
      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb"
      COMMAND  ${PROTOBUF_PROTOC_EXECUTABLE}
      ARGS -I${GENERATOR_PATH} -I${CMAKE_CURRENT_BINARY_DIR} ${_nanobp_include_path} -o${FIL_WE}.pb ${ABS_FIL}
      DEPENDS ${ABS_FIL}
      COMMENT "Running C++ protocol buffer compiler on ${FIL}"
      VERBATIM )

    add_custom_command(
      OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.c"
             "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
      COMMAND python
      ARGS ${NANOPB_GENERATOR_EXECUTABLE} ${FIL_WE}.pb
      DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb"
      COMMENT "Running nanopb generator on ${FIL_WE}.pb"
      VERBATIM )
  endforeach()

  set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
  set(${SRCS} ${${SRCS}} ${NANOPB_SRCS} PARENT_SCOPE)
  set(${HDRS} ${${HDRS}} ${NANOPB_HDRS} PARENT_SCOPE)

endfunction()



#
# Main.
#

# By default have NANOPB_GENERATE_CPP macro pass -I to protoc
# for each directory where a proto file is referenced.
if(NOT DEFINED NANOPB_GENERATE_CPP_APPEND_PATH)
  set(NANOPB_GENERATE_CPP_APPEND_PATH TRUE)
endif()

# Find the include directory
find_path(NANOPB_INCLUDE_DIRS
    pb.h
    PATHS ${NANOPB_SRC_ROOT_FOLDER}
)
mark_as_advanced(NANOPB_INCLUDE_DIRS)

# Find nanopb source files
set(NANOPB_SRCS)
set(NANOPB_HDRS)
list(APPEND _nanopb_srcs pb_decode.c pb_encode.c)
list(APPEND _nanopb_hdrs pb_decode.h pb_encode.h pb.h)

foreach(FIL ${_nanopb_srcs})
  find_file(${FIL}__nano_pb_file NAMES ${FIL} PATHS ${NANOPB_SRC_ROOT_FOLDER} ${NANOPB_INCLUDE_DIRS})
  list(APPEND NANOPB_SRCS "${${FIL}__nano_pb_file}")
  mark_as_advanced(${FIL}__nano_pb_file)
endforeach()

foreach(FIL ${_nanopb_hdrs})
  find_file(${FIL}__nano_pb_file NAMES ${FIL} PATHS ${NANOPB_INCLUDE_DIRS})
  mark_as_advanced(${FIL}__nano_pb_file)
  list(APPEND NANOPB_HDRS "${${FIL}__nano_pb_file}")
endforeach()

# Find the protoc Executable
find_program(PROTOBUF_PROTOC_EXECUTABLE
    NAMES protoc
    DOC "The Google Protocol Buffers Compiler"
    PATHS
    ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Release
    ${PROTOBUF_SRC_ROOT_FOLDER}/vsprojects/Debug
)
mark_as_advanced(PROTOBUF_PROTOC_EXECUTABLE)

# Find nanopb generator
find_file(NANOPB_GENERATOR_EXECUTABLE
    NAMES nanopb_generator.py
    DOC "nanopb generator"
    PATHS
    ${NANOPB_SRC_ROOT_FOLDER}/generator
)
mark_as_advanced(NANOPB_GENERATOR_EXECUTABLE)

include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(NANOPB DEFAULT_MSG
  NANOPB_INCLUDE_DIRS
  NANOPB_SRCS NANOPB_HDRS
  NANOPB_GENERATOR_EXECUTABLE
  PROTOBUF_PROTOC_EXECUTABLE
  )
