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

catfile_dlg.h (C-Munipack project)
The preview dialog for catalog files
Copyright (C) 2008 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_CAT_FILE_DLG_H
#define CMPACK_CAT_FILE_DLG_H

#include "file_dlg.h"
#include "info_dlg.h"
#include "menubar.h"
#include "popup.h"
#include "infobox.h"
#include "catfile_class.h"
#include "progress_dlg.h"

//
// Non-modal file viewer
//
class CCatFileDlg:public CFileDlg
{
public:
	// Constructor
	CCatFileDlg(void);

	// Destructor
	virtual ~CCatFileDlg(void);

	// Environment changed, reload settings
	virtual void EnvironmentChanged(void);

protected:
	// Get name of icon
	virtual const char *GetIconName(void) { return "catalogfile"; }

	// Load a file
	virtual bool LoadFile(GtkWindow *pParent, const char *fpath, GError **error);

	// Save a file
	virtual bool SaveFile(const char *fpath, GError **error);

	// Update dialog controls
	virtual void UpdateControls(void);

private:
	enum tDispMode {
		DISP_EMPTY,
		DISP_CHART,
		DISP_TABLE,
		DISP_MODE_COUNT
	};

	enum tInfoMode {
		INFO_NONE,
		INFO_OBJECT
	};

	CCatalog			*m_File;
	CWcs				*m_Wcs;
	GtkWidget			*m_ChartScrWnd, *m_ChartView, *m_TableScrWnd, *m_TableView;
	GtkWidget			*m_SelectCbx;
	GtkWidget			*m_NoteBox, *m_NoteCap, *m_NoteApplyBtn, *m_NoteDiscardBtn, *m_NoteIcon;
	GtkToolItem			*m_ClearBtn, *m_SaveBtn, *m_RemoveBtn;
	GtkToolItem			*m_ZoomFit, *m_ZoomIn, *m_ZoomOut;
	GtkListStore		*m_Selections;
	CMenuBar			m_Menu;
	CmpackChartData		*m_ChartData;
	GtkTreeModel		*m_TableData;
	CTextBox			m_InfoBox;
	bool				m_Rulers, m_Negative, m_RowsUpward, m_Updating, m_UpdatePos, m_UpdateZoom;
	bool				m_EditSelection, m_NotSavedBackup, m_SelectionChanged, m_ShowNewSelection;
	int					m_LastPosX, m_LastPosY, m_LastFocus;
	int					m_SelectedRow, m_SelectedObjId;
	int					m_SelectionIndex, m_SelectionIndexBackup;
	tDispMode			m_DispMode;
	tInfoMode			m_InfoMode;
	gint				m_TimerId;
	CPopupMenu			m_ObjectMenu, m_ChartMenu, m_SelectMenu, m_ContextMenu;
	CSelectionList		m_SelectionList, m_SelectionListBackup;
	CSelection			m_CurrentSelection, m_NewSelection;
	CTags				m_Tags, m_TagsBackup;
	int					m_SortColumnId;
	GtkSortType			m_SortType;
	GtkTreeViewColumn	*m_SortCol;
	GtkTreePath			*m_SelectedPath;

	void LoadSelectionList(const CSelectionList &list);
	void UpdateSelectionList(void);
	void UpdateTableHeader(void);
	void UpdateChart(void);
	void Export(void);
	void SetDisplayMode(tDispMode mode);
	void SetInfoMode(tInfoMode mode);
	void SetSortMode(int column, GtkSortType type);
	void ShowProperties(void);
	void EditHeader(void);
	void BeginEditSelection();
	void EndEditSelection(bool apply);
	void UpdateInfoBox(void);
	void UpdateStatus(void);
	void UpdateZoom(void);
	void Select(int row, CmpackSelectionType type);
	void Select(GtkTreePath *path, CmpackSelectionType type);
	void Unselect(int row);
	void Unselect(GtkTreePath *path);
	void UnselectType(CmpackSelectionType type);
	void NewSelection(void);
	void SaveSelection(void);
	void RemoveSelection(void);
	void EditTag(int row);
	void EditTag(GtkTreePath *path);
	void SetTag(int row, const char *tag);
	void SetTag(GtkTreePath *path, const char *tag);
	void RemoveTag(int row);
	void RemoveTag(GtkTreePath *path);
	void ClearTags(void);
	int ConfirmSelectionChanges();
	void DettachSelection(void);
	void CopyWcsCoordinatesFromChart(int row);
	void CopyWcsCoordinatesFromTable(GtkTreePath *path); 
	void CopyWcsCoordinates(double lng, double lat);

	void UpdateObject(CmpackChartData *model, int row);
	void UpdateObject(GtkTreeModel *model, GtkTreeIter *iter);
	void UpdateAll(void);

	void OnCommand(int cmd_id);
	void OnButtonClicked(GtkWidget *pBtn);
	void OnComboChanged(GtkComboBox *widget);
	void OnChartItemActivated(gint row);
	void OnSelectionChanged(void);
	void OnTableColumnClicked(GtkTreeViewColumn *pCol);
	void OnTableRowActivated(GtkTreeView *treeview, GtkTreePath *path);
	void OnInfoBoxClosed(void);
	void OnSelectMenu(GdkEventButton *event, gint item);
	void OnSelectMenu(GdkEventButton *event, GtkTreePath *path);
	void OnObjectMenu(GdkEventButton *event, gint item);
	void OnObjectMenu(GdkEventButton *event, GtkTreePath *path);
	void OnContextMenu(GdkEventButton *event);
	void OnChartMenu(GdkEventButton *event);
	bool OnNameValidator(const gchar *value, GtkWindow *parent);
	bool OnTagValidator(const gchar *value, GtkWindow *parent);

	static void button_clicked(GtkWidget *pButton, CCatFileDlg *pDlg);
	static void combo_changed(GtkComboBox *widget, CCatFileDlg *pDlg);
	static void mouse_moved(GtkWidget *pChart, CCatFileDlg *pMe);
	static void mouse_left(GtkWidget *pChart, CCatFileDlg *pMe);
	static void zoom_changed(GtkWidget *pChart, CCatFileDlg *pMe);
	static void chart_item_activated(GtkWidget *pChart, gint row, CCatFileDlg *pMe);
	static gint button_press_event(GtkWidget *widget, GdkEventButton *event, CCatFileDlg *pMe);
	static void selection_changed(GtkWidget *pChart, CCatFileDlg *pMe);
	static gboolean timer_cb(CCatFileDlg *pMe);
	static void MenuCallback(CCBObject *sender, int message, int wparam, void* lparam, void* cb_data);
	static void InfoBoxCallback(CCBObject *sender, int message, int wparam, void* lparam, void* cb_data);
	static bool name_validator(const gchar *value, GtkWindow *parent, CCatFileDlg *pMe);
	static bool tag_validator(const gchar *value, GtkWindow *parent, CCatFileDlg *pMe);
	static void table_column_clicked(GtkTreeViewColumn *pCol, CCatFileDlg *pMe);
	static void table_row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, CCatFileDlg *pMe);
};

//
// File properties dialog
//
class CCatFileInfoDlg:public CInfoDlg
{
public:
	// Constructor
	CCatFileInfoDlg(GtkWindow *pParent);

	// Display dialog
	void ShowModal(CCatalog *file, CWcs *wcs, const gchar *name, const gchar *path);

private:
	CCatalog	*m_File;
	CWcs		*m_Wcs;
	const gchar	*m_Name;
	GtkWidget	*m_HdrBtn, *m_WcsBtn;

	void OnButtonClicked(GtkWidget *pBtn);
	void ShowHeader(void);
	void ShowWcsData(void);

	static void button_clicked(GtkWidget *pButton, CCatFileInfoDlg *pDlg);
};

//
// Save photometry file dialog
//
class CExportCatFileDlg
{
public:
	// Constructor
	CExportCatFileDlg(GtkWindow *pParent);

	// Destructor
	virtual ~CExportCatFileDlg();

	// Execute the dialog
	bool Execute(const CCatalog &file, const CTags &tags, const CSelection &selection, 
		const gchar *current_path, int sort_column_id, GtkSortType sort_order);

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

	struct tOptions { 
		bool skip_invalid, header;
	};

	GtkWindow		*m_pParent;
	GtkWidget		*m_pDlg, *m_TypeCombo;
	GtkWidget		*m_Header, *m_SkipInvalid;
	GtkListStore	*m_FileTypes;
	CCatalog		m_File;
	tFileType		m_FileType;
	tOptions		m_Options[TYPE_N_ITEMS];
	bool			m_Updating;

	void UpdateControls(void);

	bool OnResponseDialog(gint response_id);
	void OnSelectionChanged(GtkComboBox *pWidget);
	void OnTypeChanged(void);
	void OnButtonToggled(GtkToggleButton *widget);
	
	static void response_dialog(GtkWidget *widget, gint response_id, CExportCatFileDlg *pMe);
	static void selection_changed(GtkComboBox *pWidget, CExportCatFileDlg *pMe);
	static void button_toggled(GtkToggleButton *widget, CExportCatFileDlg *user_data);
};


//
// Edit header dialog
//
class CCatEditHeaderDlg
{
public:
	// Constructor
	CCatEditHeaderDlg(GtkWindow *pParent);

	// Destructor
	virtual ~CCatEditHeaderDlg();

	// Execute the dialog
	bool Execute(CCatalog &file, const gchar *name);

private:
	GtkWidget	*m_pDlg, *m_ObjBtn, *m_LocBtn;
	GtkWidget	*m_ObjName, *m_RA, *m_Dec, *m_Observer, *m_LocName;
	GtkWidget	*m_Lon, *m_Lat, *m_Telescope, *m_Camera, *m_Filter;
	GtkWidget	*m_FOV, *m_Orientation, *m_Notes;

	void SetData(CCatalog &file);
	void GetData(CCatalog &file) const;
	void EditObjectCoords(void);
	void EditLocation(void);

	void OnButtonClicked(GtkWidget *widget);

	static void button_clicked(GtkWidget *widget, CCatEditHeaderDlg *user_data);
};

#endif
