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

varcat.h (C-Munipack project)
Catalogs of variable stars
Copyright (C) 2010 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_VARFIND_H
#define MUNIWIN_VARFIND_H

#include <gtk/gtk.h>

#include "callback.h"
#include "cmpack_widgets.h"
#include "table_class.h"
#include "phot_class.h"
#include "catfile_class.h"
#include "image_class.h"
#include "progress_dlg.h"
#include "popup.h"

class CVarFind:public CCBObject
{
public:
	// Message codes
	enum tMessageCode {
		CB_APERTURE_CHANGED,
		CB_COMPARISON_CHANGED,
		CB_VARIABLE_CHANGED,
		CB_ENABLE_CTRL_QUERY,
		CB_SHOW_FRAME_PREVIEW,
		CB_SHOW_FRAME_INFO,
		CB_REMOVE_FRAMES_FROM_DATASET,
		CB_DELETE_FRAMES_FROM_PROJECT,
		CB_REMOVE_OBJECTS_FROM_DATASET,
		CB_OBJECT_VALID_QUERY,
		CB_UPDATE_STATUS
	};

	// Control identifiers
	enum tControlId
	{
		ID_SAVE_CHART,
		ID_SHOW_FRAME_PREVIEW,
		ID_SHOW_FRAME_INFO,
		ID_REMOVE_FROM_DATASET,
		ID_DELETE_FROM_PROJECT
	};

	// Display modes
	enum tDisplayMode
	{
		DISPLAY_IMAGE,
		DISPLAY_CHART,
		DISPLAY_MIXED
	};

	// Mouse position
	enum tMousePos
	{
		MOUSE_OTHER,
		MOUSE_ON_LCURVE,
		MOUSE_ON_MDCURVE,
		MOUSE_ON_CHART
	};

	CVarFind(void);
	virtual ~CVarFind();

	GtkWidget *Handle(void)
	{ return m_Box; }

	tDisplayMode DisplayMode(void) const
	{ return m_DisplayMode; }

	bool TagsVisible(void) const
	{ return m_VSTags; }

	CmpackGraphData *LightCurveData(void) const
	{ return m_LCData; }

	CmpackGraphData *MagDevCurveData(void) const
	{ return m_MDData; }

	int ApertureId(void) const;

	const CAperture *Aperture(void) const
	{ return m_Aper.Get(m_ApertureIndex); }

	int ApertureIndex(void) const
	{ return m_ApertureIndex; }
	
	// List of selected objects - variable star, comparison star(s)
	CSelection GetSelection(void) const;
	void SetSelection(const CSelection &objs) { SetSelection(-1, objs); }

	// List of row indices of selected rows
	GList *GetSelectedFrames(void) const;

	// List of column indices of selected objects
	GList *GetSelectedObjects(void) const;

	int SelectedFrameID(void) const;
	
	void SetDisplayMode(tDisplayMode mode);
	void SetTagsVisible(bool visible);
	void SetImage(CImage *img);
	void SetPhotometryFile(GtkWindow *parent, CPhot *phot);
	void SetCatalogFile(GtkWindow *parent, CCatalog *file);
	void SetApertures(const CApertures &aper, int defaultApertureId);
	void SetSelectionList(CSelectionList *list);
	void SetMagDev(const CTable &tab);
	void SetLightCurve(const CTable &tab);
	void SetFixedJDRange(double jdmin, double jdmax);
	void SetFixedMagRange(double magrange);

	void ExportChart(void);
	void SaveLightCurve(void);
	void SaveMagDevCurve(void);
	void ExportLightCurve(void);
	void ExportMagDevCurve(void);

	void UpdateChart(void);

private:
	// Object selection mode
	enum tSelectMode
	{
		SELECT_VARIABLE,
		SELECT_COMPARISON,
		ADD_COMPARISON,
		REMOVE_COMPARISON
	};

	// Mag scale modes
	enum tMagScaleMode
	{
		MAG_SCALE_VAR,
		MAG_SCALE_FIXED,
		MAG_SCALE_CUSTOM
	};

	struct tCustomColor 
	{
		double red;
		double green;
		double blue;
	};

	struct tCatalogSet 
	{
		GtkWidget		*chkButton;
		GtkWidget		*setButton;
		GtkWidget		*icon;
		bool			enabled, show;
		int				layerId;
		tCustomColor	color;
		GSList			*obj_list;
	};

	GtkWidget		*m_Box, *m_MDView, *m_LCView, *m_Chart, *m_SelectCbx, *m_MultiComp, *m_SaveBtn, *m_RemoveBtn;
	GtkToolItem		*m_SelectVar, *m_SelectComp, *m_AddComp, *m_RemoveComp, *m_GoBack, *m_GoForward;
	GtkWidget		*m_AperLabel, *m_AperCombo, *m_CatalogsLabel;
	GtkWidget		*m_XLabel, *m_XCombo, *m_YLabel, *m_YCombo, *m_MagScale;
	GtkListStore	*m_XChannels, *m_Apertures, *m_Selections, *m_YModes;
	CmpackChartData	*m_ChartData;
	CmpackImageData	*m_ImageData;
	CmpackGraphData	*m_MDData, *m_LCData;
	CApertures		m_Aper;
	CImage			*m_Image;
	CPhot			*m_Phot;
	CCatalog		*m_Catalog;
	CWcs			*m_Wcs;
	CTable			m_LCurve, m_MagDev;
	int				m_ApertureIndex, m_MDChannelX, m_MDChannelY, m_LCChannelX, m_LCChannelY;
	int				m_Variable, m_VarIndex, m_VarIndex2;
	GSList			*m_CompList;
	int				m_MovingTarget;
	tSelectMode		m_SelectMode;
	tDisplayMode	m_DisplayMode;
	bool			m_Updating, m_UpdatePos, m_Negative, m_RowsUpward, m_SingleComp, m_VSTags;
	bool			m_Cancelled;
	CPopupMenu		m_LCGraphMenu, m_MDGraphMenu, m_ChartMenu;
	tDateFormat		m_DateFormat;
	CSelectionList	*m_SelectionList;
	int				m_SelectionIndex;
	CSelection		m_NewSelection;
	bool			m_ShowNewSelection;
	double			m_JDMin, m_JDMax;
	tMagScaleMode	m_MagScaleMode;
	double			m_FixedMagRange, m_CustomMagRange;
	guint			m_TimerId;
	tMousePos		m_MouseWhere;
	tIndex			m_LastFocus;
	gdouble			m_LastPosX, m_LastPosY;
	bool			m_LastPosValid;
	tCatalogSet     *m_CatalogBtns;
	int				m_ImageWidth, m_ImageHeight, m_CurrentCatalog;

	GtkWindow *GetTopLevel(void);
	bool EnableCtrlQuery(tControlId ctrl);
	void SetVariableStar(int star_id);
	void SetComparisonStar(int star_id);
	void SelectComparisonStar(int star_id);
	void UnselectComparisonStar(int star_id);
	void SetSelection(int selectionIndex, const CSelection &objs);
	void DettachSelection(void);
	void UpdateImage(void);
	void UpdateLightCurve(void);
	void UpdateMagDevCurve(void);
	void UpdateSelectionList(void);
	void UpdateControls(void);
	void SaveSelection(void);
	void RemoveSelection(void);
	void UpdateStatus(void);
	void PrintKeyValue(char *buf, double val, const CChannel *channel);
	const gchar *getSelectionLabel(int star_id) const;
	void CopyWcsCoordinatesFromChart(int row);
	void CopyWcsCoordinatesFromCurve(int row);
	void CopyWcsCoordinates(double lng, double lat);

	void OnButtonClicked(GtkWidget *pBtn);
	void OnItemActivated(GtkWidget *pChart, gint item);
	void OnContextMenu(GtkWidget *widget, GdkEventButton *event);
	void OnComboChanged(GtkComboBox *widget);
	bool OnNameValidator(const gchar *name, GtkWindow *parent);
	void OnObjectMenu(GdkEventButton *event, gint item);
	void OnChartMenu(GdkEventButton *event);

	GtkWidget *CreateCatalogsWidget();
	void UpdateCatalogs(GtkWindow *parent);
	void ShowCatalog(GtkWindow *parent, int index, bool show);
	void UpdateCatalog(GtkWindow *parent, int index);
	void EditCatalog(int index);

	static void button_clicked(GtkWidget *pButton, CVarFind *pMe);
	static void mouse_moved(GtkWidget *pChart, CVarFind *pMe);
	static void mouse_left(GtkWidget *pChart, CVarFind *pMe);
	static gboolean timer_cb(CVarFind *pMe);
	static void chart_item_activated(GtkWidget *pChart, gint item, CVarFind *pMe);
	static void graph_item_activated(GtkWidget *pChart, gint col, gint row, CVarFind *pMe);
	static void combo_changed(GtkComboBox *widget, CVarFind *pMe);
	static gint button_press_event(GtkWidget *widget, GdkEventButton *event, CVarFind *pMe);
	static bool name_validator(const gchar *name, GtkWindow *parent, CVarFind *pMe);
	static void AddToLayer(const char *objname, double ra, double dec, const char *catalog, const char *comment, void *data);
};

//
// Save mag-dev curve
//
class CExportMagDevCurveDlg
{
public:
	// Constructor
	CExportMagDevCurveDlg(GtkWindow *pParent);

	// Destructor
	virtual ~CExportMagDevCurveDlg();

	// Execute the dialog
	bool Execute(const CTable &table);

private:
	enum tFileType {
		TYPE_CSV,
		TYPE_TEXT,
		TYPE_N_ITEMS			// Number of file formats
	};

	struct tOptions {
		bool all_values, skip_invalid, header;
	};
	
	GtkWindow		*m_pParent;
	GtkWidget		*m_pDlg, *m_TypeCombo, *m_VCCombo;
	GtkWidget		*m_Header, *m_SkipInvalid, *m_AllValues;
	GtkListStore	*m_FileTypes, *m_Channels;
	CTable			m_Table;
	bool			m_Updating;
	tFileType		m_FileType;
	int				m_SelectedY;
	tOptions		m_Options[TYPE_N_ITEMS];
	
	void UpdateControls(void);

	bool OnResponseDialog(gint response_id);
	void OnSelectionChanged(GtkComboBox *pWidget);
	void OnTypeChanged(void);
	void OnButtonToggled(GtkToggleButton *widget);
	
	static tFileType StrToFileType(const gchar *str);
	static const gchar *FileTypeToStr(tFileType type);

	static void response_dialog(GtkWidget *widget, gint response_id, CExportMagDevCurveDlg *pMe);
	static void selection_changed(GtkComboBox *pWidget, CExportMagDevCurveDlg *pMe);
	static void button_toggled(GtkToggleButton *widget, CExportMagDevCurveDlg *user_data);
};

#endif
