/*  HomeBank -- Free, easy, personal accounting for everyone.
 *  Copyright (C) 1995-2026 Maxime DOYEN
 *
 *  This file is part of HomeBank.
 *
 *  HomeBank 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.
 *
 *  HomeBank is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty ofdeftransaction_amountchanged
 *  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, see <http://www.gnu.org/licenses/>.
 */

#include "homebank.h"

#include "ui-dialogs.h"
#include "ui-widgets.h"


#include "ui-transaction.h"
#include "ui-archive.h"
#include "gtk-dateentry.h"
#include "ui-payee.h"
#include "ui-category.h"
#include "ui-account.h"

#include "hbtk-decimalentry.h"

#include "ui-txn-split.h"

/****************************************************************************/
/* Debug macros															 */
/****************************************************************************/
#define MYDEBUG 0

#if MYDEBUG
#define DB(x) (x);
#else
#define DB(x);
#endif

/* our global datas */
extern struct HomeBank *GLOBALS;
extern struct Preferences *PREFS;


#define GTK_RESPONSE_SPLIT_REM 10888


/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */


static void list_split_cell_data_func_number (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
GtkTreePath *path;
gint *indices;
gchar num[16];

	path = gtk_tree_model_get_path(model, iter);
	indices = gtk_tree_path_get_indices(path);
	//num = gtk_tree_path_to_string(path);
	g_snprintf(num, 15, "%d", 1 + *indices);
	gtk_tree_path_free(path);

	g_object_set(renderer, "text", num, NULL);

}


static void list_split_cell_data_func_amount (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
Split *split;
gchar buf[G_ASCII_DTOSTR_BUF_SIZE];
gchar *color;
guint32 kcur;

	gtk_tree_model_get(model, iter, 0, &split, -1);

	kcur = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(col), "kcur_data"));
	hb_strfmon(buf, G_ASCII_DTOSTR_BUF_SIZE-1, split->amount, kcur, FALSE);

	color = get_normal_color_amount(split->amount);
	g_object_set(renderer,
		"foreground",  color,
		"text", buf,
		NULL);
	
}


static void list_split_cell_data_func_memo (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
Split *split;

	gtk_tree_model_get(model, iter, 0, &split, -1);
	
	g_object_set(renderer, "text", split->memo, NULL);
}


static void list_split_cell_data_func_category (GtkTreeViewColumn *col, GtkCellRenderer *renderer, GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
{
Split *split;
Category *cat;

	gtk_tree_model_get(model, iter, 0, &split, -1);

	cat = da_cat_get(split->kcat);
	if( cat != NULL )
	{
		g_object_set(renderer, "text", cat->fullname, NULL);
	}
	else
		g_object_set(renderer, "text", "", NULL);
}


static void list_split_populate(GtkWidget *treeview, GPtrArray *splits)
{
GtkTreeModel *model;
GtkTreeIter	iter;
Split *split;
gint count, i;

	DB( g_print("\n[list_split] populate\n") );

	count = da_splits_length (splits);

	if( count <= 0 )
		return;

	model = gtk_tree_view_get_model(GTK_TREE_VIEW(treeview));

	gtk_list_store_clear (GTK_LIST_STORE(model));

	g_object_ref(model); /* Make sure the model stays with us after the tree view unrefs it */
	gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), NULL); /* Detach model from view */

	/* populate */
	for(i=0 ; i < count ; i++)
	{
		split = da_splits_get(splits, i);

		DB( g_print(" append split %d : %d, %.2f, '%s'\n", i, split->kcat, split->amount, split->memo) );

		gtk_list_store_append (GTK_LIST_STORE(model), &iter);
		gtk_list_store_set (GTK_LIST_STORE(model), &iter,
			0, split,
			-1);

	}

	gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), model); /* Re-attach model to view */
	g_object_unref(model);
}


static GtkWidget *
list_split_new(guint32 kcur)
{
GtkListStore *store;
GtkWidget *treeview;
GtkCellRenderer		*renderer;
GtkTreeViewColumn	*column;

	DB( g_print("\n[ui_split_listview] new\n") );


	// create list store
	store = gtk_list_store_new(1,
		G_TYPE_POINTER
		);

	// treeview
	treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
	g_object_unref(store);

	gtk_tree_view_set_grid_lines (GTK_TREE_VIEW (treeview), PREFS->grid_lines);

	//column 0: line number
	renderer = gtk_cell_renderer_text_new ();
	g_object_set(renderer, "xalign", 1.0, NULL);
	column = gtk_tree_view_column_new_with_attributes("#", renderer, NULL);
	gtk_tree_view_column_set_alignment (column, 1.0);
	gtk_tree_view_column_set_cell_data_func(column, renderer, list_split_cell_data_func_number, NULL, NULL);
	gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);


	// column 1: category
	renderer = gtk_cell_renderer_text_new ();
	g_object_set(renderer, 
		"ellipsize", PANGO_ELLIPSIZE_END,
		"ellipsize-set", TRUE,
		//taken from nemo, not exactly a resize to content, but good compromise
		"width-chars", 20,
		NULL);
	
	column = gtk_tree_view_column_new_with_attributes(_("Category"), renderer, NULL);

	//gtk_tree_view_column_set_alignment (column, 0.5);
	gtk_tree_view_column_set_resizable(column, TRUE);

	//gtk_tree_view_column_set_sort_column_id (column, sortcolumnid);
	//gtk_tree_view_column_set_fixed_width( column, HB_MINWIDTH_LIST);
	gtk_tree_view_column_set_expand (column, TRUE);
	gtk_tree_view_column_set_cell_data_func(column, renderer, list_split_cell_data_func_category, NULL, NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);
	
	// column 2: memo
	renderer = gtk_cell_renderer_text_new ();
	g_object_set(renderer, 
		"ellipsize", PANGO_ELLIPSIZE_END,
		"ellipsize-set", TRUE,
		//taken from nemo, not exactly a resize to content, but good compromise
		"width-chars", 20,
		NULL);
	
	column = gtk_tree_view_column_new_with_attributes(_("Memo"), renderer, NULL);

	//gtk_tree_view_column_set_alignment (column, 0.5);
	gtk_tree_view_column_set_resizable(column, TRUE);

	//gtk_tree_view_column_set_sort_column_id (column, sortcolumnid);
	//gtk_tree_view_column_set_fixed_width( column, HB_MINWIDTH_LIST);
	gtk_tree_view_column_set_expand (column, TRUE);
	gtk_tree_view_column_set_cell_data_func(column, renderer, list_split_cell_data_func_memo, NULL, NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);


	// column 3: amount
	renderer = gtk_cell_renderer_text_new ();
	g_object_set(renderer, "xalign", 1.0, NULL);

	column = gtk_tree_view_column_new_with_attributes(_("Amount"), renderer, NULL);
	g_object_set_data(G_OBJECT(column), "kcur_data", GINT_TO_POINTER(kcur));
	
	gtk_tree_view_column_set_alignment (column, 1.0);
	gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
	//gtk_tree_view_column_set_sort_column_id (column, sortcolumnid);
	//gtk_tree_view_column_set_fixed_width( column, HB_MINWIDTH_LIST);
	gtk_tree_view_column_set_cell_data_func(column, renderer, list_split_cell_data_func_amount, NULL, NULL);
	gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);


	// column empty
	//column = gtk_tree_view_column_new();
	//gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column);


	// treeviewattribute
	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW(treeview), TRUE);
	gtk_tree_view_set_reorderable (GTK_TREE_VIEW(treeview), TRUE);
	
	gtk_tree_view_set_enable_search(GTK_TREE_VIEW(treeview), FALSE);

	//gtk_tree_sortable_set_default_sort_func(GTK_TREE_SORTABLE(store), ui_acc_listview_compare_func, NULL, NULL);
	//gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(store), GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);

	return treeview;
}


/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */


/*static gboolean ui_split_dialog_cb_output_amount(GtkSpinButton *spin, gpointer data)
{
GtkAdjustment *adjustment;
gchar *text;
gdouble value;
//gpointer position;

	DB( g_print("\n[ui_split_dialog] amount output\n") );


	adjustment = gtk_spin_button_get_adjustment (spin);
	value = gtk_adjustment_get_value (adjustment);

	if( value == 0.0 )
	{
		gtk_entry_set_text (GTK_ENTRY (spin), "");
	}
	else
	{
		text = g_strdup_printf ("%+.*f", gtk_spin_button_get_digits(spin), value);
		
		DB( g_print(" output '%s'\n", text) );
		
		gtk_entry_set_text (GTK_ENTRY (spin), text);
		//gtk_editable_delete_text (GTK_EDITABLE(spin), 0, -1);
		//gtk_editable_insert_text (GTK_EDITABLE(spin), text, -1, &position);
		
		g_free (text);
	}
	return TRUE;
}*/


static void ui_split_dialog_filter_text_handler (GtkEntry	*entry,
						  const gchar *text,
						  gint		 length,
						  gint		*position,
						  gpointer	 data)
{
GtkEditable *editable = GTK_EDITABLE(entry);
gint i, count=0;
gchar *result = g_new0 (gchar, length+1);

  for (i=0; i < length; i++)
  {
	if (text[i]=='|')
	  continue;
	result[count++] = text[i];
  }


  if (count > 0) {
	g_signal_handlers_block_by_func (G_OBJECT (editable),
									 G_CALLBACK (ui_split_dialog_filter_text_handler),
									 data);
	gtk_editable_insert_text (editable, result, count, position);
	g_signal_handlers_unblock_by_func (G_OBJECT (editable),
									   G_CALLBACK (ui_split_dialog_filter_text_handler),
									   data);
  }
  g_signal_stop_emission_by_name (G_OBJECT (editable), "insert-text");

  g_free (result);
}


static void ui_split_dialog_cb_eval_order(struct ui_split_dialog_data *data)
{
GtkTreeModel *model;
GtkTreeIter	iter;
gboolean valid;
guint i;

	DB( g_print("\n[ui_split_dialog] eval order\n") );

	model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_split));
	i=1; valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
	while (valid)
	{
	Split *split;

		gtk_tree_model_get (model, &iter, 0, &split, -1);
		split->pos = i;

		DB( g_print(" split pos: %d '%s' %.2f\n", i, split->memo, split->amount) );
		
		i++; valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
	}

	da_splits_sort(data->tmp_splits);
}

/*
static gboolean ui_split_dialog_cb_amount_focus_out (GtkEditable *spin_button, GdkEvent  *event, gpointer user_data)
{
struct ui_split_dialog_data *data;
const gchar *txt;

	DB( g_print("\n[ui_split_dialog] cb amount focus out\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(spin_button), GTK_TYPE_WINDOW)), "inst_data");

	//force store
	txt = gtk_entry_get_text(GTK_ENTRY(spin_button));
	data->amountsign = hb_amount_forced_sign(txt);

	DB( g_print(" txt='%s'\n amt=%.8f\n sign=%d\n", txt, gtk_spin_button_get_value (GTK_SPIN_BUTTON(spin_button)), data->amountsign) );

	return FALSE;
}
*/

static void ui_split_dialog_update(GtkWidget *widget, gpointer user_data)
{
struct ui_split_dialog_data *data;
gboolean tmpval;
guint count;

	DB( g_print("\n[ui_split_dialog] update\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	count = da_splits_length (data->tmp_splits);

	//btn: edit/rem
	tmpval = gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_split)), NULL, NULL);
	gtk_widget_set_sensitive (data->BT_edit, (data->isedited) ? FALSE : tmpval);
	gtk_widget_set_sensitive (data->BT_dup, (data->isedited) ? FALSE : tmpval);
	gtk_widget_set_sensitive (data->BT_rem, (data->isedited) ? FALSE : tmpval);

	//btn: remall
	tmpval = (count > 1) ? TRUE : FALSE;
	gtk_widget_set_sensitive (data->BT_remall, (data->isedited) ? FALSE : tmpval);

	//btn: add/apply
	/*amount = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->ST_amount));
	tmpval = hb_amount_round(amount, 2) != 0.0 ? TRUE : FALSE;
	gtk_widget_set_sensitive (data->BT_apply, tmpval);
	*/

	//action title
	gtk_label_set_text(GTK_LABEL(data->LB_action), data->isedited == TRUE ? _("QUICK EDIT") : _("QUICK ADD") );

	//btn: add	
	tmpval = ( count >= TXN_MAX_SPLIT ) ? FALSE : TRUE;
	gtk_widget_set_sensitive (data->BT_add, tmpval);
	if( data->isedited )
		tmpval = TRUE;
	gtk_widget_set_sensitive (data->PO_cat, tmpval);
	gtk_widget_set_sensitive (data->ST_memo, tmpval);
	gtk_widget_set_sensitive (data->ST_amount, tmpval);	

	//btn: show/hide
	gtk_widget_set_sensitive (data->LV_split, !data->isedited);

	hb_widget_visible (data->BT_add, !data->isedited);
	
	hb_widget_visible (data->IM_edit, data->isedited);
	hb_widget_visible (data->BT_apply, data->isedited);
	hb_widget_visible (data->BT_cancel, data->isedited);
}


static void ui_split_dialog_edit_end(GtkWidget *widget, gpointer user_data)
{
struct ui_split_dialog_data *data;

	DB( g_print("\n[ui_split_dialog] edit_end\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	//ui_cat_comboboxentry_set_active(GTK_COMBO_BOX(data->PO_cat), 0);
	ui_cat_entry_popover_set_active(GTK_BOX(data->PO_cat), 0);
	if( data->mode == SPLIT_MODE_EMPTY )
		//gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->ST_amount), 0.0);
		hbtk_decimal_entry_set_value(HBTK_DECIMAL_ENTRY(data->ST_amount), 0.0);

	gtk_entry_set_text(GTK_ENTRY(data->ST_memo), "");

	gtk_widget_grab_focus(data->ST_amount);
	
	data->isedited = FALSE;
}


static void ui_split_dialog_edit_start(GtkWidget *widget, gpointer user_data)
{
struct ui_split_dialog_data *data;
GtkTreeSelection *selection;
GtkTreeModel		 *model;
GtkTreeIter			 iter;

	DB( g_print("\n[ui_split_dialog] edit_start\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_split));
	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_split));
	if (gtk_tree_selection_get_selected(selection, &model, &iter))
	{
	Split *split;
	gchar *txt;

		gtk_tree_model_get(model, &iter, 0, &split, -1);

		//ui_cat_comboboxentry_set_active(GTK_COMBO_BOX(data->PO_cat), split->kcat);
		ui_cat_entry_popover_set_active(GTK_BOX(data->PO_cat), split->kcat);
		//gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->ST_amount), split->amount);
		hbtk_decimal_entry_set_value(HBTK_DECIMAL_ENTRY(data->ST_amount), split->amount);
		txt = (split->memo != NULL) ? split->memo : "";
		gtk_entry_set_text(GTK_ENTRY(data->ST_memo), txt);
		
		data->isedited = TRUE;

		ui_split_dialog_update (data->dialog, user_data);
	}
}


static void ui_split_dialog_cancel_cb(GtkWidget *widget, gpointer user_data)
{
//struct ui_split_dialog_data *data;

	DB( g_print("\n[ui_split_dialog] cancel\n") );

	//data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	ui_split_dialog_edit_end(widget, user_data);
	ui_split_dialog_update (widget, user_data);
}


static void ui_split_dialog_apply_cb(GtkWidget *widget, gpointer user_data)
{
struct ui_split_dialog_data *data;
GtkTreeSelection *selection;
GtkTreeModel		 *model;
GtkTreeIter			 iter;

	DB( g_print("--------\n[ui_split_dialog] apply\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_split));
	if (gtk_tree_selection_get_selected(selection, &model, &iter))
	{
	Split *split;
	gdouble amount;

		gtk_tree_model_get(model, &iter, 0, &split, -1);
		DB( g_print(" update spin\n") );
		
		//gtk_spin_button_update (GTK_SPIN_BUTTON(data->ST_amount));
		//amount = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->ST_amount));
		amount = hbtk_decimal_entry_get_value(HBTK_DECIMAL_ENTRY(data->ST_amount));
		if(amount)
		{
			//split->kcat = ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(data->PO_cat));
			split->kcat = ui_cat_entry_popover_get_key_add_new(GTK_BOX(data->PO_cat));
			g_free(split->memo);
			split->memo = g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_memo)));
			//split->amount = amount;
			//#1910819 must round frac digit
			split->amount = hb_amount_round(amount, data->cur->frac_digits);
		}
	}

	ui_split_dialog_edit_end(widget, user_data);
	ui_split_dialog_compute (widget, data);
	ui_split_dialog_update (widget, user_data);
}


static void ui_split_dialog_deleteall_cb(GtkWidget *widget, gpointer user_data)
{
struct ui_split_dialog_data *data;
gint result;

	DB( g_print("\n[ui_split_dialog] deleteall_cb\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	result = ui_dialog_msg_confirm_alert(
			GTK_WINDOW(data->dialog),
			NULL,
			_("Do you want to delete all split lines"),
			_("_Delete"),
			TRUE
		);

	if(result == GTK_RESPONSE_OK)
	{
		gtk_list_store_clear (GTK_LIST_STORE(gtk_tree_view_get_model (GTK_TREE_VIEW(data->LV_split))));
		da_split_destroy(data->tmp_splits);
		data->tmp_splits = da_split_new ();
		
		ui_split_dialog_compute (widget, data);
		ui_split_dialog_update (widget, user_data);
	}
}


static void ui_split_dialog_cb_duplicate(GtkWidget *widget, gpointer user_data)
{
struct ui_split_dialog_data *data;
GtkTreeSelection *selection;
GtkTreeModel		 *model;
GtkTreeIter			 iter;

	DB( g_print("\n[ui_split_dialog] duplicate\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_split));
	if (gtk_tree_selection_get_selected(selection, &model, &iter))
	{
	Split *src_split, *new_split;

		gtk_tree_model_get(model, &iter, 0, &src_split, -1);
		new_split = da_split_duplicate(src_split);
		if( new_split )
		{
			//ui_split_listview_add(GTK_TREE_VIEW(data->LV_split), new_split);

			da_splits_append (data->tmp_splits, new_split);

			//model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_split));
			gtk_list_store_append (GTK_LIST_STORE(model), &iter);
			gtk_list_store_set (GTK_LIST_STORE(model), &iter,
				0, new_split,
				-1);
		}
	}

	ui_split_dialog_compute (widget, data);
	ui_split_dialog_update (widget, user_data);
}


static void ui_split_dialog_delete_cb(GtkWidget *widget, gpointer user_data)
{
struct ui_split_dialog_data *data;
GtkTreeSelection *selection;
GtkTreeModel		 *model;
GtkTreeIter			 iter;

	DB( g_print("\n[ui_split_dialog] delete_cb\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_split));
	if (gtk_tree_selection_get_selected(selection, &model, &iter))
	{
	Split *split;

		gtk_tree_model_get(model, &iter, 0, &split, -1);
		//todo: not implemented yet
		gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
		da_splits_delete(data->tmp_splits, split);
	}
	
	ui_split_dialog_compute (widget, data);
	ui_split_dialog_update (widget, user_data);
}


static void ui_split_dialog_add_cb(GtkWidget *widget, gpointer user_data)
{
struct ui_split_dialog_data *data;
GtkTreeModel *model;
GtkTreeIter	iter;
Split *split;
guint count;
gdouble amount;

	DB( g_print("--------\n[ui_split_dialog] add\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	count = da_splits_length (data->tmp_splits);
	DB( g_print(" n_split: %d (of %d)\n", count, TXN_MAX_SPLIT) );
	
	if( count <= TXN_MAX_SPLIT )
	{
		split = da_split_malloc ();
		//5.4.4
		DB( g_print(" update spin %d\n", data->amountsign) );
		
		//gtk_spin_button_update (GTK_SPIN_BUTTON(data->ST_amount));
		//amount = gtk_spin_button_get_value(GTK_SPIN_BUTTON(data->ST_amount));
		amount = hbtk_decimal_entry_get_value(HBTK_DECIMAL_ENTRY(data->ST_amount));
		if(amount)
		{
			//force sign apply
			if( hbtk_decimal_entry_get_forcedsign(HBTK_DECIMAL_ENTRY(data->ST_amount)) == FALSE )
			{
				DB( g_print(" raw amt=%.2f\n", amount) );
				switch( data->amountsign )
				{
					case HB_AMT_SIGN_EXP:
						if( amount > 0)
							amount *= -1;
						break;
					case HB_AMT_SIGN_INC:
						if( amount < 0)
							amount *= -1;
						break;
					default:
						if( hb_amount_type_match(amount, data->txntype) == FALSE )
							amount *= -1;
						break;
				}
			}	

			DB( g_print(" final amt=%.2f\n", amount) );
			//split->amount = amount;
			//#1910819 must round frac digit
			split->amount = hb_amount_round(amount, data->cur->frac_digits);

			//split->kcat = ui_cat_comboboxentry_get_key_add_new(GTK_COMBO_BOX(data->PO_cat));
			split->kcat = ui_cat_entry_popover_get_key_add_new(GTK_BOX(data->PO_cat));
			split->memo = g_strdup((gchar *)gtk_entry_get_text(GTK_ENTRY(data->ST_memo)));

			//#1977686 add into memo autocomplete
			if(PREFS->txn_memoacp == TRUE)
			{
				if( da_transaction_insert_memo(split->memo, data->date) )
				{
				GtkEntryCompletion *completion;
				GtkTreeModel *model;
				GtkTreeIter  iter;

					DB( g_print(" add memo to completion\n") );
					completion = gtk_entry_get_completion (GTK_ENTRY(data->ST_memo));
					model = gtk_entry_completion_get_model (completion);
					gtk_list_store_insert_with_values(GTK_LIST_STORE(model), &iter, -1,
						0, split->memo, 
						-1);
				}
			}

			DB( g_print(" append split : %d, %.2f, %s\n", split->kcat, split->amount, split->memo) );

			da_splits_append (data->tmp_splits, split);

			model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_split));
			gtk_list_store_append (GTK_LIST_STORE(model), &iter);
			gtk_list_store_set (GTK_LIST_STORE(model), &iter,
				0, split,
				-1);

			ui_split_dialog_compute (widget, data);
		}
		// 0 amount not allowed into splits
		else
		{
			da_split_free(split);
		}
	}
	else
	{
		g_warning("split error: limit of %d reached", TXN_MAX_SPLIT);
	}
	
	ui_split_dialog_edit_end(widget, user_data);
	ui_split_dialog_update (widget, user_data);
}


static void ui_split_dialog_cb_amount_activate(GtkWidget *widget, gpointer user_data)
{
struct ui_split_dialog_data *data;

	DB( g_print("\n[ui_split_dialog] cb amount activate\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	//we trigger the focus-out-event on spinbutton, with grab the add button
	//because we also do things before the legacy spinbutton fucntion
	//gtk_widget_grab_focus(data->BT_add);

	if( data->isedited == TRUE )
		ui_split_dialog_apply_cb(widget, NULL);
	else
		ui_split_dialog_add_cb(widget, NULL);
}


static void ui_split_rowactivated(GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col, gpointer user_data)
{
	DB( g_print("\n[ui_split_dialog] rowactivated\n") );

	ui_split_dialog_edit_start(GTK_WIDGET(treeview), NULL);
}


static void ui_split_selection(GtkTreeSelection *treeselection, gpointer user_data)
{
	DB( g_print("\n[ui_split_dialog] selection\n") );

	ui_split_dialog_update (GTK_WIDGET(gtk_tree_selection_get_tree_view (treeselection)), user_data);
}


void ui_split_dialog_compute(GtkWidget *widget, gpointer user_data)
{
struct ui_split_dialog_data *data;
gint i, count, nbvalid;
gchar buf[G_ASCII_DTOSTR_BUF_SIZE], *color = NULL;
gboolean sensitive;
GtkTreeModel *model;
GtkTreeIter	iter;
gboolean valid;

	DB( g_print("\n[ui_split_dialog] compute\n") );

	data = g_object_get_data(G_OBJECT(gtk_widget_get_ancestor(GTK_WIDGET(widget), GTK_TYPE_WINDOW)), "inst_data");

	nbvalid = 0;
	data->sumsplit = 0.0;
	data->remsplit = 0.0;

	model = gtk_tree_view_get_model(GTK_TREE_VIEW(data->LV_split));
	i=0; valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &iter);
	while (valid)
	{
	Split *split;

		gtk_tree_model_get (model, &iter,
			0, &split,
			-1);

		data->sumsplit += split->amount;
		if( hb_amount_round(split->amount, data->cur->frac_digits) != 0.0 )
			 nbvalid++;
		//TODO: we should warn if multiple line with same category

		/* Make iter point to the next row in the list store */
		i++; valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &iter);
	}
	count = i;

	DB( g_print(" n_count=%d, n_valid=%d\n", count, nbvalid ) );
	
	data->remsplit = data->amount - data->sumsplit;

	//validation: 2 split min, if 0 split
	//Accept button is not disabled to enable empty the splits
	sensitive = FALSE;
	if( (count == 0) || nbvalid >= 2 )
		sensitive = TRUE;

	gtk_widget_hide(data->IB_inflimit);
	gtk_widget_hide(data->IB_errtype);

	if( count >= TXN_MAX_SPLIT )
	{
		gtk_widget_show_all(data->IB_inflimit);
		//#GTK+710888: hack waiting a GTK fix 
		gtk_widget_queue_resize (data->IB_inflimit);
	}

	//-- fill summary
	ui_label_set_integer(GTK_LABEL(data->LB_lines), count);

	hb_strfnum(buf, G_ASCII_DTOSTR_BUF_SIZE-1, data->sumsplit, data->cur->key, FALSE);
	gtk_label_set_text(GTK_LABEL(data->LB_sumsplit), buf);

	hb_strfnum(buf, G_ASCII_DTOSTR_BUF_SIZE-1, data->amount, data->cur->key, FALSE);
	gtk_label_set_label(GTK_LABEL(data->LB_txnamount), buf);

	if( data->mode == SPLIT_MODE_EMPTY )
	{
		gtk_label_set_label(GTK_LABEL(data->LB_remain), "---");
	}
	else
	{
		if( hb_amount_round(data->remsplit, data->cur->frac_digits) == 0.0 )
		{
			g_sprintf(buf, _("Fully assigned"));
			//gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->ST_amount), 0);
			hbtk_decimal_entry_set_value(HBTK_DECIMAL_ENTRY(data->ST_amount), 0.0);
			color = PREFS->color_inc;
		}
		else
		{
		gchar *statestr = "";

			//g_snprintf(buf, G_ASCII_DTOSTR_BUF_SIZE-1, data->cur->format, data->remsplit);
			hb_strfnum(buf, G_ASCII_DTOSTR_BUF_SIZE-1, data->remsplit, data->cur->key, FALSE);
			if (data->remsplit < 0)
			{
				color = PREFS->color_exp;
				///TRANSLATORS: must keep the start space char
				statestr = _(" remaining");
			}
			else
			{
				color = PREFS->color_warn;
				///TRANSLATORS: must keep the start space char
				statestr = _(" over");
			}
			
			g_strlcat(buf, statestr, G_ASCII_DTOSTR_BUF_SIZE);
			//#1845841 bring back checkpoint with initial amount + init remainder
			//revert, because block any edition/inherit
			//sensitive = (count > 1) ? FALSE : sensitive;
			//but keep prefill remainder
			//gtk_spin_button_set_value(GTK_SPIN_BUTTON(data->ST_amount), data->remsplit);
			hbtk_decimal_entry_set_value(HBTK_DECIMAL_ENTRY(data->ST_amount), data->remsplit);
		}

		hb_label_set_set_color(GTK_LABEL(data->LB_remain), buf, color);
		//gtk_label_set_label(GTK_LABEL(data->LB_remain), buf);
	}

	//if split sum sign do not match
	if( hb_amount_type_match(data->sumsplit, data->txntype) == FALSE )
	{
		DB( g_print(" sum=%.2F, sign=%d (%s)\n", data->sumsplit, data->txntype, data->txntype == TXN_TYPE_EXPENSE ? "expense" : "income" ) );

		//#1885413 enable sign invert from split dialog
		//sensitive = FALSE;
		gtk_widget_show_all(data->IB_errtype);
		//#GTK+710888: hack waiting a GTK fix 
		gtk_widget_queue_resize (data->IB_errtype);
	}

	gtk_dialog_set_response_sensitive(GTK_DIALOG(data->dialog), GTK_RESPONSE_ACCEPT, sensitive);
}


static void _setup_txn_info(const gchar *memo, guint32 jdate, GtkLabel *LB_memo, GtkLabel *LB_date)
{
gchar buffer[256];
GDate date;

	//char option: • “ ”
	if( memo == NULL || strlen(memo) == 0 )
		memo = _("(no memo)");
	gtk_label_set_label(GTK_LABEL(LB_memo), memo);
	gtk_label_set_ellipsize(GTK_LABEL(LB_memo), PANGO_ELLIPSIZE_END);

	g_date_set_julian (&date, jdate);
	g_date_strftime (buffer, 256-1, PREFS->date_format, &date);
	gtk_label_set_label(GTK_LABEL(LB_date), buffer);
}


static void ui_split_dialog_setup(struct ui_split_dialog_data *data)
{
guint count;

	DB( g_print("\n[ui_split_dialog] set\n") );

	count = da_splits_length(data->tmp_splits);
	data->nbsplit = count > 1 ? count-1 : 0;

	DB( g_print(" n_count = %d\n", count) );
	list_split_populate (data->LV_split, data->tmp_splits);

	data->isedited = FALSE;

	//setup txn infos
	_setup_txn_info(data->ctx->memo, data->ctx->date, GTK_LABEL(data->LB_memo), GTK_LABEL(data->LB_date) );
	
	//gtk_spin_button_set_digits (GTK_SPIN_BUTTON(data->ST_amount), data->cur->frac_digits);
	hbtk_decimal_entry_set_digits(HBTK_DECIMAL_ENTRY(data->ST_amount), data->cur->frac_digits);

	//5.5 done in popover
	//ui_cat_comboboxentry_populate(GTK_COMBO_BOX(data->PO_cat), GLOBALS->h_cat);
	ui_split_dialog_compute(data->dialog, data);
	ui_split_dialog_update (data->dialog, data);
}


//TODO: we should merge this with normal window
GtkWidget *ui_split_dialog_view (GtkWidget *parent, Transaction *ope)
{
GtkWidget *dialog, *content, *scrollwin, *treeview, *hbox, *label;
GtkWidget *LB_memo, *LB_date;
gint w, h, dw, dh;

	DB( g_print("\n[ui_split_dialog] new view only\n") );

	if( ope->splits == NULL )
		return NULL;

	dialog = gtk_dialog_new_with_buttons (_("Split transaction (Read-only)"),
						GTK_WINDOW(parent),
						0,
						_("_Close"),
						GTK_RESPONSE_ACCEPT,
						NULL);

	//store our dialog private data
	DB( g_print(" window=%p\n", dialog) );

	//set a nice dialog size
	gtk_window_get_size(GTK_WINDOW(parent), &w, &h);
	dh = (h/PHI);
	//ratio 3:2
	dw = (dh * 3) / 2;
	DB( g_print(" parent w=%d h=%d => diag w=%d h=%d\n", w, h, dw, dh) );
	gtk_window_set_default_size (GTK_WINDOW(dialog), dw, dh);

	//dialog contents
	content = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
	gtk_box_set_spacing(GTK_BOX(content), SPACING_SMALL);
	hb_widget_set_margin(GTK_WIDGET(content), SPACING_SMALL);

	//transaction infos
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
	gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
	gtk_box_prepend (GTK_BOX (content), hbox);

		label = make_label(NULL, 0.0, 0.5);
		LB_memo = label;
		gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_MEDIUM, -1);
		gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(label)), GTK_STYLE_CLASS_DIM_LABEL);
		gtk_box_prepend (GTK_BOX (hbox), label);

		label = make_label("•", 0.0, 0.5);
		gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_MEDIUM, -1);
		gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(label)), GTK_STYLE_CLASS_DIM_LABEL);
		gtk_box_prepend (GTK_BOX (hbox), label);

		label = make_label(NULL, 0.0, 0.5);
		LB_date = label;
		gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_MEDIUM, -1);
		gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(label)), GTK_STYLE_CLASS_DIM_LABEL);
		gtk_box_prepend (GTK_BOX (hbox), label);

	//-- listview
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
	hbtk_box_prepend (GTK_BOX (content), hbox);

	scrollwin = make_scrolled_window(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	hbtk_box_prepend (GTK_BOX (hbox), scrollwin);
	treeview = list_split_new(ope->kcur);
	gtk_widget_set_vexpand (treeview, TRUE);
	gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrollwin), treeview);

	//setup
	_setup_txn_info(ope->memo, ope->date, GTK_LABEL(LB_memo), GTK_LABEL(LB_date) );
	list_split_populate(treeview, ope->splits);
	
	gtk_widget_show_all (dialog);

	gtk_dialog_run (GTK_DIALOG (dialog));

	gtk_window_destroy (GTK_WINDOW(dialog));

	return NULL;
	
}


GtkWidget *ui_split_dialog (GtkWidget *parent, GPtrArray **src_splits, SplitContext *ctx, void (update_callbackFunction(GtkWidget*, gdouble)))
{
struct ui_split_dialog_data *data;
GtkWidget *dialog, *content, *table, *hbox, *vbox, *scrollwin, *bar;
GtkWidget *label, *widget, *treeview;
gint row;

	DB( g_print("\n[ui_split_dialog] new\n") );

	data = g_malloc0(sizeof(struct ui_split_dialog_data));
	if(!data) return NULL;

	dialog = gtk_dialog_new_with_buttons (_("Split transaction"),
						GTK_WINDOW(parent),
						0,
						_("_Cancel"),
						GTK_RESPONSE_CANCEL,
						NULL);

	//store our dialog private data
	g_object_set_data(G_OBJECT(dialog), "inst_data", (gpointer)data);
	DB( g_print(" window=%p, inst_data=%p\n", dialog, data) );

	g_signal_connect (dialog, "destroy", G_CALLBACK (gtk_widget_destroyed), &dialog);

	data->dialog = dialog;

	gtk_dialog_add_button(GTK_DIALOG(dialog), _("_OK"), GTK_RESPONSE_ACCEPT);

	data->ctx = ctx;
	data->cur  = da_cur_get (ctx->kcur);

	//todo: init should move
	data->src_splits = *src_splits;
	data->mode = (hb_amount_round(ctx->amount, data->cur->frac_digits) != 0.0) ? SPLIT_MODE_AMOUNT : SPLIT_MODE_EMPTY;
	data->txntype = ctx->type;
	data->amount = ctx->amount;
	data->sumsplit = ctx->amount;

	DB( g_print(" kcur: %d %d %s\n", data->cur->key, data->cur->frac_digits, data->cur->format) );
	DB( g_print(" amount : %f\n", data->amount) );
	DB( g_print(" txntype: %s\n", data->txntype == TXN_TYPE_EXPENSE ? "expense" : "income" ));
	DB( g_print(" mode   : %s\n", data->mode == SPLIT_MODE_AMOUNT ? "amount" : "empty" ));

	if( *src_splits != NULL )
		data->tmp_splits = da_splits_clone(*src_splits); 
	else
		data->tmp_splits = da_split_new();

	//dialog contents
	content = gtk_dialog_get_content_area(GTK_DIALOG (dialog));
	gtk_box_set_spacing(GTK_BOX(content), SPACING_SMALL);
	hb_widget_set_margin(GTK_WIDGET(content), SPACING_SMALL);

	//transaction infos
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
	gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
	gtk_box_prepend (GTK_BOX (content), hbox);

		label = make_label(NULL, 0.0, 0.5);
		data->LB_memo = label;
		gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_MEDIUM, -1);
		gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(label)), GTK_STYLE_CLASS_DIM_LABEL);
		gtk_box_prepend (GTK_BOX (hbox), label);

		label = make_label("•", 0.0, 0.5);
		gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_MEDIUM, -1);
		gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(label)), GTK_STYLE_CLASS_DIM_LABEL);
		gtk_box_prepend (GTK_BOX (hbox), label);

		label = make_label(NULL, 0.0, 0.5);
		data->LB_date = label;
		gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_MEDIUM, -1);
		gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET(label)), GTK_STYLE_CLASS_DIM_LABEL);
		gtk_box_prepend (GTK_BOX (hbox), label);

	//-- listview
	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
	hbtk_box_prepend (GTK_BOX (content), hbox);

	scrollwin = make_scrolled_window(GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
	hbtk_box_prepend (GTK_BOX (hbox), scrollwin);
	treeview = list_split_new(ctx->kcur);
	data->LV_split = treeview;
	gtk_widget_set_vexpand (treeview, TRUE);
	gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(scrollwin), data->LV_split);

	bar = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_LARGE);
	gtk_widget_set_valign (bar, GTK_ALIGN_END);
	gtk_box_prepend (GTK_BOX (hbox), bar);

	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_TINY);
	gtk_box_prepend (GTK_BOX (bar), vbox);

		widget = make_image_button(ICONNAME_LIST_DELETE_ALL, _("Delete all"));
		data->BT_remall = widget;
		gtk_box_prepend (GTK_BOX (vbox), widget);

	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_TINY);
	gtk_box_prepend (GTK_BOX (bar), vbox);
	
		widget = make_image_button(ICONNAME_LIST_DELETE, _("Delete"));
		data->BT_rem = widget;
		gtk_box_prepend (GTK_BOX(vbox), widget);

		widget = make_image_button(ICONNAME_LIST_DUPLICATE, _("Duplicate"));
		data->BT_dup = widget;
		gtk_box_prepend (GTK_BOX(vbox), widget);

		widget = make_image_button(ICONNAME_HB_OPE_EDIT, _("Edit"));
		data->BT_edit = widget;
		gtk_box_prepend (GTK_BOX(vbox), widget);

	//-- quick add
	vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, SPACING_TINY);
	gtk_box_prepend (GTK_BOX (content), vbox);
	//gtk_style_context_add_class (gtk_widget_get_style_context (vbox), GTK_STYLE_CLASS_HEADER);

	label = make_label_group(_("QUICK ADD"));
	data->LB_action = label;
	gtk_box_prepend (GTK_BOX (vbox), label);
	
	gimp_label_set_attributes (GTK_LABEL (label), 
		PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, 
		PANGO_ATTR_WEIGHT, PANGO_WEIGHT_BOLD,
		-1);

	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_SMALL);
	gtk_box_prepend (GTK_BOX (vbox), hbox);
	//gtk_widget_set_margin_top(hbox, SPACING_SMALL);

		widget = ui_cat_entry_popover_new(NULL);
		data->PO_cat = widget;
		gtk_box_prepend (GTK_BOX(hbox), widget);
		widget = ui_cat_entry_popover_get_entry(GTK_BOX(widget));
		gtk_entry_set_placeholder_text(GTK_ENTRY(widget), _("Category..."));

		widget = make_memo_entry(NULL);
		data->ST_memo= widget;
		hbtk_box_prepend (GTK_BOX(hbox), widget);
		gtk_entry_set_placeholder_text(GTK_ENTRY(widget), _("Memo (optional)"));
		
		widget = hbtk_decimal_entry_new(NULL);
		data->ST_amount = widget;
		gtk_box_prepend (GTK_BOX(hbox), widget);

		// buttons
		widget = hbtk_image_new_from_icon_name_16 (ICONNAME_HB_OPE_EDIT);
		data->IM_edit = widget;
		gtk_box_prepend (GTK_BOX(hbox), widget);

		widget = make_image_button(ICONNAME_LIST_ADD, _("Add"));
		data->BT_add = widget;
		gtk_box_prepend (GTK_BOX(hbox), widget);

		widget = make_image_button(ICONNAME_EMBLEM_OK, _("Apply"));
		data->BT_apply = widget;
		gtk_box_prepend (GTK_BOX(hbox), widget);

		widget = make_image_button(ICONNAME_WINDOW_CLOSE, _("Cancel"));
		data->BT_cancel = widget;
		gtk_box_prepend (GTK_BOX(hbox), widget);


	widget = make_label_helper(_("Press [Enter] on Amount to add; [Tab] to move between fields"));
	gtk_box_prepend (GTK_BOX (vbox), widget);

	widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
	gtk_box_prepend (GTK_BOX (content), widget);

	hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, SPACING_LARGE);
	gtk_widget_set_halign (hbox, GTK_ALIGN_CENTER);
	//gtk_widget_set_vexpand (hbox, FALSE);
	gtk_box_prepend (GTK_BOX (content), hbox);

	table = gtk_grid_new ();
	//hb_widget_set_margin(GTK_WIDGET(table), SPACING_SMALL);
	gtk_grid_set_row_spacing (GTK_GRID (table), SPACING_TINY);
	gtk_grid_set_column_spacing (GTK_GRID (table), SPACING_LARGE);
	gtk_box_prepend (GTK_BOX (hbox), table);

		row = 0;
		label = gtk_label_new(_("LINES"));
		gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
		gtk_widget_set_halign (label, GTK_ALIGN_START);
		gtk_grid_attach (GTK_GRID (table), label, 0, row, 1, 1);
		label = gtk_label_new(_("SPLIT TOTAL"));
		gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
		gtk_widget_set_halign (label, GTK_ALIGN_START);
		gtk_grid_attach (GTK_GRID (table), label, 1, row, 1, 1);
		label = gtk_label_new(_("TRANSACTION"));
		gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
		gtk_widget_set_halign (label, GTK_ALIGN_START);
		gtk_grid_attach (GTK_GRID (table), label, 2, row, 1, 1);

		row++;
		widget = gtk_label_new(NULL);
		data->LB_lines = widget;
		gtk_widget_set_halign (widget, GTK_ALIGN_START);
		gtk_grid_attach (GTK_GRID (table), widget, 0, row, 1, 1);
		
		widget = gtk_label_new(NULL);
		data->LB_sumsplit = widget;
		gtk_widget_set_halign (widget, GTK_ALIGN_START);
		gtk_grid_attach (GTK_GRID (table), widget, 1, row, 1, 1);
		widget = gtk_label_new(NULL);
		data->LB_txnamount = widget;
		gtk_widget_set_halign (widget, GTK_ALIGN_START);
		gtk_grid_attach (GTK_GRID (table), widget, 2, row, 1, 1);

		widget = gtk_separator_new(GTK_ORIENTATION_VERTICAL);
		gtk_box_prepend (GTK_BOX (hbox), widget);

	table = gtk_grid_new ();
	//hb_widget_set_margin(GTK_WIDGET(table), SPACING_SMALL);
	gtk_grid_set_row_spacing (GTK_GRID (table), SPACING_TINY);
	gtk_grid_set_column_spacing (GTK_GRID (table), SPACING_LARGE);
	gtk_box_prepend (GTK_BOX (hbox), table);

		row = 0;
		label = gtk_label_new(_("DIFFERENCE"));
		gimp_label_set_attributes (GTK_LABEL (label), PANGO_ATTR_SCALE, PANGO_SCALE_SMALL, -1);
		gtk_widget_set_halign (label, GTK_ALIGN_START);
		gtk_grid_attach (GTK_GRID (table), label, 3, row, 1, 1);

		row++;
		widget = gtk_label_new(NULL);
		data->LB_remain = widget;
		gtk_widget_set_halign (widget, GTK_ALIGN_START);
		gtk_grid_attach (GTK_GRID (table), widget, 3, row, 1, 1);

	widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
	gtk_box_prepend (GTK_BOX (content), widget);

	//-- info bar
	bar = gtk_info_bar_new ();
	data->IB_inflimit = bar;
	gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_INFO);
	label = gtk_label_new (_("Number of splits limit is reached"));
	hbtk_box_prepend (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
	gtk_box_prepend (GTK_BOX (content), bar);

	bar = gtk_info_bar_new ();
	data->IB_errtype = bar;
	gtk_info_bar_set_message_type (GTK_INFO_BAR (bar), GTK_MESSAGE_WARNING);
	label = gtk_label_new (_("Warning: sum of splits and transaction type don't match"));
	hbtk_box_prepend (GTK_BOX (gtk_info_bar_get_content_area (GTK_INFO_BAR (bar))), label);
	gtk_box_prepend (GTK_BOX (content), bar);

	//connect all our signals
	g_signal_connect (gtk_tree_view_get_selection(GTK_TREE_VIEW(data->LV_split)), "changed", G_CALLBACK (ui_split_selection), data);
	g_signal_connect (GTK_TREE_VIEW(data->LV_split), "row-activated", G_CALLBACK (ui_split_rowactivated), data);

	g_signal_connect (data->BT_edit  , "clicked", G_CALLBACK (ui_split_dialog_edit_start), NULL);
	g_signal_connect (data->BT_dup   , "clicked", G_CALLBACK (ui_split_dialog_cb_duplicate), NULL);

	g_signal_connect (data->BT_rem   , "clicked", G_CALLBACK (ui_split_dialog_delete_cb), NULL);
	g_signal_connect (data->BT_remall, "clicked", G_CALLBACK (ui_split_dialog_deleteall_cb), NULL);

	g_signal_connect (data->ST_memo  , "insert-text", G_CALLBACK(ui_split_dialog_filter_text_handler), data);
	
	//g_signal_connect_after (data->ST_amount, "focus-out-event", G_CALLBACK (ui_split_dialog_cb_amount_focus_out), data);
	g_signal_connect_after (data->ST_amount, "activate", G_CALLBACK (ui_split_dialog_cb_amount_activate), NULL);

	g_signal_connect (data->BT_add   , "clicked", G_CALLBACK (ui_split_dialog_add_cb), NULL);
	g_signal_connect (data->BT_apply , "clicked", G_CALLBACK (ui_split_dialog_apply_cb), NULL);
	g_signal_connect (data->BT_cancel, "clicked", G_CALLBACK (ui_split_dialog_cancel_cb), NULL);

	//gtk_window_set_default_size(GTK_WINDOW(dialog), 480, -1);
	gtk_widget_show_all (dialog);

	//setup, init and show dialog
	ui_split_dialog_setup(data);

	//wait for the user
	gint result = gtk_dialog_run (GTK_DIALOG (dialog));

	switch (result)
	{
	// sum split and alter txn amount
	case GTK_RESPONSE_ACCEPT:
		if( da_splits_length(data->tmp_splits) )
		{
			ui_split_dialog_cb_eval_order(data);
			// here we swap src_splits <> tmp_splits
			*src_splits = data->tmp_splits;
			data->tmp_splits = data->src_splits;
			update_callbackFunction(parent, data->sumsplit);
		}
		else
		{
			//delete split and revert back original amount
			da_split_destroy(*src_splits);
			*src_splits = NULL;
			update_callbackFunction(parent, data->amount);
		}
		break;
	/*case GTK_RESPONSE_SPLIT_REM:
		da_split_destroy(*src_splits);
		*src_splits = NULL;
		update_callbackFunction(parent, data->sumsplit);
		break;
		*/
	default:
	   //do_nothing_since_dialog_was_cancelled ();
	   break;
	}

	// debug
	/*#if MYDEBUG == 1
	{
	guint i;

		for(i=0;i<TXN_MAX_SPLIT;i++)
		{
		Split *split = data->ope_splits[i];
			if(data->ope_splits[i] == NULL)
				break;
			g_print(" split %d : %d, %.2f, %s\n", i, split->kcat, split->amount, split->memo);
		}
	}
	#endif*/

	// cleanup and destroy
	//GLOBALS->changes_count += data->change;
	gtk_window_destroy (GTK_WINDOW(dialog));
	
	da_split_destroy (data->tmp_splits);

	g_free(data);

	return NULL;
}

