/*
 Copyright (C) 2004   Teemu Ikonen   <tpikonen@pcu.helsinki.fi>
 Copyright (C) 2016   Susi Lehtola
 Copyright (C) 2016   Julien Bect    <jbect@users.sourceforge.net>

 This program is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation; either version 2 of the License, or
 (at your option) any later version.

 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program; if not, see <http://www.gnu.org/licenses/>.
*/

#include "config.h"
#include <limits>
#include <octave/oct.h>
#include <octave/parse.h>
#include <gsl/gsl_sf.h>
#include <gsl/gsl_sf_result.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_version.h>

#ifdef OCTAVE_HAS_OV_ISREAL_METHOD
#define ISREAL(x) ((x).isreal ())
#else
#define ISREAL(x) ((x).is_real_type ())
#endif

void octave_gsl_errorhandler (const char * reason, const char * file,
			      int line, int gsl_errno)
{
    error("GSL error %d at %s, line %d: %s\n", gsl_errno, file, line, reason);
}

DEFUN_DLD (gsl_sf, args, nargout,
  "-*- texinfo -*-\n\
@deftypefn {Loadable Function} gsl_sf ()\n\
\n\
gsl_sf is an oct-file containing Octave bindings to the \
special functions of the GNU Scientific Library (GSL).\n\
\n\
@end deftypefn\n")
{
#ifdef OCTAVE_HAS_FEVAL_IN_OCTAVE_NAMESPACE
  octave::feval ("help", octave_value ("gsl_sf"));
#else
  feval ("help", octave_value ("gsl_sf"));
#endif

  return octave_value();
}


template <typename A>
bool check_arg_dim
(
 A arg,
 dim_vector &dim,
 octave_idx_type &numel,
 bool &conformant
)
{
  dim_vector arg_dim = arg.dims ();
  octave_idx_type arg_numel = arg.numel ();

  // If this is a scalar argument, nothing more to do.
  // The return value indicates that this is a scalar argument.
  if (arg_numel == 1)
    return true;

  if (numel == 1)
  {
    dim = arg_dim;
    numel = arg_numel;
  }
  else if (arg_dim != dim)
  {
    conformant = false;
  }
  return false;
}
