# vim: expandtab sw=2
# Copyright (C) 2000-2008
# Stefan Buehler   <sbuehler@ltu.se>
# Patrick Eriksson <patrick@rss.chalmers.se>
# Oliver Lemke     <olemke@core-dump.info>
#
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without 
# modifications, as long as this notice is preserved.
# 
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

AC_INIT(autogen.sh)
AM_CONFIG_HEADER(config.h)

# The ARTS release number must go here:
AM_INIT_AUTOMAKE(arts,1.11.50)


dnl Put the ACLOCAL flags in the Makefile
ACLOCAL="$ACLOCAL -I m4 $ACLOCAL_FLAGS"

AM_MAINTAINER_MODE


#
# First of all set the default PREFIX if not given
# (needed for arts data path later)
#
if test x${prefix} = xNONE; then
  prefix="/usr/local"
fi

# If FLAGS are not set, we set them explicitly empty to prevent
# autoconf from adding its default -O2 -g switches
test "$CFLAGS" || CFLAGS=""
test "$CXXFLAGS" || CXXFLAGS=""

# C Compiler:
AC_PROG_CC
AM_PROG_CC_C_O
# C Preprocessor
AC_PROG_CPP
# C++ Compiler:
AC_PROG_CXX
# C++ Preprocessor:
AC_PROG_CXXCPP
# Determine the name of the ranlib program
AC_PROG_RANLIB
# What's used by make install:
AC_PROG_INSTALL
# Check for compiler vendor
AX_COMPILER_VENDOR
AC_LANG_PUSH([C++])
AX_COMPILER_VENDOR
AC_LANG_POP([C++])

#
# Check for python
#
AC_CHECK_PROG(ac_python, python, yes, no)
if test x$ac_python = xno; then
  AC_MSG_ERROR([Python not found - Get it from http://www.python.org/])
fi

#
# Provide standard headers:
#
AC_STDC_HEADERS

#
# Check features of c++ compiler
#
AC_CXX_HAVE_STD
AC_CXX_BOOL
AC_CXX_STATIC_CAST
AC_CXX_CONST_CAST
AC_CXX_TEMPLATES
AC_CXX_HAVE_SSTREAM

#
# Check compiler characteristics
#
AC_C_INLINE
AC_C_CONST
AC_TYPE_SIZE_T
AC_CHECK_SIZEOF(float, 8)
AC_CHECK_SIZEOF(double, 16)
AC_CHECK_SIZEOF(int, 4)
AC_CHECK_SIZEOF(long, 8)
AC_CHECK_SIZEOF(size_t, 8)


# Special headers that we need:
# AC_HAVE_HEADERS(getopt.h) (now included in the source)
AC_CHECK_HEADER(math.h, , AC_MSG_ERROR(required header file <math.h> missing))

#
# Check for math library
#
AC_CHECK_LIB(m, sin, ,
  AC_MSG_ERROR(function $func not found in math library) )

#
# Check for zlib library
#
AC_CHECK_LIB(z, gzopen, ac_zlibsupport=yes, ac_zlibsupport=no )

AM_CONDITIONAL(ENABLE_ZLIB, test x$ac_zlibsupport = xyes)
if test x$ac_zlibsupport = xyes; then
  AC_DEFINE([ENABLE_ZLIB],[1],[Define to compile with zlib support])
fi

#
# Check for netcdf library
#
AC_MSG_CHECKING([whether NetCDF exists and contains nc_open])
AC_COMPILE_IFELSE(
                  [AC_LANG_PROGRAM([[ #include <netcdf.h> ]],
                                   [[ int id; nc_open("", NC_NOWRITE, &id) ]])],ac_ncsupport=yes, ac_ncsupport=no, netcdf.h )
AC_MSG_RESULT($ac_ncsupport)

if test x$ac_ncsupport = xyes; then
  AC_CHECK_LIB(netcdf, nc_open, ac_ncsupport=yes, ac_ncsupport=no )
fi

AM_CONDITIONAL(ENABLE_NETCDF, test x$ac_ncsupport = xyes)
if test x$ac_ncsupport = xyes; then
  AC_DEFINE([ENABLE_NETCDF],[1],[Define to compile with NetCDF support])
fi

#
# Default Numeric type
#
AC_ARG_WITH(numeric-type,
[  --with-numeric-type=ARG    Set Numeric type (default=double)],
[case "${withval}" in
  double) ac_numeric_type=double ;;
   float) ac_numeric_type=float ;;
       *) AC_MSG_ERROR(bad value ${withval} for --with-numeric-type) ;;
esac],[ ac_numeric_type=double ])

AC_MSG_RESULT(Setting Numeric type to $ac_numeric_type)
AC_DEFINE_UNQUOTED(NUMERIC, $ac_numeric_type, Default Numeric type)
if test x$ac_numeric_type = xfloat; then
  AC_DEFINE_UNQUOTED(USE_FLOAT,, Whether float precision is in use)
fi

if test x$ac_numeric_type = xdouble; then
  AC_DEFINE_UNQUOTED(USE_DOUBLE,, Whether double precision is in use)
fi

#
# Default Index type
#
AC_ARG_WITH(index-type,
[  --with-index-type=ARG      Set Index type (default=long)],
[case "${withval}" in
  short) ac_index_type=short ;;
  int)  ac_index_type=int ;;
  long)  ac_index_type=long ;;
  size_t)  ac_index_type=size_t ;;
    *) AC_MSG_ERROR(bad value ${withval} for --with-index-type) ;;
esac],[ ac_index_type=long ])

AC_MSG_RESULT(Setting Index type to $ac_index_type)
AC_DEFINE_UNQUOTED(INDEX, $ac_index_type, Default Index type)


#
# Detect/disable Disort
#
AC_MSG_CHECKING(whether Disort should be supported)
AC_ARG_ENABLE(disort,
[  --enable-disort          Enable Disort support (default=no)],
[case "${enableval}" in
   yes) AC_MSG_RESULT([yes]);
   AC_CHECK_HEADER(f2c.h, ac_disort=yes, AC_MSG_ERROR([cannot find f2c.h which is required for disort])) ;;
    *) ac_disort=no; AC_MSG_RESULT([no]);;
esac],[ AC_MSG_RESULT([yes]);
        ac_disort=no ])
AM_CONDITIONAL(ENABLE_DISORT, test x$ac_disort = xyes)
if test x$ac_disort = xyes; then
  AC_DEFINE([ENABLE_DISORT],[1],[Define to compile with disort support])
fi


#
# Enable/disable debugging
#
AC_MSG_CHECKING(whether debugging should be activated)
AC_ARG_ENABLE(debug,
[  --enable-debug           Enable debugging mode (default=no)],
[case "${enableval}" in
  yes) ac_debug=yes ;;
   no) ac_debug=no ;;
    *) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
esac],[ ac_debug=$USE_MAINTAINER_MODE ])
AM_CONDITIONAL(DEBUGGING, test x$ac_debug = xyes)
AC_MSG_RESULT([$ac_debug])


#
# Enable/disable optimizations
#
AC_MSG_CHECKING(whether optimizations should be activated)
AC_ARG_ENABLE(optimize,
[  --enable-optimize        Enable compiler optimizations (default=yes)],
[case "${enableval}" in
  yes) ac_optimize=yes ;;
   no) ac_optimize=no ;;
    *) AC_MSG_ERROR(bad value ${enableval} for --enable-optimize) ;;
  esac],[ ac_optimize=yes ])
AM_CONDITIONAL(OPTIMIZE, test x$ac_optimize = xyes)
AC_MSG_RESULT([$ac_optimize])


AC_MSG_CHECKING(whether advanced optimizations should be activated)
AC_ARG_ENABLE(full-optimize,
[  --enable-full-optimize        Enable advanced compiler optimizations (default=no)],
[case "${enableval}" in
  yes) ac_full_optimize=yes ;;
   no) ac_full_optimize=no ;;
    *) AC_MSG_ERROR(bad value ${enableval} for --enable-full-optimize) ;;
  esac],[ ac_full_optimize=no ])
AM_CONDITIONAL(OPTIMIZE, test x$ac_full_optimize = xyes)
AC_MSG_RESULT([$ac_full_optimize])


#
# Enable/disable warnings
#
AC_MSG_CHECKING(whether warnings should be enabled)
AC_ARG_ENABLE(more-warnings,
[  --enable-more-warnings   Enable more warnings (default=no)],
[case "${enableval}" in
  yes) ac_more_warnings=yes ;;
   no) ac_more_warnings=no ;;
    *) AC_MSG_ERROR(bad value ${enableval} for --enable-more-warnings) ;;
esac],[ ac_more_warnings=no ])
AC_MSG_RESULT([$ac_more_warnings])


#
# Enable/disable vectorization
#
AC_MSG_CHECKING(whether vectorization should be enabled)
AC_ARG_ENABLE(vectorize,
[  --disable-vectorize      Disable OpenMP vectorization (default=auto)],
[case "${enableval}" in
   no) ax_openmp=no ;;
   *) ax_openmp=auto;; esac
   ],[ax_openmp=auto])
AC_MSG_RESULT([$ax_openmp])

if test x$ax_openmp = xauto; then
  if test "$ac_optimize" = "no" -a "$ax_cv_cxx_compiler_vendor" = "intel"; then
    ax_openmp="OpenMP disabled because it doesn't work properly
                             with the Intel compiler when compiling without
                             optimizations"
  else
    # Detect openmp
    AX_OPENMP(ax_openmp_c=yes,ax_openmp_c=no)
    AC_LANG_PUSH([C++])
    AX_OPENMP(ax_openmp_cxx=yes,ax_openmp_cxx=no)
    AC_LANG_POP([C++])

    if test "$ax_openmp_c" = "yes" -a "$ax_openmp_cxx" = "yes"; then
      ax_openmp="yes"
    elif test "$ax_openmp_c" = "no" -a "$ax_openmp_cxx" = "no"; then
      ax_openmp="no OpenMP support in compiler found"
    else
      ax_openmp="partly (check log!)"
    fi
  fi
fi


#
# Toggle documentation
#
if test x$USE_MAINTAINER_MODE = xyes; then
  ac_docgen=yes
else
  ac_docgen=no
fi
AC_MSG_CHECKING(whether documentation should be generated)
AM_CONDITIONAL(ARTS_GENDOCS, test x$ac_docgen = xyes)
AC_MSG_RESULT([$ac_docgen])


#
# Check for the required tools to build the docs
#
if test x$ac_docgen = xyes; then
    AC_CHECK_PROG(ac_doxygen, doxygen, yes, no)
    if test x$ac_doxygen = xno; then
        AC_MSG_WARN(Doxygen is required to build the documentation - Get it from http://www.doxygen.org/)
    fi

    AC_CHECK_PROG(ac_dot, dot, yes, no)
    if test x$ac_dot = xno; then
      AC_MSG_WARN(The dot tool from the graphviz package is needed to generate dependency plots in the documentation - Get it from http://www.graphviz.org/)
    fi
    AC_SUBST(ac_dot)

    AC_CHECK_PROG(ac_latex, latex, yes, no)
    if test x$ac_latex = xno; then
        AC_MSG_ERROR(LaTeX is required to build the documentation!!!)
    fi

    AC_CHECK_PROG(ac_pdflatex, pdflatex, yes, no)
    if test x$ac_pdflatex = xno; then
        AC_MSG_ERROR(pdfLaTeX is required to build the documentation!!!)
    fi

fi

#
# Set warning flags
#
WARNINGCFLAGS=
case x$ax_cv_cxx_compiler_vendor in
  xgnu)
    AC_CHECK_TOOL(AR,ar)
    #
    # GNU Compiler warning flags
    #
    GCC_MAJOR=`$CC -v 2>&1 | grep '^gcc version' | sed 's/^gcc version \([[0-9]]\)\..*$/\1/'`
    GCC_MINOR=`$CC -v 2>&1 | grep '^gcc version' | sed 's/^gcc version [[0-9]]\.\([[0-9]]\)\..*$/\1/'`

    WARNINGCFLAGS="-W -Wall -Wconversion"

    if test x"$ax_openmp" != xyes; then
      WARNINGCFLAGS="$WARNINGCFLAGS -Wno-unknown-pragmas"
    fi

    if test x$ac_more_warnings = xyes; then

      WARNINGCFLAGS="$WARNINGCFLAGS -Werror"

      # gcc2 produces warnings in standard headers, therefore only
      # enable it with gcc3 and gcc4
      if test x$GCC_MAJOR = x3 -o x$GCC_MAJOR = x4; then
        WARNINGCFLAGS="$WARNINGCFLAGS -Wshadow"
      fi
    fi

    #
    # GNU Compiler debug flags
    #
    if test x$ac_debug = xyes; then
      DEBUG_FLAGS="-g"
    else
      DEBUG_FLAGS=""
      CPPFLAGS="-DNDEBUG $CPPFLAGS"
    fi

    #
    # GNU Compiler optimization flags
    #
    if test x$ac_full_optimize = xyes; then
      CFLAGS_OPT="-O3"
      CXXFLAGS_OPT="$CFLAGS_OPT"
    elif test x$ac_optimize = xyes; then
      CFLAGS_OPT="-O2"
      CXXFLAGS_OPT="$CFLAGS_OPT"
    else
      CFLAGS_OPT=""
      CXXFLAGS_OPT=""
    fi

    CXXFLAGS_NOOPT=""
    CXXFLAGS="-ftemplate-depth-60 $CXXFLAGS"
    CXXNOSTRICTALIASING="-fno-strict-aliasing"

    AC_DEFINE_UNQUOTED(_U_, [__attribute((unused))], Macro to ignore unused function parameters)
    ;;
  xintel)
    AC_CHECK_TOOL(AR,xiar)
    #
    # Intel Compiler warning flags
    #
    WARNINGCFLAGS="-Wall -Wshadow -w1 -diag-disable 383,981,1418,1419"

    if test x"$ax_openmp" != xyes; then
      WARNINGCFLAGS="$WARNINGCFLAGS -Wno-unknown-pragmas"
    fi

    if test x$ac_more_warnings = xyes; then
      WARNINGCFLAGS="$WARNINGCFLAGS -Werror"
    fi

    #
    # Intel Compiler debug flags
    #
    if test x$ac_debug = xyes; then
      DEBUG_FLAGS="-g"
    else
      DEBUG_FLAGS=""
      CPPFLAGS="-DNDEBUG $CPPFLAGS"
    fi

    #
    # Intel Compiler optimization flags
    #
    if test x$ac_full_optimize = xyes; then
      CFLAGS_OPT="-O3 -ip"
      CXXFLAGS_OPT="$CFLAGS_OPT"
    elif test x$ac_optimize = xyes; then
      CFLAGS_OPT="-O2"
      CXXFLAGS_OPT="$CFLAGS_OPT"
    else
      CFLAGS_OPT=""
      CXXFLAGS_OPT=""
    fi

    CXXFLAGS_NOOPT="$CXXFLAGS_OPT"
    CXXNOSTRICTALIASING=""

    AC_DEFINE_UNQUOTED(_U_, [__attribute((unused))], Macro to ignore unused function parameters)

    #
    # Intel Compiler linker flags
    #
    LDFLAGS="-lstdc++ $LDFLAGS"
    ;;
  *)
    AC_CHECK_TOOL(AR,ar)
    CFLAGS_OPT="$CFLAGS"
    CXXFLAGS_OPT="$CXXFLAGS"
    CFLAGS_NOOPT="$CFLAGS"
    CXXFLAGS_NOOPT="$CXXFLAGS"
    CXXNOSTRICTALIASING=""
    echo "WARNING: UNKNOWN COMPILER VENDOR"
esac

AC_SUBST(LDFLAGS)
AC_SUBST(WARNINGCFLAGS)


#
# OS check
#
ac_osname=`uname`
ac_osversion=`uname -r`

AM_CONDITIONAL(OS_NAME, test "$ac_osname")
AC_DEFINE_UNQUOTED(OS_NAME, "$ac_osname", Operating system name)

AM_CONDITIONAL(OS_VERSION, test "$ac_osversion")
AC_DEFINE_UNQUOTED(OS_VERSION, "$ac_osversion", Operating system version)

case "$ac_osname" in
  Linux) CPPFLAGS="$CPPFLAGS -DLINUX" ;;
  HP-UX) CPPFLAGS="$CPPFLAGS -DHPUX" ;;
  SunOS) CPPFLAGS="$CPPFLAGS -DSUNOS" ;;
esac


#
# Compile flags switches
#
CFLAGS="$DEBUG_FLAGS $CFLAGS $OPENMP_CFLAGS"
CXXFLAGS="$DEBUG_FLAGS $CXXFLAGS $OPENMP_CXXFLAGS"

AC_SUBST(CFLAGS_OPT)
AC_SUBST(CFLAGS_NOOPT)
AC_SUBST(CXXFLAGS_OPT)
AC_SUBST(CXXFLAGS_NOOPT)
AC_SUBST(CXXNOSTRICTALIASING)

AM_CONDITIONAL(COMPILE_FLAGS, test "$CXXFLAGS")
AC_DEFINE_UNQUOTED(COMPILE_FLAGS, "$CXXFLAGS $CXXFLAGS_OPT", Compile Flags)

AC_OUTPUT([
arts.spec
Makefile 
   3rdparty/Makefile
      3rdparty/disort1.2/Makefile
   aii/Makefile 
   doc/Makefile 
   doc/index.html
      doc/icons/Makefile 
      doc/doxygen/Makefile
      doc/doxygen/Doxyfile
         doc/doxygen/html/Makefile
      doc/uguide/Makefile 
      doc/uguide/auto_version.tex 
         doc/uguide/Figs/Makefile 
   includes/Makefile 
      includes/amsu/Makefile 
      includes/odin/Makefile 
   m4/Makefile 
   src/Makefile
   tests/Makefile
])

AC_MSG_RESULT()
AC_MSG_RESULT([*******************************************************])
AC_MSG_RESULT([              ARTS configuration summary])
AC_MSG_RESULT()
AC_MSG_RESULT([  Maintainer mode          : $USE_MAINTAINER_MODE])
AC_MSG_RESULT([  Debugging                : $ac_debug])
AC_MSG_RESULT([  Optimizations            : $ac_optimize])
AC_MSG_RESULT([  OpenMP support           : $ax_openmp])
AC_MSG_RESULT([  Numeric type             : $ac_numeric_type])
AC_MSG_RESULT([  Index type               : $ac_index_type])
AC_MSG_RESULT([  Zlib support             : $ac_zlibsupport])
AC_MSG_RESULT([  NetCDF support           : $ac_ncsupport])
if test x$ac_disort = xno; then
  AC_MSG_RESULT([  Disort                   : no (not enabled or f2c library not found)])
else
  AC_MSG_RESULT([  Disort                   : yes])
fi

AC_MSG_RESULT([  Regenerate documentation : $ac_docgen])
AC_MSG_RESULT()
AC_MSG_RESULT([  CC             : $CC])
AC_MSG_RESULT([  CXX            : $CXX])
AC_MSG_RESULT([  CPPFLAGS       : $CPPFLAGS])
AC_MSG_RESULT([  CFLAGS         : $CFLAGS_OPT $CFLAGS])
AC_MSG_RESULT([  CXXFLAGS       : $CXXFLAGS_OPT $CXXFLAGS])
AC_MSG_RESULT([  WARNINGFLAGS   : $WARNINGCFLAGS])
AC_MSG_RESULT([  LDFLAGS        : $LDFLAGS])
AC_MSG_RESULT([*******************************************************])
AC_MSG_RESULT()

