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

project_dlg.h (C-Munipack project)
Project settions dialog
Copyright (C) 2012 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 CMPACK_PROFILE_WIDGET_H
#define CMPACK_PROFILE_WIDGET_H

#include <gtk/gtk.h>

#include "profile.h"
#include "utils.h"

// Section identifiers
enum tProfilePageId {
	PAGE_PROFILE,
	PAGE_PROJECT,
	PAGE_FILES,
	PAGE_CAMERA,
	PAGE_SOURCE_FILES,
	PAGE_CALIBRATION,
	PAGE_STAR_DETECTION,
	PAGE_PHOTOMETRY,
	PAGE_MATCHING,
	PAGE_MASTER_BIAS,
	PAGE_MASTER_DARK,
	PAGE_MASTER_FLAT,
	PAGE_MERGE_FRAMES,
	PAGE_FIND_VARIABLES,
	PAGE_OBSERVER,
	EndOfProfilePages
};

class CEditProfileBase
{
public:
	struct tStringList
	{
		const char *str;			// Caption (NULL = terminator)
		int id;						// Value, bitmask
	};

	CEditProfileBase(void);
	virtual ~CEditProfileBase();

	void SetInitialPage(tProfilePageId id) { m_lastPageId = id; }
	tProfilePageId GetLastPage(void) const { return m_lastPageId; }
	GtkRequisition GetSizeRequest(void);
	GtkWidget *GetHandle(void) { return m_pBox; }
	CProfile *Profile(void) { return &m_Profile; }

protected:
	struct tStackItem
	{
		int level;
		GtkTreePath *item;
		tStackItem(int l, GtkTreePath *i):level(l), item(i) {}
		~tStackItem(void) { if (item) gtk_tree_path_free(item); }
		static void Release(tStackItem *pMe) { delete pMe; }
	};

	typedef const gchar *(*AddComboFn)(int);

	GtkWidget		*m_pBox, *m_PageFrame, *m_TitleFrame, *m_PageTitle, *m_Separator;
	GtkWidget		*m_CurrentPage, *m_PageView, *m_PageScroller;
	GtkWidget		*m_WorkFormat, *m_DataMin, *m_DataMax, *m_Binning, *m_FlipV, *m_FlipH;
	GtkWidget		*m_BLeft, *m_BRight, *m_BTop, *m_BBottom, *m_TimeOffset;
	GtkWidget		*m_StdCalibration, *m_AdvCalibration, *m_MBiasFormat, *m_MDarkFormat;
	GtkWidget		*m_VarFindThreshold, *m_MFlatFormat, *m_MFlatLevel, *m_KombineFormat;
	GtkWidget		*m_RNoise, *m_ADCGain, *m_FWHM, *m_Thresh;
	GtkWidget		*m_SharpMin, *m_SharpMax, *m_RoundMin, *m_RoundMax;
	GtkWidget		*m_Aperture[MAX_APERTURES], *m_SkyIn, *m_SkyOut, *m_MaxStar;
	GtkWidget		*m_MatchStandard, *m_MatchSparse, *m_MatchBox1, *m_MatchBox2, *m_MatchBox3;
	GtkWidget		*m_MatchRS, *m_MatchIS, *m_MatchClip, *m_MatchMax, *m_MatchPhiLnR, *m_MatchClip2;
	GtkWidget		*m_LocName, *m_LocBtn, *m_Lon, *m_Lat;
	GtkTreeStore	*m_PageList;
	GtkTreeModel	*m_FilteredPageList;
	CProfile		m_Profile;
	bool			m_ReadOnly, m_Updating, m_Changed;
	tProfilePageId	m_currentPageId, m_lastPageId;
	GtkRequisition	m_SizeRequest;

	GtkWidget *CreatePage(tProfilePageId id, int indent, const gchar *caption, 
		const gchar *icon, bool def_btn, GSList **stack);
	void SetPageTitle(tProfilePageId id, const gchar *caption);

	void SetProfile(const CProfile &profile, bool readOnly);
	void SetReadOnly(bool readOnly);

	virtual GtkWidget *DialogWidget(void) = 0;
	virtual void CreatePages(GSList **stack);
	virtual void SetData(void);
	virtual void GetData(void);
	virtual bool CheckPage(tProfilePageId pageId, GError **error);
	virtual bool IsPageVisible(tProfilePageId pageId);
	virtual bool CheckProfile(GError **error);
	virtual tProjectType projectType() const = 0;

	virtual void OnPageChanged(tProfilePageId currentPage, tProfilePageId previousPage) {}
	virtual void OnEntryChanged(GtkEditable *editable);
	virtual void OnButtonClicked(GtkWidget *pWidget);
	virtual void OnButtonToggled(GtkWidget *pWidget);
	virtual void OnComboBoxChanged(GtkWidget *pWidget) {}
	virtual void OnSetDefaultsClicked(GtkWidget *pWidget);

	void PreparePages(void);
	void UpdateControls(void);
	void ShowPage(tProfilePageId id);

	static GtkWidget *new_label(const gchar *text, gfloat xalign = 0);
	static GtkWidget *add_label(GtkTable *tbox, gint row, const gchar *text);
	static GtkWidget *add_button_box(GtkTable *tbox, int top);
	GtkWidget *add_entry(GtkTable *tbox, gint row, const gchar *caption,
		gint maxlen, const gchar *tooltip);
	GtkWidget *add_push_button(GtkTable *tbox, gint row, const gchar *label,
		const gchar *tooltip);
	static GtkWidget *add_static(GtkTable *tbox, gint row, const gchar *caption,
		PangoEllipsizeMode ellipsize, const gchar *tooltip);
	GtkWidget *add_spin_button(GtkTable *tbox, int left, int top,
		double dmin, double dmax, double step, int digits, const gchar *tooltip);
	GtkWidget *add_spin_button_dbl(GtkTable *tbox, int top, const gchar *caption,
		CProfile::tParameter p, double step, int digits, const gchar *tooltip);
	GtkWidget *add_spin_button_int(GtkTable *tbox, int top, const gchar *caption,
		CProfile::tParameter p, int step, const gchar *tooltip);
	GtkWidget *add_combo_box(GtkTable *tbox, int top, const gchar *caption,
		const tStringList *strings, const gchar *tooltip);
	GtkWidget *add_combo_box(GtkTable *tbox, int top, const gchar *caption,
		const tProjectType *types, const gchar *tooltip);
	GtkWidget *add_radio_btn(GtkTable *tbox, int top, const gchar *caption,
		GSList **group, const gchar *tooltip);
	GtkWidget *add_check_btn(GtkTable *tbox, int top, const gchar *caption,
		const gchar *tooltip);
			
	static const tProjectType *projectTypes();
	static void select_project_type(GtkWidget *cbx, tProjectType type);
	static tProjectType combo_box_project_type(GtkWidget *cbx);

	static tProfilePageId str_to_page(const char *str, tProfilePageId defaultValue);
	static const char *page_to_str(tProfilePageId page);

	static void button_clicked(GtkWidget *widget, CEditProfileBase *pDlg);
	static void combo_box_changed(GtkWidget *widget, CEditProfileBase *pDlg);
	static void button_toggled(GtkWidget *widget, CEditProfileBase *pDlg);
	static void entry_changed(GtkEditable *editable, CEditProfileBase *pDlg);

private:
	struct tFindData
	{
		int page_id;
		GtkTreePath *path;
		tFindData(int page):page_id(page), path(NULL) {}
	};

	void EditLocation(void);
	void OnTreeSelectionChanged(void);

	static gboolean max_dialog_size(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, GtkRequisition *data);
	static gint tree_selection_changed(GtkTreeSelection *selection, CEditProfileBase *pMe);
	static void setdefaults_clicked(GtkWidget *widget, CEditProfileBase *pMe);
	static gboolean page_visible(GtkTreeModel *model, GtkTreeIter *iter, CEditProfileBase *pMe);
	static gboolean find_page_proc(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, tFindData *data);
};

#endif
