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

preview_dlg.h (C-Munipack project)
The preview dialog
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_INFOBOX_H
#define CMPACK_INFOBOX_H

#include <gtk/gtk.h>

#include "callback.h"
#include "cmpack_widgets.h"
#include "image_class.h"

class CInfoBox:public CCBObject
{
public:
	enum tMessageId {
		CB_CLOSED,
		CB_MOUSE_MOVED,
		CB_MOUSE_LEFT,
		CB_TOGGLED,
		CB_COLOR_CHANGED
	};

	// Constructor
	CInfoBox(const char *title);

	// Destructor
	virtual ~CInfoBox();

	// Set window caption
	void SetCaption(const gchar *caption);

	// Show/hide
	void Show(bool show);

	// Handle
	GtkWidget *Handle() const
	{ return m_Frame; }

	// Get top level widget
	GtkWindow *GetTopLevel(void);

protected:
	gchar			*m_Title;					// Window title
	GtkWidget		*m_Frame, *m_Box;			// Frame around the box
	GtkWidget		*m_Caption;					// The caption (drawing area widget)
	GdkPixmap		*m_Pixmap;					// Caption backscreen buffer
	int				m_PixWidth, m_PixHeight;	// Caption backscreen size
	bool			m_Visible;					// Tools is shown
	bool			m_NeedUpdate;				// Redraw caption at next paint
	
	// Create a new backing pixmap of the appropriate size 
	static gint configure_event(GtkWidget *widget, GdkEventConfigure *event, CInfoBox *pMe);
	void OnConfigure(GtkWidget *widget, GdkEventConfigure *event);

	// Redraw the screen from the backing pixmap 
	static gint expose_event(GtkWidget *widget, GdkEventExpose *event, CInfoBox *pMe);
	void OnExposeEvent(GtkWidget *widget, GdkEventExpose *event);

	// Click handling
	static gint button_press_event(GtkWidget *widget, GdkEventButton *event, CInfoBox *pMe);
	void OnButtonPress(GtkWidget *widget, GdkEventButton *event);

	// Compute width of given text
	int text_width(GtkWidget *widget, const gchar *buf);

	// Refraw backscreen buffer
	void RedrawCaption();

	// Initialization before the tool is shown
	virtual void OnShow(void) {};

	// Clean up after the tool is hidden
	virtual void OnHide(void) {};

	// Return false to prevent closing the panel
	virtual bool OnCloseQuery(void) { return true; }
};

class CTextBox:public CInfoBox
{
public:
	// Constructor
	CTextBox();

	// Destructor
	virtual ~CTextBox();

	// Redraw lock
	void BeginUpdate(void);
	void EndUpdate(void);

	// Clear the box
	void Clear(void);

	// Add heading (level=1..2)
	void AddTitle(int level, const gchar *text);

	// Add normal text
	void AddText(const gchar *text);

private:
	GtkTextBuffer	*m_Buffer;			// Text buffer
	GtkWidget		*m_TextView;		// The text area (text view widget)
};

class CScaleBox:public CInfoBox
{
public:
	// Constructor
	CScaleBox();

	// Set scale parameters
	void SetScaleParams(double min, double max, bool pseudocolors, bool invert);

private:
	GtkWidget		*m_Scale;			// Scale widget (shows grayscale or pseudoscale)
};

class CProfileBox:public CInfoBox
{
public:
	// Constructor
	CProfileBox();

	// Destructor
	virtual ~CProfileBox();

	// Clear profile data
	void Clear(void);

	// Set scale parameters
	void SetProfile(const CImage &image, int x0, int y0, int x1, int y1);

	// Get current position of the mouse
	bool GetMousePos(int *x, int *y);

protected:
	// Initialization before the tool is shown
	virtual void OnShow(void);

	// Clean up after the tool is hidden
	virtual void OnHide(void);

private:
	int				m_Style;
	int				m_X0, m_Y0;
	int				m_X1, m_Y1;
	int				m_Count;
	double			m_YMin, m_YMax, m_Mean, m_StdDev;
	CmpackGraphData	*m_Data;			// Graph data
	GtkWidget		*m_Plot;			// Graph widget
	GtkWidget		*m_StyleBox;		// Style selection box
	GtkTextBuffer	*m_Buffer;			// Text buffer
	GtkWidget		*m_View;			// Text view

	// Change display style
	void SetDisplayStyle(int style);

	// Update histogram
	void UpdateProfile(void);

	// Update displayed text
	void UpdateText(void);

	// Tracking mouse cursor on the plot
	static void mouse_moved(GtkWidget *pChart, CProfileBox *pMe);

	// Mouse cursor has left the the plot
	static void mouse_left(GtkWidget *pChart, CProfileBox *pMe);

	// Changed display style
	static void select_changed(GtkComboBox *pWidget, CProfileBox *pMe);
};

class CHistogramBox:public CInfoBox
{
public:
	// Constructor
	CHistogramBox();

	// Destructor
	virtual ~CHistogramBox();

	// Clear profile data
	void Clear(void);

	// Set scale parameters
	void SetData(CImage *image);

	// Get current position of the mouse
	bool GetMousePos(double *pos);

protected:
	// Initialization before the tool is shown
	virtual void OnShow(void);

	// Clean up after the tool is hidden
	virtual void OnHide(void);

private:
	CImage			*m_pImage;
	bool			m_logScale;
	double			m_XMin, m_XMax, m_YMax;
	double			m_ChannelWidth, m_ZeroOffset;
	int				m_Count;
	CmpackGraphData	*m_Data;			// Graph data
	GtkWidget		*m_Plot;			// Graph widget
	GtkTextBuffer	*m_Buffer;			// Text buffer
	GtkWidget		*m_View;			// Text view
	GtkWidget		*m_LogScaleChk;		// "Log scale" check box

	// Update graph data
	void UpdateData(void);

	// Update histogram
	void UpdateHistogram(void);

	// Update displayed text
	void UpdateText(void);

	// Change display style
	void SetLogScale(bool enable);

	// Mouse tracking
	static void mouse_moved(GtkWidget *pChart, CHistogramBox *pMe);

	// Mouse tracking
	static void mouse_left(GtkWidget *pChart, CHistogramBox *pMe);

	// Check box toggled
	static void button_toggled(GtkToggleButton *pButton, CHistogramBox *pMe);
};

#endif
