/**
	\file
	\brief Functions for making photometry files.

	Set of functions defined in this module allows user to 
	make a photometry file from a CCD frame.
	
	\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_phot.h,v 1.2 2015/09/12 10:49:06 dmotl Exp $
*/
#ifndef _CMPACK_PHOT_H_INCLUDED
#define _CMPACK_PHOT_H_INCLUDED

#include "cmpack_common.h"
#include "cmpack_console.h"
#include "cmpack_ccdfile.h"
#include "cmpack_phtfile.h"

/********************   Private data structures   ********************************/

/**
	\brief Configuration context for the Photometry tool
	\details This private data structure holds the configuration parameters
	for the photometry.
*/
typedef struct _CmpackPhot CmpackPhot;

/**	\brief Frame property flags */
typedef enum _CmpackPhotInfoMask
{
	CMPACK_PHI_XY = (1 << 0),	/**< Fields: center_x, center_y, max_x, max_y */
} CmpackPhotInfoMask;

/**	\brief Object properties */
typedef struct _CmpackPhotObject
{
	double center_x;							/**< Center - X coordinate */
	double center_y;							/**< Center - Y coordinate */
	int max_x;									/**< Maximum pixel - X coordinate */ 
	int max_y;									/**< Maximum pixel - Y coordinate */
} CmpackPhotObject;

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

#ifdef __cplusplus
extern "C" {
#endif

/**
	\brief Make new photometry context
	\details The function allocates memory with photometry context and returns a 
	new reference to it. The reference counter is set to one. The caller is 
	responsible to call cmpack_phot_destroy() when it is no longer needed.
	\return pointer to a new reference
*/
	CMPACK_EXPORT(CmpackPhot*, cmpack_phot_init, (void));

/**
	\brief Make a new reference to the photometry context
	\details The function makes a new reference to the context and returns a 
	pointer to it. The reference counter is incremented by one. The caller 
	is responsible to call cmpack_phot_destroy() when the reference is 
	no longer needed.
	\return pointer to a new reference
*/
	CMPACK_EXPORT(CmpackPhot*, cmpack_phot_reference, (CmpackPhot* ctx));

/**
	\brief Release a reference to the photometry context
	\details The function releases a reference to the context. 
	The reference counter is decreased by one and when it was the 
	last reference to the context, the context is freed and all memory 
	allocated in the context is reclaimed.
*/
	CMPACK_EXPORT(void, cmpack_phot_destroy, (CmpackPhot* ctx));

/**
	\brief Attach console to the context
	\details Increment console's reference counter. Only one console can
	be attached to a single context. If another console is attached, by
	calling this function detaches it. Set console to NULL to detach
	the current console.
	\param[in] ctx			photometry context
	\param[in] con			console context
*/
	CMPACK_EXPORT(void, cmpack_phot_set_console, (CmpackPhot* ctx, CmpackConsole* con));

/**
	\brief Set readout noise level
	\param[in] ctx			photometry context
	\param[in] rnoise		readout noise
*/
	CMPACK_EXPORT(void, cmpack_phot_set_rnoise, (CmpackPhot* ctx, double rnoise));

/**
	\brief Get readout noise level
	\param[in] file			output file context
	\return current value of readout noise level
*/
	CMPACK_EXPORT(double, cmpack_phot_get_rnoise, (CmpackPhot* file));

/**
	\brief Set ADC gain
	\param[in] file			output file context
	\param[in] adcgain		ADC gain
*/
	CMPACK_EXPORT(void, cmpack_phot_set_adcgain, (CmpackPhot* file, double adcgain));

/**
	\brief Get ADC gain
	\param[in] file			output file context
	\return current ADC gain
*/
	CMPACK_EXPORT(double, cmpack_phot_get_adcgain, (CmpackPhot* file));

/**
	\brief Set threshold for bad pixels
	\param[in] file			output file context
	\param[in] minval		minimal valid value in ADU
*/
	CMPACK_EXPORT(void, cmpack_phot_set_minval, (CmpackPhot* file, double minval));

/**
	\brief Get threshold for bad pixels
	\param[in] file			output file context
	\return minimal valid value in ADU
*/
	CMPACK_EXPORT(double, cmpack_phot_get_minval, (CmpackPhot* file));

/**
	\brief Set threshold for overexposed pixels
	\param[in] file			output file context
	\param[in] maxval		maximal valid value in ADU + 1
*/
	CMPACK_EXPORT(void, cmpack_phot_set_maxval, (CmpackPhot* file, double maxval));

/**
	\brief Get threshold for overexposed pixels
	\param[in] file			output file context
	\return current value of threshold for overexposed pixels
*/
	CMPACK_EXPORT(double, cmpack_phot_get_maxval, (CmpackPhot* file));

/**
	\brief Set expected value of FWHM of objects
	\param[in] file			output file context
	\param[in] fwhm			FWHM in pixels
*/
	CMPACK_EXPORT(void, cmpack_phot_set_fwhm, (CmpackPhot* file, double fwhm));

/**
	\brief Get expected value of FWHM of objects
	\param[in] file			output file context
	\return FWHM in pixels
*/
	CMPACK_EXPORT(double, cmpack_phot_get_fwhm, (CmpackPhot* file));

/**
	\brief Set detection threshold
	\param[in] file			output file context
	\param[in] thresh		threshold
*/
	CMPACK_EXPORT(void, cmpack_phot_set_thresh, (CmpackPhot* file, double thresh));

/**
	\brief Get detection threshold
	\param[in] file			output file context
	\return threshold
*/
	CMPACK_EXPORT(double, cmpack_phot_get_thresh, (CmpackPhot* file));

/**
	\brief Set min. sharpness threshold
	\param[in] file			output file context
	\param[in] minshrp		threshold
*/
	CMPACK_EXPORT(void, cmpack_phot_set_minshrp, (CmpackPhot* file, double minshrp));

/**
	\brief Get min. sharpness threshold
	\param[in] file			output file context
	\return current value of min. sharpness threshold
*/
	CMPACK_EXPORT(double, cmpack_phot_get_minshrp, (CmpackPhot* file));

/**
	\brief Set max. sharpness threshold
	\param[in] file			output file context
	\param[in] maxshrp		threshold
*/
	CMPACK_EXPORT(void, cmpack_phot_set_maxshrp, (CmpackPhot* file, double maxshrp));

/**
	\brief Get max. sharpness threshold
	\param[in] file			output file context
	\return current value of max. sharpness threshold
*/
	CMPACK_EXPORT(double, cmpack_phot_get_maxshrp, (CmpackPhot* file));

/**
	\brief Set min. roundness threshold
	\param[in] file			output file context
	\param[in] minrnd		threshold
*/
	CMPACK_EXPORT(void, cmpack_phot_set_minrnd, (CmpackPhot* file, double minrnd));

/**
	\brief Get min. roundness threshold
	\param[in] file			output file context
	\return current value of min. roundness threshold
*/
	CMPACK_EXPORT(double, cmpack_phot_get_minrnd, (CmpackPhot* file));

/**
	\brief Set max. roundness threshold
	\param[in] file			output file context
	\param[in] maxrnd		threshold
*/
	CMPACK_EXPORT(void, cmpack_phot_set_maxrnd, (CmpackPhot* file, double maxrnd));

/**
	\brief Get max. roundness threshold
	\param[in] file			output file context
	\return current value of max. roundness threshold
*/
	CMPACK_EXPORT(double, cmpack_phot_get_maxrnd, (CmpackPhot* file));

/**
	\brief Set image border size
	\details If you set the border to nonzero size, the conversion function
	will set the pixels which belongs to the border area to zero. You can use
	this feature to clear an unusable part of a frame.
	\param[in] file			conversion context
	\param[in] border		border size in pixels
*/
	CMPACK_EXPORT(void, cmpack_phot_set_border, (CmpackPhot* file, const CmpackBorder* border));

/**
	\brief Get image flip flags
	\param[in] file			conversion context
	\param[out] border		border size in pixels
*/
	CMPACK_EXPORT(void, cmpack_phot_get_border, (CmpackPhot* file, CmpackBorder* border));

/**
	\brief Set inner radius of the sky annulus
	\param[in] file			output file context
	\param[in] skyin		radius in pixels
*/
	CMPACK_EXPORT(void, cmpack_phot_set_skyin, (CmpackPhot* file, double skyin));

/**
	\brief Get inner radius of the sky annulus
	\param[in] file			output file context
	\return current value of inner radius of the sky annulus
*/
	CMPACK_EXPORT(double, cmpack_phot_get_skyin, (CmpackPhot* file));

/**
	\brief Set outer radius of the sky annulus
	\param[in] file			output file context
	\param[in] skyout		radius in pixels
*/
	CMPACK_EXPORT(void, cmpack_phot_set_skyout, (CmpackPhot* file, double skyout));

/**
	\brief Get outer radius of the sky annulus
	\param[in] file			output file context
	\return current value of outer radius of the sky annulus
*/
	CMPACK_EXPORT(double, cmpack_phot_get_skyout, (CmpackPhot* file));

/**
	\brief Set apertures
	\param[in] file			output file context
	\param[in] items		table of aperture radii
	\param[in] nitems		number of apertures
*/
	CMPACK_EXPORT(void, cmpack_phot_set_aper, (CmpackPhot* file, const double* items, int nitems));

/**
	\brief Get apertures
	\details The function makes copy of the data and returns the pointer
	to it. The caller is reponsible to free the memory by means of the
	cmpack_free() method.
	\param[in] file			output file context
	\param[out] items		table of aperture radii
	\param[out] nitems		number of apertures
*/
	CMPACK_EXPORT(void, cmpack_phot_get_aper, (CmpackPhot* file, double** items, int* nitems));

/**
	\brief Set limit on number of objects
	\param[in] file			output file context
	\param[in] maxstar		max. number of objects
*/
	CMPACK_EXPORT(void, cmpack_phot_set_limit, (CmpackPhot* file, int maxstar));

/**
	\brief Make photometry file from a calibrated CCD frame
	\details The function reads input frame, finds stars and determine their
	brightness. The result is stored in the photometry file.
	\param[in] ctx			photometry configuration context
	\param[in] infile		input file context
	\param[in] outfile		output file context
	\param[out] nstars		number of stars detected
	\return zero on success or error code on failure
*/
	CMPACK_EXPORT(int, cmpack_phot, (CmpackPhot* ctx, CmpackCcdFile* infile, CmpackPhtFile* outfile, int* nstars));

/**
	\brief Reads a calibrated CCD frame and prepare it for star detection
	\details The function reads input frame and initializes the internal variables. The 
	process stops before star detection.
	\param[in] ctx			photometry configuration context
	\param[in] infile		input file context
	\return zero on success or error code on failure
*/
	CMPACK_EXPORT(int, cmpack_phot_read, (CmpackPhot* ctx, CmpackCcdFile* infile));

/**
	\brief Find an object nearest to the specified position on a source frame
	and returns its coordinates. The function is used to find a local maximum
	when objects are specified manually by mouse clicking.
	\param[in] ctx			photometry configuration context
	\param[in, out] x		origin X coordinate, centroid X, coordinate
	\param[in, out] y		origin Y coordinate, centroid Y, coordinate
	\
	\return zero on success or error code on failure
*/
	CMPACK_EXPORT(int, cmpack_phot_pos, (CmpackPhot* ctx, double* x, double* y));

/**
	\brief Detect objects on a source frame. The function is used to detect
	objects on a frame without measuring them. List of detected objects is
	stored internally and a pointer is set to a first object. The function
	returns zero if any object was found, or non-zero value otherwise. After
	successfull call to "find_first", you call "get_data" to retrieve properties
	of the current object and "find_next" to move to the next record. When you
	have finished enumeration of the objects, you should call "find_close" 
	to release the allocated memory.
	\param[in] ctx			photometry configuration context
	\return zero on success or error code on failure
*/
	CMPACK_EXPORT(int, cmpack_phot_find_first, (CmpackPhot* ctx));

/**
	\brief Get properties of a current object. You have to call "find_first" and
	"find_next" functions before calling this function.
	\param[in] ctx			photometry configuration context
	\param[in] flags		which fields to read
	\param[in] data			object properties
	\return zero on success or error code on failure
*/
	CMPACK_EXPORT(int, cmpack_phot_get_data, (CmpackPhot* ctx, unsigned flags, CmpackPhotObject* data));

/**
	\brief Move pointer to the next object. This function is used in conjunction
	with "find_first" and "get_data" to enumerate detected objects. The function 
	returns zero if the context now points to a valid object or a nonzero value
	if the pointer passed beyond the end of the list.
	\param[in] ctx			photometry configuration context
	\return zero on success or error code on failure
*/
	CMPACK_EXPORT(int, cmpack_phot_find_next, (CmpackPhot* ctx));

/**
	\brief Clear a list of objects and release an allocated memory. The function clears
	the list of objects detected by "find_first" function. Calling this function
	is not mandatory, the list is cleared when the context is destroyed or by calling
	"read" and "find_first" functions.
	\param[in] ctx			photometry configuration context
*/
	CMPACK_EXPORT(void, cmpack_phot_find_close, (CmpackPhot* ctx));

/**
	\brief Turn detection of objects on and off. If the property is set to non-zero value, the 
	photometry will use a user-defined objects and runs an aperture photometry for specified positions.
	If the property value is set to zero, the process detects objects and runs the aperture photometry for
	them. The default value is zero.
	\param[in] ctx			photometry configuration context
	\param[in] value		new property value
*/
	CMPACK_EXPORT(void, cmpack_phot_set_use_object_list, (CmpackPhot* ctx, int value));

/**
	\brief Set the list of objects. To have an effect, you have to set the "use_object_list" property
	to non-zero value. The function replaces the previous list. The caller has to fill the center_x and center_y
	fields, other fields are ignored.
	\param[in] ctx			photometry configuration context
	\param[in] length		number of objects, size of the 'list' array
	\param[in] list			list of objects
*/
	CMPACK_EXPORT(void, cmpack_phot_set_object_list, (CmpackPhot* ctx, int length, const CmpackPhotObject* list));

#ifdef __cplusplus
}
#endif

#endif
