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

ccdfile_class.h (C-Munipack project)
CCD image 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_CCDFILE_CLASS_H
#define MUNIWIN_CCDFILE_CLASS_H

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

//
// CCD file class
//
class CCCDFile
{
public:
	// Export flags
	enum tExportFlags {
		EXPORT_NO_HEADER		= (1<<0)
	};

	// Constructor
	CCCDFile(void);

	// Destructor
	virtual ~CCCDFile();

	// Load data from a file
	bool Open(const gchar *fpath, CmpackOpenMode mode, GError **error = NULL);

	// Make deep copy of another image file
	bool MakeCopy(const CCCDFile &file, GError **error = NULL);

	// Save CCD file as...
	bool SaveAs(const gchar *fpath, GError **error = NULL);

	// Free internal data
	bool Close(GError **error = NULL);

	// Get image data in specified format
	CImage *GetImageData(CmpackBitpix bitpix = CMPACK_BITPIX_AUTO, GError **error = NULL);

	// Set image data
	bool SetImageData(const CImage &img, GError **error = NULL);

	// Get format identifier
	CmpackFormat FileFormat(void) const;

	// Get image depth identifier
	CmpackBitpix Depth(void) const;

	// Check the format the file
	// Returns true if the file is in standard working format
	bool isWorkingFormat(void) const;

	// Get header field by index
	bool GetParam(int index, char **key, char **val, char **com) const;

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

	CmpackCcdFile *Handle(void) const
	{ return m_Handle; }

	// Image width in pixels
	int Width(void) const;
	
	// Image height in pixels
	int Height(void) const;

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

	// File format identifier (magic string)
	const gchar *Magic(void);

	// Filter name
	const gchar *Filter(void);

	// Object name and coordinates
	const CObjectCoords *Object(void);

	// Oberver's name
	const gchar *Observer(void);

	// Acquisition telescope designation
	const gchar *Telescope(void);

	// Acquisition instrument designation
	const gchar *Instrument(void);

	// Observer's location and coordinates
	const CLocation *Location(void);

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

	// Exposure duration
	double ExposureDuration(void) const;

	// CCD temperature
	double CCDTemperature(void) const;

	// Number of averaged frames
	int AvgFrames(void);

	// Number of summed frames
	int SumFrames(void);

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

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

	// True if the file with external WCS data exists
	bool hasExternalWcs(void) const;

	// Returns handle of the external file with WCS data
	CCCDFile *openExternalWcs(GError **error = NULL) const;

protected:
	enum tCacheFlags
	{
		CF_FORMATNAME	= (1<<0),
		CF_OBJECT		= (1<<1),
		CF_OBSERVER		= (1<<2),
		CF_LOCATION		= (1<<3),
		CF_FILTER		= (1<<4),
		CF_SUBFRAMES	= (1<<5),
		CF_TELESCOPE	= (1<<6),
		CF_INSTRUMENT	= (1<<7),
		CF_WCS			= (1<<8)
	};

	CmpackCcdFile	*m_Handle;
	unsigned		m_CacheFlags;
	CObjectCoords	m_Object;
	CLocation		m_Location;
	gchar			*m_Path, *m_Filter, *m_FormatName;
	int				m_AvgFrames, m_SumFrames;
	gchar			*m_Observer, *m_Telescope, *m_Instrument;
	CWcs			*m_Wcs;

	// Invalidate cached data
	void InvalidateCache(void);

	// Export header
	void ExportHeader(CCSVWriter &file, unsigned flags) const;

	// Returns path to the external file with WCS data
	gchar *externalWcsPath(void) const;

private:
	// Disable copy constructor and assigment operator
	CCCDFile(const CCCDFile&);
	CCCDFile &operator=(const CCCDFile &);
};

#endif
