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

lightcurve_dlg.cpp (C-Munipack project)
The 'Light curve' window
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.

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

#include <stdlib.h>
#include <string.h>

#include "graph_toolbox.h"
#include "colorchooser_dlg.h"

enum tTreeColumns
{
	DATA_CHANNEL,
	DATA_CAPTION,
	DATA_CHECK,
	DATA_COLOR,
	DATA_ICON,
	DATA_COLUMNS
};

static guint32 get_rgba(const GdkColor *color)
{
	return ((guint32)(color->red>>8) << 24) | ((color->green>>8)<<16) | ((color->blue>>8)<<8) | (0xFF);
}

static GdkPixbuf *makePixbuf(const GdkColor *color)
{
	static const int ICON_SIZE = 12;

	GdkPixbuf *buf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, ICON_SIZE, ICON_SIZE);
	gdk_pixbuf_fill(buf, get_rgba(color));
	return buf;
}

// Constructor
CGraphToolBox::CGraphToolBox():CInfoBox("Data"), m_Model(NULL)
{
	// Scrolled window
	GtkWidget *scrwnd = gtk_scrolled_window_new(NULL, NULL);
	gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwnd),
		GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrwnd), 
		GTK_SHADOW_ETCHED_IN);
	gtk_box_pack_start(GTK_BOX(m_Box), scrwnd, TRUE, TRUE, 0);

	// Tree view 
	m_Table = gtk_tree_view_new();
	gtk_container_add(GTK_CONTAINER(scrwnd), m_Table);
	gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(m_Table), FALSE);
	g_signal_connect(G_OBJECT(m_Table), "row-activated", G_CALLBACK(row_activated), this);
	// Value column (check box + text)
	m_Cols[0] = gtk_tree_view_column_new();
	gtk_tree_view_append_column(GTK_TREE_VIEW(m_Table), m_Cols[0]);
	GtkCellRenderer *renderer = gtk_cell_renderer_toggle_new();
	g_signal_connect(G_OBJECT(renderer), "toggled", G_CALLBACK(cell_toggled), this);
	g_object_set(renderer, "activatable", TRUE, NULL);
	gtk_tree_view_column_pack_start(m_Cols[0], renderer, FALSE);
	gtk_tree_view_column_add_attribute(m_Cols[0], renderer, "active", DATA_CHECK);

	m_Cols[1] = gtk_tree_view_column_new();
	gtk_tree_view_append_column(GTK_TREE_VIEW(m_Table), m_Cols[1]);
	renderer = gtk_cell_renderer_pixbuf_new();
	gtk_tree_view_column_pack_start(m_Cols[1], renderer, FALSE);
	gtk_tree_view_column_add_attribute(m_Cols[1], renderer, "pixbuf", DATA_ICON);
	renderer = gtk_cell_renderer_text_new();
	gtk_tree_view_column_pack_start(m_Cols[1], renderer, TRUE);
	gtk_tree_view_column_add_attribute(m_Cols[1], renderer, "text", DATA_CAPTION);

	gtk_widget_set_size_request(scrwnd, 160, -1);
}

// Destructor
CGraphToolBox::~CGraphToolBox(void)
{
	if (m_Model)
		g_object_unref(m_Model);
}

void CGraphToolBox::row_activated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *column, CGraphToolBox *pMe)
{
	if (column == ((CGraphToolBox*)pMe)->m_Cols[1])
		((CGraphToolBox*)pMe)->OnRowActivated(treeview, path);
}

void CGraphToolBox::OnRowActivated(GtkTreeView *tree_view, GtkTreePath *path)
{
	GtkTreeIter iter;

	if (m_Model && gtk_tree_model_get_iter(GTK_TREE_MODEL(m_Model), &iter, path)) {
		gint id;
		GdkColor *old_color, new_color;
		gtk_tree_model_get(GTK_TREE_MODEL(m_Model), &iter, DATA_CHANNEL, &id, DATA_COLOR, &old_color, -1);
		CColorChooserDlg dlg(GetTopLevel(), "Choose color");
		if (dlg.Execute(*old_color, new_color) && !gdk_color_equal(&new_color, old_color)) {
			gtk_tree_model_get_iter(GTK_TREE_MODEL(m_Model), &iter, path);
			gtk_list_store_set(m_Model, &iter, DATA_COLOR, &new_color, DATA_ICON, makePixbuf(&new_color), -1);
			Callback(CB_COLOR_CHANGED, id, &new_color);
		}
	}
}

void CGraphToolBox::cell_toggled(GtkCellRendererToggle *cell, char *path, CGraphToolBox *pMe)
{
	((CGraphToolBox*)pMe)->OnCellToggled(cell, path);
}

void CGraphToolBox::OnCellToggled(GtkCellRendererToggle *cell, char *path)
{
	int id;
	GtkTreeIter iter;

	if (gtk_tree_model_get_iter_from_string(GTK_TREE_MODEL(m_Model), &iter, path)) {
		gtk_tree_model_get(GTK_TREE_MODEL(m_Model), &iter, DATA_CHANNEL, &id, -1);
		gboolean checked = !gtk_cell_renderer_toggle_get_active(cell);
		gtk_list_store_set(m_Model, &iter, DATA_CHECK, checked, -1);
		Callback(CB_TOGGLED, id, &checked);
	}
}

// Initialization start
void CGraphToolBox::BeginReset()
{
	gtk_tree_view_set_model(GTK_TREE_VIEW(m_Table), NULL);
	if (m_Model) {
		g_object_unref(m_Model);
		m_Model = NULL;
	}
}

// Add channel
void CGraphToolBox::AddChannel(gint channel, const gchar *caption, const GdkColor *color)
{
	GtkTreeIter iter;

	if (!m_Model) {
		m_Model = gtk_list_store_new(DATA_COLUMNS, G_TYPE_INT, G_TYPE_STRING, G_TYPE_BOOLEAN, 
			GDK_TYPE_COLOR, GDK_TYPE_PIXBUF);
	}
	gtk_list_store_append(m_Model, &iter);
	gtk_list_store_set(m_Model, &iter, DATA_CHANNEL, channel, DATA_CAPTION, caption, 
		DATA_COLOR, color, DATA_ICON, makePixbuf(color), -1);
}

// Initialization done
void CGraphToolBox::EndReset()
{
	if (m_Model)
		gtk_tree_view_set_model(GTK_TREE_VIEW(m_Table), GTK_TREE_MODEL(m_Model));
}

// Set channel check state
void CGraphToolBox::SetState(gint channel, gboolean checked)
{
	if (m_Model) {
		GtkTreeIter iter;
		gboolean ok = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(m_Model), &iter);
		while (ok) {
			gint id;
			gboolean old_state;
			gtk_tree_model_get(GTK_TREE_MODEL(m_Model), &iter, DATA_CHECK, &old_state,
				DATA_CHANNEL, &id, -1);
			if (id == channel) {
				if (checked != old_state) 
					gtk_list_store_set(m_Model, &iter, DATA_CHECK, checked, -1);
				break;
			}
			ok = gtk_tree_model_iter_next(GTK_TREE_MODEL(m_Model), &iter);
		}
	}
}
