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

phot_class.h (C-Munipack project)
Photometry file class interface
Copyright (C) 2011 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 MUNIWIN_PHOT_CLASS_H
#define MUNIWIN_PHOT_CLASS_H

#include "helper_classes.h"
#include "file_classes.h"

//
// Photometry file class
//
class CPhot
{
public:
	// Export flags
	enum tExportFlags {
		EXPORT_SKIP_INVALID		= (1<<0),
		EXPORT_SKIP_UNMATCHED	= (1<<1),
		EXPORT_NO_HEADER		= (1<<2)
	};

	// Table columns (also sorting columns)
	enum tColumnId {
		COL_ID, COL_REF_ID, COL_POS_X, COL_POS_Y, COL_WCS_VALID, COL_WCS_LNG, COL_WCS_LAT, 
		COL_FWHM, COL_SKY, COL_SKY_DEV, COL_MAG_VALID, COL_MAG, COL_MAG_ERR, COL_CODE, 
		COL_REMARKS, COL_COUNT
	};

	// Additional columns for sorting
	enum tSortColumnId {
		SORT_INT = COL_COUNT, SORT_NOISE, SORT_SNR
	};

	// Constructor(s)
	CPhot():m_Handle(NULL), m_CacheFlags(0), m_CurrentAperture(-1), m_RefMag(0), 
		m_Path(NULL), m_Filter(NULL), m_Wcs(NULL) {}
	explicit CPhot(CmpackPhtFile *handle);
	
	// Destructor
	virtual ~CPhot();

	// Load photometry file
	// The function opens a file, makes internal copy and closes it.
	bool Load(const gchar *fpath, GError **error = NULL);

	// Save photometry a file
	bool SaveAs(const gchar *fpath, GError **error = NULL) const;

	// Make deep copy from a photometry file
	bool MakeCopy(const CPhot &pht, GError **error = NULL);

	// Release internal data
	void Clear();

	// Is the object valid?
	bool Valid(void) const
	{ return m_Handle!=NULL; }

	// File path
	const gchar *Path(void) const { return m_Path; }

	// Date of observation
	bool DateTime(CmpackDateTime *dt) const;
	double JulianDate(void) const;

	// Exposure duration
	double ExposureDuration(void) const;

	// Optical filter
	const gchar *Filter(void);

	// Has the file been matched?
	bool Matched(void) const;

	// Number of apertures
	int ApertureCount(void) const;

	// Find aperture
	int FindAperture(int id) const;

	// Get table of apertures
	const CApertures *Apertures(void);

	// Set current aperture
	void SelectAperture(int apertureIndex);

	// Get index of selected aperture
	int SelectedAperture(void) const { return m_CurrentAperture; }

	// Number of stars
	int ObjectCount(void) const;

	// Find object
	int FindObject(int id);

	// Find object by reference identifier
	int FindObjectRefID(int ref_id);

	// Get star identifier
	int GetObjectID(int star_index);

	// Get reference indentifier
	int GetObjectRefID(int star_index);

	// Get position of a star
	bool GetObjectPos(int star_index, double *x, double *y);

	// Get star attributes
	bool GetObjectParams(int star_index, unsigned mask, CmpackPhtObject *obj);

	// Get measurement
	bool GetMagnitude(int star_index, double *mag, double *err);

	// Get measurement with a code indicating a reason why the brightness is not valid
	bool GetMagnitudeAndCode(int star_index, CmpackPhtData &res, CmpackError &code);

	// Make chart data
	CmpackChartData *ToChartData(bool gray_not_matched, bool transparent = false);

	// Make table model
	GtkTreeModel *ToTreeModel(void);

	// Set view parameters
	void SetView(GtkTreeView *view);

	// Export table of objects
	bool ExportTable(const gchar *filepath, const gchar *format, unsigned flags, int sort_column_id,
		GtkSortType sort_order, GError **error);

	// Export file header
	bool ExportHeader(const gchar *filepath, const gchar *format, unsigned flags, GError **error) const;

	// Get header field by index
	bool GetParams(unsigned mask, CmpackPhtInfo &info) const;

	// Get WCS data
	CWcs *Wcs(void);

	// Translate object result code into a printable string
	// The caller is responsible to free the buffer using the g_free procedure.
	static gchar *CodeToString(int code);

protected:
	friend class CFrameSet;
	friend class CCatalog;

	enum tCacheFlags {
		CF_APERTURES	= (1<<0),
		CF_REFMAG		= (1<<1),
		CF_FILTER		= (1<<2),
		CF_WCS			= (1<<3)
	};

	CmpackPhtFile	*m_Handle;
	int				m_CacheFlags;
	CApertures		m_Apertures;
	int				m_CurrentAperture;
	double			m_RefMag;
	gchar			*m_Path, *m_Filter;
	CWcs			*m_Wcs;

	// Compute reference magnitude for given aperture
	double GetRefMag(void);

	// Refresh cached data
	void InvalidateCache(void);

private:
	// Disable copy constructor and assigment operator
	CPhot(const CPhot&);
	CPhot &operator=(const CPhot &orig);

	void ExportTable(CCSVWriter &file, unsigned flags, int sort_column_id, GtkSortType sort_order);
	void ExportHeader(CCSVWriter &file, unsigned flags) const;
	void ExportHeaderItem(CCSVWriter &file, const gchar *keyword, const gchar *value, const gchar *comment) const;
	void ExportHeaderItem(CCSVWriter &file, const gchar *keyword, int value, const gchar *comment) const;
	void ExportHeaderItem(CCSVWriter &file, const gchar *keyword, double value, int prec, const gchar *comment) const;
};

#endif
