/**************************************************************

comfun.h (C-Munipack project)
Private common types, definitions, helper functions, ...
Copyright (C) 2003 David Motl, dmotl@volny.cz

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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

**************************************************************/

#ifndef COMFUN_H
#define COMFUN_H

#include <stdint.h>

#include "cmpack_common.h"
#include "cmpack_table.h"
#include "cmpack_ccdfile.h"

/* ************* Common constats *******************/

/* Maximum length of the line in text files */
#define MAXLINE 1024

/* Maximum number of apertures */
#define MAXAP    12              

/* Pi number */
/* PI number */
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

/* Number of decimal places: */
#define MAG_PRECISION	5			/**< Magnitudes */
#define JD_PRECISION	7			/**< Julian date */
#define POS_PRECISION	2			/**< Object positions */
#define EXP_PRECISION	3			/**< Exposure duration */
#define	TEMP_PRECISION  2			/**< Temperature */
#define AMASS_PRECISION	4			/**< Airmass coefficients */
#define ALT_PRECISION	2			/**< Altitude */
#define FWHM_PRECISION	2			/**< Full width at half maximum */
#define SKY_PRECISION	2			/**< Sky intensity, noise */

#define INVALID_JD		0.0			/**< Invalid Julian date */
#define INVALID_HCORR	99.0		/**< Invalid heliocentric correction */
#define INVALID_MAG		99.99999	/**< Invalid magnitude value */
#define INVALID_MAGERR	9.99999		/**< Invalid error value */
#define INVALID_TEMP	999.99		/**< Invalid temperature */
#define INVALID_ALT		-99.99		/**< Invalid altitude */
#define INVALID_AMASS	-1.0			/**< Invalid air mass */
#define INVALID_EXPTIME	-1.0			/**< Invalid exposure duration */
#define INVALID_XY		-1.0			/**< Invalid frame offset */
#define INVALID_SKY		-999.99		/**< Invalid sky intensity */
#define INVALID_SKYERR	-1.0			/**< Invalid sky noise */
#define INVALID_FWHM	-1.0			/**< Invalid FWHM value */

/****************** Common macros ******************/

#define fsig(x)   ((x)>=0?(+1):(-1))
#define fabs(x)   ((x)>=0?(x):-(x))
#define fmax(x,y) (((x)>(y))?(x):(y))
#define fmin(x,y) (((x)<(y))?(x):(y))

/**************** Common functions *****************/

/**
	\brief Get range for specified output data format
	\param[in] bitpix		output data format
	\param[out] minvalue	minimal value
	\param[out] maxvalue	maximal value
	\return nonzero on success, zero on failure
*/
int pixrange(CmpackBitpix bitpix, double *minvalue, double *maxvalue);

/**
	\brief Print output data format
	\param[in] bitpix		output data format
	\return allocated string
*/
const char *pixformat(int bitpix);

/**
	\brief Returns true if the string contains whitespaces on
	its start or end.
*/
int needs_trim(const char *str);

/**
	\brief Trim all leading and trailing whitespace characters from a string
	\details The result of the operation is stored to a newly
	allocated buffer.
*/
char *trim(const char *str);

/**
	\brief Trim all trailing whitespace characters from a string
	\details The operation is done in situ, the function returns
	the same pointer as the parameter.
*/
char *rtrim(char *str);

/**
	\brief Trim all leading whitespace characters from a string
	\details The result of the operation is stored to a newly
	allocated buffer.
*/
char *ltrim(const char *str);

/**
	\brief Find a string in memory buffer.
	\details This is similar to strstr, but the haystack need
	not to be null-terminated
*/
const char *memstr(const char *haystack, char *needle, size_t haystack_size);

/**
	\brief unquote FITS string 
	\details If the given null-terminated string starts with a quote or
	spaces followed by quote, the function extract the characters between starting
	and ending quote. If two subsequent quotes appear in the string, it is replaced
	by single quote. Also removed all trailing spaces even if they are inside quotes.
	The operation is done in situ, the function returns the same pointer as the parameter.
*/
char *fits_unquote(char *str);

/**
	\brief encode string that it can be safely written to XML file
*/
char *xml_encode_string(const char *str);

/**
	\brief copy string to buffer with truncation
*/
int strcpy_truncate(char *buf, int bufsize, const char *str);

/**************** Cross platform mutex *****************/

/* Mutex object */
typedef intptr_t CmpackMutex;

/* Initialize mutex object (non-recursive) */
void cmpack_mutex_init(CmpackMutex *mutex);

/* Lock the given mutex. Blocks until the given mutex can be locked.
   If the calling thread already has a lock on the mutex, this call will block forever. */
void cmpack_mutex_lock(CmpackMutex *mutex);

/* Unlock the given mutex. */
void cmpack_mutex_unlock(CmpackMutex *mutex);

/* Release any resources used by the given mutex. */
void cmpack_mutex_destroy(CmpackMutex *mutex);

#endif
