/**
	\file
	\brief World Coordinate System (WCS) suport

	Set of functions that manage the WCS data. This is basically
	a wrapper around wcslib. Using this wrapper, the application 
	does not need to include the wcslib.h directly; this is tiresome
	because of the conflict between its wcsset function and wcsset
	defined in wchar.h.
	
	\author David Motl <dmotl@volny.cz>
	
	\par Copying
	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, version 2.
	
	$Id: cmpack_wcs.h,v 1.2 2015/07/12 08:11:55 dmotl Exp $
*/

#ifndef _CMPACK_WCS_H_INCLUDED
#define _CMPACK_WCS_H_INCLUDED

#include "cmpack_config.h"

/********************   Public data types   ********************************/

/**
	\brief WCS data context
	\details This private structure is used to read the WCS data
	from a frame. It is designed to hold one celestial WCS data set.
*/
typedef struct _CmpackWcs CmpackWcs;

/** \brief WCS axis property flags */
typedef enum _CmpackWcsAxisMask
{
	CMPACK_AP_STYP = (1<<0),		/** axis short type */
	CMPACK_AP_NAME = (1<<1),		/** axis name */
	CMPACK_AP_UNIT = (1<<3)			/** axis unit */
} CmpackWcsAxisMask;

/** \brief WCS axis parameters */
typedef struct _CmpackWcsAxisParams
{
	char styp[8];
	char name[72];
	char unit[72];
} CmpackWcsAxisParams;

/********************   Public functions   ********************************/

#ifdef __cplusplus
extern "C" {
#endif

/**
	\brief Make a new reference to the WCS data set
	\details The function makes a new reference to the CmpackWcs object and returns a 
	pointer to it. The reference counter is incremented by one. The caller 
	is responsible to call cmpack_wcs_destroy() when the reference is 
	no longer needed.
	\param[in]	wcs				wcs data set
	\return pointer to a new reference
*/
	CMPACK_EXPORT(CmpackWcs*, cmpack_wcs_reference, (CmpackWcs* wcs));

/**
	\brief Release a reference to the WCS data set
	\details The function releases a reference to the CmpackWcs object. 
	The reference counter is decreased by one and when it was the last 
	reference to the object, the object is released from the memory.
	\param[in]	wcs				wcs data set
*/
	CMPACK_EXPORT(void, cmpack_wcs_destroy, (CmpackWcs* wcs));

/**
	\brief Make copy of the WCS data
	\details The function makes deep copy of the source data to 
	the target data.
	\param[in] src				source data context
	\return new CmpackWcs object
*/
	CMPACK_EXPORT(CmpackWcs*, cmpack_wcs_copy, (const CmpackWcs* src));

/**
	\brief Print the WCS data (debug output)
	\details Use this function to print debugging output for the WCS data. 
	The output is given in newly allocated memory buffer, the caller is 
	responsible to free the memory using the cmpack_free function. The string is
	terminated by a NULL character.
	\param[in] wcs				wcs data set
	\param[out]	buf				memory buffer
	\param[out]	len				size of data, not including the nul terminator
	\return zero on success, error code on failure
*/
	CMPACK_EXPORT(int, cmpack_wcs_print, (CmpackWcs* wcs, char** buf, int* len));

/**
	\brief Get name of the WCS data set (optional)
	\details This function returns a name of the current data set, if any.
	The name is retrieved from the wcsname field of the wcsprm structure.
	This field is optional. The function may return NULL, if the name
	of the data set is not defined.
	The function returns pointer to the internal memory. Do not free or 
	modify it.
	\param[in] wcs				wcs data set
	\return pointer to internal memory or NULL if the name is undefined.
*/
	CMPACK_EXPORT(const char*, cmpack_wcs_get_name, (CmpackWcs* wcs));

/**
	\brief Get world coordinate axes name
	\details The function retrieves the parameters of the indicated world
	coordinate axis. The mask specifies field to be retrieved.
	\param[in] wcs				wcs data set
	\param[in] axis				axis (0=longitude, 1=latitude)
	\param[in] mask				which fields shall be retrieved
	\param[out] params			axis parameters
	\return zero on success, error code on failure
*/
	CMPACK_EXPORT(int, cmpack_wcs_get_axis_params, (CmpackWcs* wcs, int axis, unsigned mask,
		CmpackWcsAxisParams* params));

/**
	\brief Pixel-to-world transformation (single 2D vector)
	\details The function transforms single 2D vector of pixel coordinates to 
	the world coordinates.
	\param[in] wcs				wcs data set
	\param[in] x				image coordinate X
	\param[in] y				image coordinate Y
	\param[out] lng				world coordinate (e.g. right ascension)
	\param[out] lat				world coordinate (e.g. declination)
	\return zero on success, error code on failure
*/
	CMPACK_EXPORT(int, cmpack_wcs_p2w, (CmpackWcs* wcs, double x, double y, double* lng, double* lat));

/**
	\brief World-to-pixel transformation (single 2D vector)
	\details The function transforms single 2D vector of world coordinates to 
	the pixel coordinates.
	\param[in] wcs				wcs data set
	\param[in] lng				world coordinate (e.g. right ascension)
	\param[in] lat				world coordinate (e.g. declination)
	\param[out] x				image coordinate X
	\param[out] y				image coordinate Y
	\return zero on success, error code on failure
*/
	CMPACK_EXPORT(int, cmpack_wcs_w2p, (CmpackWcs* wcs, double lng, double lat, double* x, double* y));

/**
	\brief Get wcslib's version
	\details The function returns pointer to a null-terminated string that contains
	wcslib's version identifier. If the C-Munipack library was compiled without
	wcslib, the function returns NULL. The caller must not modify or free the string.
*/
	CMPACK_EXPORT(const char*, cmpack_wcs_version, (void));
	
#ifdef __cplusplus
}
#endif

#endif
