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

profile.h (C-Munipack project)
Environment options
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_PROFILE_H
#define MUNIWIN_PROFILE_H

#include "helper_classes.h"

// Project types
enum tProjectType {
	PROJECT_REDUCE,
	PROJECT_REDUCE_ALGND,
	PROJECT_MASTER_BIAS,
	PROJECT_MASTER_DARK,
	PROJECT_MASTER_FLAT,
	PROJECT_COMBINING,
	PROJECT_TEST,
	EndOfProjectTypes
};

// Printable name for given project type
const gchar *ProjectTypeCaption(tProjectType type);

// Icon name for given project type
const gchar *ProjectTypeIcon(tProjectType type);

// Project type to string identifier
const gchar *ProjectTypeToStr(tProjectType type);

// String identifier to project type
tProjectType StrToProjectType(const gchar *str);

// Project type to recent group
const gchar *ProjectTypeRecentGroup(tProjectType type);

// Initialize shared variables
void ProfilesInitGlobals(void);

// Release allocated memory in shared variables
void ProfilesFreeGlobals(void);

// Get path to the directory with user-defined profiles
const gchar *UserProfilesDir(void);

// Get list of user-defined profiles
// The list contains full paths to files. Call ProfileListFree
// to release memory allocated in the profile list.
GSList *GetProfileList(const gchar *dirpath);

// Get list of default profiles
// The list contains profile names. Call ProfileListFree
// to release memory allocated in the profile list.
GSList *DefaultProfileList(void);

// Free memory allocated in the profile list
void ProfileListFree(GSList *list);

//
// Profile - project settings
//
class CProfile
{
public:
	// Parameter identifiers
	enum tParameter
	{
		FLIP_V,
		FLIP_H,
		BINNING,
		TIME_OFFSET,
		BAD_PIXEL_VALUE,
		OVEREXPOSED_VALUE,
		WORK_FORMAT,
		ADVANCED_CALIBRATION,
		MBIAS_FORMAT,
		MDARK_FORMAT,
		MFLAT_LEVEL,
		MFLAT_FORMAT,
		KOMBINE_FORMAT,
		READ_NOISE,
		ADC_GAIN,
		DETECTION_FWHM,
		DETECTION_THRESHOLD,
		MIN_ROUNDNESS,
		MAX_ROUNDNESS,
		MIN_SHARPNESS,
		MAX_SHARPNESS,
		SKY_INNER_RADIUS,
		SKY_OUTER_RADIUS,
		MATCH_READ_STARS,
		MATCH_IDENT_STARS,
		MATCH_CLIP,
		SPARSE_FIELDS,
		MAX_OFFSET,
		VARFIND_THRESHOLD,
		MAX_STARS,
		DENSE_FIELDS,
		MATCH_CLIP2,
		POSITIVE_WEST,
		EndOfParameters
	};

	// Constructor
	CProfile();

	// Copy constructor
	CProfile(const CProfile &);

	// Destructor
	virtual ~CProfile();

	// Assigment operator
	CProfile &operator =(const CProfile&);

	// Enter critical section
	void Lock(void) const;

	// Leave critical section
	void Unlock(void) const;

	// Set all parameters to defaults
	void Clear();

	// Load profile from a file
	void Load(GKeyFile *file);

	// Save profile to a file
	void Save(GKeyFile *file) const;

	// Load profile from a file
	bool Import(const gchar *filepath, GError **error = NULL);

	// Save profile to a file
	bool Export(const gchar *filepath, GError **error = NULL) const;

	// Check if the file is a valid profile file and reads project type
	static bool isProfileFile(const gchar *filepath);

	// Set parameter value
	void SetStr(tParameter param, const gchar *val);
	void SetInt(tParameter param, const int val);
	void SetBool(tParameter param, bool val);
	void SetDbl(tParameter param, double val);

	// Get parameter value
	gchar *GetStr(tParameter param) const;
	int GetInt(tParameter param) const;
	bool GetBool(tParameter param) const;
	double GetDbl(tParameter param) const;
	
	// Convenience function for complex data types
	tProjectType ProjectType(void) const;
	void SetProjectType(tProjectType type);
	CApertures Apertures(void) const;
	void SetApertures(const CApertures &aper);
	CmpackBorder GetBorder(void) const;
	void SetBorder(const CmpackBorder &border);
	CLocation DefaultLocation(void) const;
	void SetDefaultLocation(const CLocation &loc);

	// Read default value for given parameter
	static bool GetDefaultBool(tParameter param);
	static int GetDefaultInt(tParameter param);
	static const gchar *GetDefaultStr(tParameter param);
	static double GetDefaultDbl(tParameter param);
	static CApertures DefaultApertures(void);

	// Get limits for given parameter
	static void GetLimitsInt(tParameter param, int *min, int *max);
	static void GetLimitsDbl(tParameter param, double *min, double *max);
	static int BoundInt(tParameter param, int value);
	static double BoundDbl(tParameter param, double value);
	static void GetApertureSizeLimits(double *min, double *max);
	static void GetBorderSizeLimits(int *min, int *max);

	// Get default profile
	static CProfile DefaultProfile(const gchar *name);

private:
	GKeyFile *m_File;

	void SetStr(const char *group, const char *key, const char *val);
	void SetDbl(const char *group, const char *key, const double val);
	void SetInt(const char *group, const char *key, const int val);
	void SetBool(const char *group, const char *key, bool val);

	bool TryGetStr(const char *group, const char *key, char **value) const;
	bool TryGetDbl(const char *group, const char *key, double *value) const;
	bool TryGetInt(const char *group, const char *key, int *value) const;
	bool TryGetBool(const char *group, const char *key, bool *value) const;

	char *GetStr(const char *group, const char *key, const char *defval = "") const;

	static bool isProfileFile(GKeyFile *file);

	// Returns true if the section belongs to profile
	static bool IsProfileGroup(const gchar *group);
};

#endif
