/*--------------------------------------------------------------------
 *
 *	Copyright (c) 1991-2024 by the GMT Team (https://www.generic-mapping-tools.org/team.html)
 *	See LICENSE.TXT file for copying and redistribution conditions.
 *
 *	This program is free software; you can redistribute it and/or modify
 *	it under the terms of the GNU Lesser General Public License as published by
 *	the Free Software Foundation; version 3 or 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 Lesser General Public License for more details.
 *
 *	Contact info: www.generic-mapping-tools.org
 *--------------------------------------------------------------------*/
/*
 * gmt_dev.h is the main include file for the main development of gmt.
 * It includes the API (gmt.h) and contains lower-level definitions
 * for several of the structures and parameters used by all libraries.
 * It also includes all of the other include files that are needed.
 *
 * Author:	Paul Wessel
 * Date:	01-AUG-2011
 * Version:	6 API
 */

/*!
 * \file gmt_dev.h
 * \brief Main include file for the main development of gmt.
 */

/* Note on data type:  GMT will generally use double precision for
 * all floating point values except for grids which are held in single
 * precision floats.  All integer values are standard int (presumably
 * 32-bit) except for quantities that may be very large, such as
 * counters of data records, which will be declared as uint64_t, and
 * variables that holds allocated number of bytes and similar, which
 * will be declared as size_t.  Occasionally, arrays of integer values
 * will be stored in smaller memory containers such as short int of
 * unsigned/signed char when the program logic places limits on their
 * possible ranges (e.g., true/false variables).
 */

#pragma once
#ifndef GMT_DEV_H
#define GMT_DEV_H

#ifdef __cplusplus	/* Basic C++ support */
extern "C" {
#endif

/* Note: GMT functions will sometimes have arguments that are unused by design, i.e., to ensure that
 * a family of functions have the same number and type of arguments so that pointers to these functions
 * can be passed, even though in some cases not all arguments are used.  These will result in compiler
 * warnings [-Wunused-variable]. To suppress those (and only those), we can define gmt_M_unused as this:
 */

#define gmt_M_unused(x) (void)(x)

/* and then call gmt_M_unused() on all such variables at the beginning of a routine. For example:
 * bool func (int x) { gmt_M_unused(x); return(true); }
 * This should work for all compilers, GCC and others.
 * Just grep for gmt_M_unused to see where these situations occur.
 */

/* Because gcc does not support some features in clang AND due to bugs in os/base.h we must add these,
 * see http://stackoverflow.com/questions/26527077/compiling-with-accelerate-framework-on-osx-yosemite */

#ifdef __APPLE__
    /* Apple Xcode expects _Nullable to be defined but it is not if gcc */
#   ifndef _Nullable
#       define _Nullable
#   endif
#   ifndef __clang__
#       ifndef __has_extension
#           define __has_extension(x) 0
#       endif
#       define vImage_Utilities_h
#       define vImage_CVUtilities_h
#   endif
#endif
#if WIN32
#   define QSORT_R_THUNK_FIRST
#endif
/* Avoid some annoying warnings from MS Visual Studio */
#ifdef _MSC_VER
#	pragma warning( disable : 4091 )	/* 'static ': ignored on left of 'XXX' when no variable is declared */
#	pragma warning( disable : 4244 )	/* conversion from 'uint64_t' to '::size_t', possible loss of data */
#endif

/* CMake definitions: This must be first! */
#include "gmt_config.h"

#if defined(HAVE_GLIB_GTHREAD) || defined(_OPENMP)
/* This means we should enable the -x+a|[-]<ncores> common option */
#define GMT_MP_ENABLED
#endif

/* Declaration modifiers for DLL support (MSC et al) */
#include "declspec.h"

/* Declaration for PSL */
#include "postscriptlight.h"

/*--------------------------------------------------------------------
 *      SYSTEM HEADER FILES
 *--------------------------------------------------------------------*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <float.h>
#include <math.h>
#include <limits.h>
#include <errno.h>

#include <time.h>

#ifdef EXPORT_GMTLIB
/* Used to export everything so external environments can do unit tests */
#	define GMT_LOCAL EXTERN_MSC
#else
/* Used to restrict the scope of a function to the file it was declared in */
#	define GMT_LOCAL static
#endif

#include "gmt_common_byteswap.h"    /* Byte-swap inline functions */

#include "gmt_common_math.h" /* Shared math functions */
#include "gmt.h"             /* All GMT high-level API */
#include "gmt_private.h"     /* API declaration needed by libraries */
#include "gmt_constants.h"   /* All basic constant definitions */
#include "gmt_hidden.h"      /* Hidden bookkeeping structure for API containers */

struct GMT_CTRL; /* forward declaration of GMT_CTRL */

#include "gmt_notposix.h"       /* Non-POSIX extensions */

#include "gmt_modern.h"         /* Modern mode constant definitions */
#include "gmt_macros.h"         /* All basic macros definitions */
#include "gmt_dimensions.h"     /* Constant definitions created by configure */
#include "gmt_time.h"           /* Declarations of structures for dealing with time */
#include "gmt_texture.h"        /* Declarations of structures for dealing with pen, fill, etc. */
#include "gmt_defaults.h"       /* Declarations of structure for GMT default settings */
#include "gmt_psl.h"            /* Declarations of structure for GMT PostScript settings */
#include "gmt_hash.h"           /* Declarations of structure for GMT hashing */

#include "gmt_gdalread.h"      /* GDAL support */

#include "gmt_common.h"         /* For holding the GMT common option settings */
#include "gmt_fft.h"            /* Structures and enums used by programs needing FFTs */
#include "gmt_nan.h"            /* Machine-dependent macros for making and testing NaNs */
#include "gmt_error.h"          /* Only contains error codes */
#include "gmt_synopsis.h"       /* Only contains macros for synopsis lines */
#include "gmt_glib.h"           /* Make the GMT_xg_OPT define visible, even if HAVE_GLIB_GTHREAD is not defined */
#include "gmt_version.h"        /* Only contains the current GMT version number */
#include "gmt_project.h"        /* Define GMT->current.proj and GMT->current.map.frame structures */
#include "gmt_grd.h"            /* Define grd file header structure */
#include "gmt_grdio.h"          /* Defines function pointers for grd i/o operations */
#include "gmt_io.h"             /* Defines structures and macros for table i/o */
#include "gmt_shore.h"          /* Defines structures used when reading shore database */
#include "gmt_dcw.h"            /* Defines structure and functions used when using DCW polygons */
#include "gmt_symbol.h"         /* Custom symbol functions */
#include "gmt_contour.h"        /* Contour label structure and functions */
#include "gmt_decorate.h"       /* Decorated line structure */
#include "gmt_plot.h"           /* extern functions defined in gmt_plot.c */
#include "gmt_memory.h"         /* extern functions defined in gmt_M_memory.c */
#include "gmt_types.h"          /* GMT type declarations */
#include "gmt_remote.h"         /* GMT remote dataset structure */

#ifdef _OPENMP                  /* Using open MP parallelization */
#include <omp.h>
#endif

#include "gmt_prototypes.h"     /* All GMT low-level API */
#include "gmt_common_string.h"  /* All code shared between GMT and PSL */

#ifndef NO_SIGHANDLER
/* Include signal declarations */
#include "gmt_common_sighandler.h"
#endif

#include "gmt_mb.h"		/* GMT redefines for MB-system compatibility */

/* qsort_r is a mess: https://stackoverflow.com/questions/39560773/different-declarations-of-qsort-r-on-mac-and-linux */

#if defined (__APPLE__)
    /* Do thunk first via qsort_r */
	#define QSORT_R_THUNK_FIRST
	#define QSORT_R(base, nel, width, compar, thunk) qsort_r(base, nel, width, thunk, compar);
#elif defined (WIN32)
    /* Do thunk last via qsort_s */
	#define QSORT_R(base, nel, width, compar, thunk) qsort_s(base, nel, width, compar, thunk);
#elif defined (HAVE_QSORT_R_GLIBC)
    /* Use thunk last GNU order with qsort_r */
	#define QSORT_R(base, nel, width, compar, thunk) qsort_r(base, nel, width, compar, thunk);
#else
    /* Use thunk last via Florian's code */
	#include "compat/qsort.h"
	#define GMT_USE_COMPAT_QSORT
	#define QSORT_R(base, nel, width, compar, thunk) qsort_r(base, nel, width, compar, thunk);
#endif

#ifdef __cplusplus
}
#endif

#endif  /* !GMT_DEV_H */
