/*
 * Osmo - a handy personal organizer
 *
 * Copyright (C) 2007 Tomasz Maka <pasp@users.sourceforge.net>
 *
 * 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 "calendar.h"
#include "calendar_notes.h"
#include "calendar_utils.h"
#include "calendar_widget.h"
#include "check_events.h"
#include "i18n.h"
#include "options_prefs.h"
#include "stock_icons.h"
#include "tasks.h"
#include "tasks_items.h"
#include "tasks_preferences_gui.h"
#include "tasks_utils.h"
#include "utils.h"
#include "utils_gui.h"
#include "utils_time.h"

#ifdef TASKS_ENABLED

/*------------------------------------------------------------------------------*/
static void
tasks_item_set_item(TASK_ITEM *item, GtkTreeIter *iter, GUI *appGUI) {
    GdkPixbuf *image;
    const gchar *icon_name;
    gchar *date_time_str;

    gtk_list_store_set(appGUI->tsk->tasks_list_store, iter,
            TA_COLUMN_DONE, item->done,
            TA_COLUMN_DUE_DATE_JULIAN, item->due_date_julian,
            TA_COLUMN_START_DATE_JULIAN, item->start_date_julian,
            TA_COLUMN_DONE_DATE_JULIAN, item->done_date_julian,
            TA_COLUMN_DUE_TIME, item->due_time,
            TA_COLUMN_PRIORITY, item->priority,
            TA_COLUMN_CATEGORY, item->category,
            TA_COLUMN_SUMMARY, item->summary,
            TA_COLUMN_DESCRIPTION, item->desc,
            TA_COLUMN_SOUND_ENABLE, item->sound_enable,
            TA_COLUMN_NDIALOG_ENABLE, item->ndialog_enable,
            TA_COLUMN_COLOR, get_date_color(item->due_date_julian, item->due_time, item->done, appGUI),
            TA_COLUMN_ACTIVE, item->active,
            TA_COLUMN_OFFLINE_IGNORE, item->offline_ignore,
            TA_COLUMN_REPEAT, item->repeat,
            TA_COLUMN_REPEAT_DAY, item->repeat_day,
            TA_COLUMN_REPEAT_MONTH_INTERVAL, item->repeat_month_interval,
            TA_COLUMN_REPEAT_DAY_INTERVAL, item->repeat_day_interval,
            TA_COLUMN_REPEAT_START_DAY, item->repeat_start_day,
            TA_COLUMN_REPEAT_TIME_START, item->repeat_time_start,
            TA_COLUMN_REPEAT_TIME_END, item->repeat_time_end,
            TA_COLUMN_REPEAT_TIME_INTERVAL, item->repeat_time_interval,
            TA_COLUMN_REPEAT_COUNTER, item->repeat_counter,
            TA_COLUMN_ALARM_COMMAND, item->alarm_command,
            TA_COLUMN_WARNING_DAYS, item->warning_days,
            TA_COLUMN_WARNING_TIME, item->warning_time,
            TA_COLUMN_POSTPONE_TIME, item->postpone_time,
            TA_COLUMN_ID, item->id,
            -1);

    icon_name = (item->repeat == TRUE) ? OSMO_STOCK_TYPE_RECURRENT : OSMO_STOCK_TYPE_NORMAL;
    image = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), icon_name, 16, 0, NULL);
    gtk_list_store_set(appGUI->tsk->tasks_list_store, iter, TA_COLUMN_TYPE, image, -1);
    g_object_unref(image);

    date_time_str = utl_date_time_print_default(item->due_date_julian, item->due_time, FALSE);
    gtk_list_store_set(appGUI->tsk->tasks_list_store, iter, TA_COLUMN_DUE_DATE, date_time_str, -1);
    g_free(date_time_str);
}
/*------------------------------------------------------------------------------*/

static void
tasks_item_add_item_to_list(TASK_ITEM *item, GUI *appGUI) {
    GtkTreeIter iter;

    gtk_list_store_append(appGUI->tsk->tasks_list_store, &iter);

    tasks_item_set_item(item, &iter, appGUI);
}

/*------------------------------------------------------------------------------*/

void
tasks_item_entered_cb (GtkWidget *widget, gpointer data) {

GtkTextBuffer *text_buffer;
GtkTextIter iter_a, iter_b;
GtkTreePath *sort_path, *filter_path, *path;
GtkTreeIter iter;
guint32 fstartdate;
guint id;
TASK_ITEM *item;
GDate *cdate;
gchar tmpbuf[BUFFER_SIZE];
gboolean create_new_item = TRUE;

    GUI *appGUI = (GUI *)data;

    item = g_new0 (TASK_ITEM, 1);

    if (appGUI->tsk->tasks_edit_state == TRUE) {

        gtk_tree_view_get_cursor (GTK_TREE_VIEW (appGUI->tsk->tasks_list), &sort_path, NULL);

        if (sort_path != NULL) {

            filter_path = gtk_tree_model_sort_convert_path_to_child_path (GTK_TREE_MODEL_SORT(appGUI->tsk->tasks_sort), sort_path);

            if (filter_path != NULL) {

                path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER(appGUI->tsk->tasks_filter), filter_path);

                if (path != NULL) {
                    gtk_tree_model_get_iter(GTK_TREE_MODEL(appGUI->tsk->tasks_list_store), &iter, path);
                    gtk_tree_model_get (GTK_TREE_MODEL(appGUI->tsk->tasks_list_store), &iter,
                               TA_COLUMN_ID, &id,
                               TA_COLUMN_START_DATE_JULIAN, &fstartdate, -1);
                    /* FIXME */
                    gtk_list_store_remove(appGUI->tsk->tasks_list_store, &iter);
                    gtk_tree_path_free(path);
                    create_new_item = FALSE;
                }

                gtk_tree_path_free(filter_path);
            }

            gtk_tree_path_free(sort_path);
        }
    }

    text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(appGUI->tsk->desc_textview));
    gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(text_buffer), &iter_a, 0);
    gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(text_buffer), &iter_b, -1);

    item->done = FALSE;
    item->due_date_julian = appGUI->tsk->tasks_due_julian_day;
    item->due_time = appGUI->tsk->tasks_due_time;

    if (create_new_item) {
        item->start_date_julian = utl_date_get_current_julian();
        item->id = appGUI->tsk->next_id++;
    } else {
        item->start_date_julian = fstartdate;
        item->id = id;
    }

    item->active = TRUE;
    item->sound_enable = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(appGUI->tsk->checkb_sound_enable));
    item->ndialog_enable = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(appGUI->tsk->checkb_ndialog_enable));

    item->repeat = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->tsk->rt_enable_checkbutton));
    item->offline_ignore = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->tsk->ignore_alarm_checkbutton));

    item->warning_days = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->aw_days_spinbutton));
    item->warning_time = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->aw_hours_spinbutton)) * 60 +
                         gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->aw_minutes_spinbutton));
    item->postpone_time = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (appGUI->tsk->postpone_spinbutton));
    item->alarm_command = g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(appGUI->tsk->alarm_cmd_entry)));

    item->repeat_time_start = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->rt_start_hour_spinbutton)) * 60 +
                         gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->rt_start_minute_spinbutton));
    item->repeat_time_end = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->rt_end_hour_spinbutton)) * 60 +
                         gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->rt_end_minute_spinbutton));
    item->repeat_time_interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->rt_interval_hour_spinbutton)) * 60 +
                         gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->rt_interval_minute_spinbutton));

    item->repeat_day_interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->rt_dp_day_spinbutton));
    item->repeat_month_interval = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->rt_dp_month_spinbutton));
    item->repeat_counter = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(appGUI->tsk->repeat_counter_spinbutton));

    item->priority = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(appGUI->tsk->priority_combobox));
    item->category = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(appGUI->tsk->category_combobox));
    item->summary = g_strdup((gchar *) gtk_entry_get_text(GTK_ENTRY(appGUI->tsk->summary_entry)));
    item->desc = gtk_text_buffer_get_text(GTK_TEXT_BUFFER(text_buffer), &iter_a, &iter_b, TRUE);

	if (g_date_valid_julian (item->due_date_julian)) {
		cdate = g_date_new_julian (item->due_date_julian);
		item->repeat_start_day = g_date_get_day (cdate);
		g_date_free (cdate);
	} else {
		item->repeat_start_day = 0;
	}

    item->repeat_day = 0;
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_1_checkbutton))) item->repeat_day |= 1;
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_2_checkbutton))) item->repeat_day |= 2;
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_3_checkbutton))) item->repeat_day |= 4;
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_4_checkbutton))) item->repeat_day |= 8;
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_5_checkbutton))) item->repeat_day |= 16;
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_6_checkbutton))) item->repeat_day |= 32;
    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_7_checkbutton))) item->repeat_day |= 64;

    if (item->repeat == TRUE && item->repeat_day == 0) {
        tsk_item_free (item);
        g_snprintf (tmpbuf, BUFFER_SIZE, "%s", _("Please select at least one day when recurrency is enabled."));
        utl_gui_create_dialog (GTK_MESSAGE_ERROR, tmpbuf, GTK_WINDOW (appGUI->tsk->tasks_add_window));
        return;
    }

    item->done_date_julian = 0;

    gtk_list_store_append(appGUI->tsk->tasks_list_store, &iter);
    tasks_item_set_item(item, &iter, appGUI);
    gui_systray_tooltip_update(appGUI);

    gtk_widget_destroy (appGUI->tsk->tasks_add_window);
    tasks_select_iter_position(&iter, appGUI);
    g_signal_emit_by_name (G_OBJECT(appGUI->cal->calendar), "day-selected");
	refresh_tasks (appGUI);

    tsk_item_free (item);
    cal_refresh_marks (appGUI);
    update_aux_calendars (appGUI);

    if (config.save_data_after_modification) {
        write_tasks_entries (appGUI);
    }
}
/*------------------------------------------------------------------------------*/

static void
tasks_related_set_state(gboolean date_state, gboolean time_state, GUI *appGUI) {
    gtk_widget_set_sensitive (appGUI->tsk->recurrent_task_vbox,
                              gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(appGUI->tsk->rt_enable_checkbutton)));
    
    gtk_widget_set_sensitive(appGUI->tsk->rt_enable_checkbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->checkb_sound_enable, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->checkb_ndialog_enable, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->aw_days_spinbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->aw_hours_spinbutton, date_state && time_state);
    gtk_widget_set_sensitive(appGUI->tsk->aw_minutes_spinbutton, date_state && time_state);
    gtk_widget_set_sensitive(appGUI->tsk->postpone_spinbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->alarm_cmd_entry, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->alarm_cmd_valid_image, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->rt_dp_day_spinbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->repeat_counter_spinbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->rt_dp_month_spinbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->dp_1_checkbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->dp_2_checkbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->dp_3_checkbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->dp_4_checkbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->dp_5_checkbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->dp_6_checkbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->dp_7_checkbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->ignore_alarm_checkbutton, date_state);
    gtk_widget_set_sensitive(appGUI->tsk->rt_start_hour_spinbutton, time_state);
    gtk_widget_set_sensitive(appGUI->tsk->rt_start_minute_spinbutton, time_state);
    gtk_widget_set_sensitive(appGUI->tsk->rt_end_hour_spinbutton, time_state);
    gtk_widget_set_sensitive(appGUI->tsk->rt_end_minute_spinbutton, time_state);
    gtk_widget_set_sensitive(appGUI->tsk->rt_interval_hour_spinbutton, time_state);
    gtk_widget_set_sensitive(appGUI->tsk->rt_interval_minute_spinbutton, time_state);
}

/*------------------------------------------------------------------------------*/

void
day_selected_cb (GuiCalendar *calendar, GUI *appGUI)
{
	TIME *tm;
	GDate *d = g_date_new ();

	gui_calendar_get_gdate (calendar, d);
	appGUI->tsk->tasks_due_julian_day = g_date_get_julian (d);
	g_date_free (d);

	if (gtk_expander_get_expanded (GTK_EXPANDER (appGUI->tsk->time_expander)) == TRUE) {
		tm = utl_time_new_hms (gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (appGUI->cal->spinbutton_start_hour)),
		                       gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (appGUI->cal->spinbutton_start_minute)),
		                       0);
		appGUI->tsk->tasks_due_time = utl_time_get_seconds (tm);
		utl_time_free (tm);
		tasks_related_set_state (TRUE, TRUE, appGUI);
	} else {
		appGUI->tsk->tasks_due_time = -1;
		tasks_related_set_state (TRUE, FALSE, appGUI);
	}

	gtk_widget_destroy (appGUI->tsk->td_calendar_window);
	gtk_entry_set_text (GTK_ENTRY (appGUI->tsk->due_date_entry),
	                    get_date_time_full_str (appGUI->tsk->tasks_due_julian_day, appGUI->tsk->tasks_due_time));
}

/*------------------------------------------------------------------------------*/

void
close_calendar_cb (GtkWidget *widget, GdkEvent *event, GUI *appGUI)
{
	gtk_widget_destroy (appGUI->tsk->td_calendar_window);
}

/*------------------------------------------------------------------------------*/

void
button_close_calendar_cb (GtkButton *button, gpointer user_data)
{
	close_calendar_cb (GTK_WIDGET (button), NULL, user_data);
}

/*------------------------------------------------------------------------------*/

void
button_ok_calendar_cb (GtkButton *button, gpointer user_data)
{
	GUI *appGUI = (GUI *) user_data;
	day_selected_cb (GUI_CALENDAR (appGUI->tsk->td_calendar), appGUI);
}

/*------------------------------------------------------------------------------*/

void
calendar_set_date (GDate *cdate, GUI *appGUI)
{
	gui_calendar_select_month (GUI_CALENDAR (appGUI->tsk->td_calendar),
	                           g_date_get_month (cdate) - 1, g_date_get_year (cdate));
	gui_calendar_select_day (GUI_CALENDAR (appGUI->tsk->td_calendar), g_date_get_day (cdate));
	day_selected_cb (GUI_CALENDAR (appGUI->tsk->td_calendar), appGUI);
}

/*------------------------------------------------------------------------------*/

void
set_today_calendar_cb (GtkWidget *widget, GUI *appGUI)
{
	GDate *date = utl_date_new_current ();
	calendar_set_date (date, appGUI);
	g_date_free (date);
}

/*------------------------------------------------------------------------------*/

void
set_tomorrow_calendar_cb (GtkWidget *widget, GUI *appGUI)
{
	GDate *date = utl_date_new_current ();
	g_date_add_days (date, 1);
	calendar_set_date (date, appGUI);
	g_date_free (date);
}

/*------------------------------------------------------------------------------*/

void
nodate_calendar_cb (GtkWidget *widget, GUI *appGUI)
{
    gtk_entry_set_text (GTK_ENTRY(appGUI->tsk->due_date_entry), _("No date"));
    appGUI->tsk->tasks_due_julian_day = 0;
    appGUI->tsk->tasks_due_time = -1;
    tasks_related_set_state (FALSE, FALSE, appGUI);
    close_calendar_cb (widget, NULL, appGUI);
}

/*------------------------------------------------------------------------------*/

gint
sd_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer data) {

    GUI *appGUI = (GUI *)data;

    if (event->keyval == GDK_KEY_Escape) {
        close_calendar_cb (NULL, NULL, appGUI);
        return TRUE;
    }

    return FALSE;
}

/*------------------------------------------------------------------------------*/

void
select_date_cb (GtkWidget *widget, gpointer data) {

GtkWidget *vbox1;
GtkWidget *hbox1;
GtkWidget *today_button;
GtkWidget *tomorrow_button;
GtkWidget *nodate_button;
GtkWidget *close_button;
GtkWidget *ok_button;
GtkWidget *grid;
GtkWidget *label;
GtkAdjustment *spinbutton_adjustment;
GDate *dt;
TIME *tm;

    GUI *appGUI = (GUI *)data;

    appGUI->tsk->td_calendar_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_window_set_position (GTK_WINDOW (appGUI->tsk->td_calendar_window), GTK_WIN_POS_MOUSE);
    gtk_window_set_modal (GTK_WINDOW (appGUI->tsk->td_calendar_window), TRUE);
	if (config.fullscreen == FALSE) {
        gtk_window_set_transient_for (GTK_WINDOW (appGUI->tsk->td_calendar_window), GTK_WINDOW (appGUI->tsk->tasks_add_window));
	}
    gtk_window_set_decorated (GTK_WINDOW (appGUI->tsk->td_calendar_window), FALSE);
    g_signal_connect (G_OBJECT (appGUI->tsk->td_calendar_window), "key_press_event",
                      G_CALLBACK (sd_key_press_cb), appGUI);
    gtk_window_set_resizable (GTK_WINDOW (appGUI->tsk->td_calendar_window), FALSE);

    vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
    gtk_widget_show (vbox1);
    gtk_container_add (GTK_CONTAINER (appGUI->tsk->td_calendar_window), vbox1);

    /* calendar */

    appGUI->tsk->td_calendar = gui_calendar_new();
    gui_calendar_set_cursor_type (GUI_CALENDAR (appGUI->tsk->td_calendar), CURSOR_BLOCK);
	gui_set_calendar_defaults(appGUI->tsk->td_calendar);
    gtk_widget_show (appGUI->tsk->td_calendar);
    g_signal_connect (G_OBJECT (appGUI->tsk->td_calendar), "day_selected_double_click",
                      G_CALLBACK (day_selected_cb), appGUI);
    gui_calendar_set_display_options (GUI_CALENDAR (appGUI->tsk->td_calendar), 
                                      (config.display_options & !GUI_CALENDAR_NO_MONTH_CHANGE) | 
                                      GUI_CALENDAR_SHOW_HEADING | GUI_CALENDAR_SHOW_DAY_NAMES | 
                                      (config.display_options & GUI_CALENDAR_WEEK_START_MONDAY));
    gtk_widget_set_valign(appGUI->tsk->td_calendar, GTK_ALIGN_FILL);
    gtk_widget_set_halign(appGUI->tsk->td_calendar, GTK_ALIGN_FILL);
    gtk_widget_set_margin_left(appGUI->tsk->td_calendar, 4);
    gtk_widget_set_margin_right(appGUI->tsk->td_calendar, 4);
    gtk_widget_set_margin_top(appGUI->tsk->td_calendar, 4);
    gtk_widget_set_margin_bottom(appGUI->tsk->td_calendar, 4);
    gtk_box_pack_start (GTK_BOX (vbox1), appGUI->tsk->td_calendar, TRUE, TRUE, 0);

    /* time selector */

    appGUI->tsk->time_expander = gtk_expander_new (_("Set time"));
    gtk_widget_set_can_focus(appGUI->tsk->time_expander, FALSE);
    gtk_box_pack_start (GTK_BOX (vbox1), appGUI->tsk->time_expander, FALSE, FALSE, 0);
    gtk_widget_show (appGUI->tsk->time_expander);

    grid = gtk_grid_new ();
    gtk_widget_show (grid);
    gtk_container_add (GTK_CONTAINER (appGUI->tsk->time_expander), grid);
    gtk_container_set_border_width (GTK_CONTAINER (grid), 4);
    gtk_grid_set_row_spacing (GTK_GRID (grid), 4);
    gtk_grid_set_column_spacing (GTK_GRID (grid), 4);

    label = gtk_label_new (_("Hour"));
    gtk_widget_show (label);
    gtk_grid_attach (GTK_GRID (grid), label, 0, 0, 1, 1);
    gtk_widget_set_valign(label, GTK_ALIGN_START);
    gtk_widget_set_halign(label, GTK_ALIGN_CENTER);

    label = gtk_label_new (_("Minute"));
    gtk_widget_show (label);
    gtk_grid_attach (GTK_GRID (grid), label, 1, 0, 1, 1);
    gtk_widget_set_valign(label, GTK_ALIGN_START);
    gtk_widget_set_halign(label, GTK_ALIGN_CENTER);

    spinbutton_adjustment = gtk_adjustment_new (get_current_hour(), 0, 23, 1, 10, 0);
    appGUI->cal->spinbutton_start_hour = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adjustment), 1, 0);
    gtk_widget_show (appGUI->cal->spinbutton_start_hour);
    gtk_widget_set_hexpand(appGUI->cal->spinbutton_start_hour, TRUE);
    gtk_grid_attach (GTK_GRID (grid), appGUI->cal->spinbutton_start_hour, 0, 1, 1, 1);

    spinbutton_adjustment = gtk_adjustment_new (get_current_minute(), 0, 59, 1, 10, 0);
    appGUI->cal->spinbutton_start_minute = gtk_spin_button_new (GTK_ADJUSTMENT (spinbutton_adjustment), 1, 0);
    gtk_widget_show (appGUI->cal->spinbutton_start_minute);
    gtk_widget_set_hexpand(appGUI->cal->spinbutton_start_minute, TRUE);
    gtk_grid_attach (GTK_GRID (grid), appGUI->cal->spinbutton_start_minute, 1, 1, 1, 1);

    /* update status */
	if (g_date_valid_julian (appGUI->tsk->tasks_due_julian_day)) {
		dt = g_date_new_julian (appGUI->tsk->tasks_due_julian_day);
		gui_calendar_select_month (GUI_CALENDAR (appGUI->tsk->td_calendar), g_date_get_month (dt) - 1, g_date_get_year (dt));
		gui_calendar_select_day (GUI_CALENDAR (appGUI->tsk->td_calendar), g_date_get_day (dt));
		g_date_free (dt);

		if (appGUI->tsk->tasks_due_time >= 0) {
			tm = utl_time_new_seconds (appGUI->tsk->tasks_due_time);
			gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->cal->spinbutton_start_hour), utl_time_get_hour (tm));
			gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->cal->spinbutton_start_minute), utl_time_get_minute (tm));
			gtk_expander_set_expanded (GTK_EXPANDER (appGUI->tsk->time_expander), TRUE);
			utl_time_free (tm);
		}
	}

    /* auxiliary buttons */

    hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 2);
    gtk_widget_show (hbox1);
    gtk_widget_set_valign(hbox1, GTK_ALIGN_FILL);
    gtk_widget_set_halign(hbox1, GTK_ALIGN_FILL);
    gtk_box_pack_start (GTK_BOX (vbox1), hbox1, TRUE, TRUE, 0);
    gtk_container_set_border_width (GTK_CONTAINER (hbox1), 4);

    today_button = gtk_button_new_with_mnemonic (_("Today"));
    gtk_widget_show (today_button);
    gtk_box_pack_start (GTK_BOX (hbox1), today_button, FALSE, FALSE, 0);
    g_signal_connect (G_OBJECT (today_button), "clicked",
                        G_CALLBACK (set_today_calendar_cb), appGUI);

    tomorrow_button = gtk_button_new_with_mnemonic (_("Tomorrow"));
    gtk_widget_show (tomorrow_button);
    gtk_box_pack_start (GTK_BOX (hbox1), tomorrow_button, FALSE, FALSE, 0);
    g_signal_connect (G_OBJECT (tomorrow_button), "clicked",
                        G_CALLBACK (set_tomorrow_calendar_cb), appGUI);

    nodate_button = gtk_button_new_with_mnemonic (_("No date"));
    gtk_widget_show (nodate_button);
    gtk_box_pack_start (GTK_BOX (hbox1), nodate_button, FALSE, FALSE, 0);
    g_signal_connect (G_OBJECT (nodate_button), "clicked",
                        G_CALLBACK (nodate_calendar_cb), appGUI);

    ok_button = gtk_button_new_from_icon_name ("gtk-ok", GTK_ICON_SIZE_BUTTON);
    gtk_button_set_relief (GTK_BUTTON (ok_button), GTK_RELIEF_NONE);
    gtk_widget_show (ok_button);
    gtk_box_pack_end (GTK_BOX (hbox1), ok_button, FALSE, FALSE, 0);
    g_signal_connect (G_OBJECT (ok_button), "clicked",
                        G_CALLBACK (button_ok_calendar_cb), appGUI);

    close_button = gtk_button_new_from_icon_name ("gtk-cancel", GTK_ICON_SIZE_BUTTON);
    gtk_widget_set_can_focus (close_button, FALSE);
    gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
    gtk_widget_show (close_button);
    gtk_box_pack_end (GTK_BOX (hbox1), close_button, FALSE, FALSE, 0);
    g_signal_connect (G_OBJECT (close_button), "clicked",
                        G_CALLBACK (button_close_calendar_cb), appGUI);

    gtk_widget_show (appGUI->tsk->td_calendar_window);
}

/*------------------------------------------------------------------------------*/

void
tasks_add_edit_window_close_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
	GUI *appGUI = (GUI *) user_data;

	gtk_window_get_size (GTK_WINDOW (appGUI->tsk->tasks_add_window),
	                     &config.tasks_addedit_win_w, &config.tasks_addedit_win_h);
	gdk_window_get_root_origin (gtk_widget_get_window(appGUI->tsk->tasks_add_window),
	                            &config.tasks_addedit_win_x, &config.tasks_addedit_win_y);
	gtk_widget_destroy (appGUI->tsk->tasks_add_window);
}

/*------------------------------------------------------------------------------*/

void
button_tasks_add_edit_window_close_cb (GtkButton *button, gpointer user_data)
{
	tasks_add_edit_window_close_cb (GTK_WIDGET (button), NULL, user_data);
}

/*------------------------------------------------------------------------------*/

gint
tasks_add_edit_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer data) {

GUI *appGUI = (GUI *)data;

	switch(event->keyval) {

        case GDK_KEY_Escape:
            tasks_add_edit_window_close_cb (appGUI->tsk->tasks_add_window, NULL, appGUI);
            return TRUE;
        case GDK_KEY_Return:
			if (gtk_widget_is_focus(appGUI->tsk->desc_textview) == FALSE) {
	            if (appGUI->tsk->tasks_accept_state == TRUE ) {
					g_signal_emit_by_name(G_OBJECT(appGUI->tsk->tasks_ok_button), "clicked");
					return TRUE;
				} 
			} else if (event->state & GDK_CONTROL_MASK) {  /* CTRL + Return */
				g_signal_emit_by_name(G_OBJECT(appGUI->tsk->tasks_ok_button), "clicked");
				return TRUE;
			}	   
			return FALSE;
    }

    return FALSE;
}
/*------------------------------------------------------------------------------*/

void
tasks_add_edit_summary_changed_cb (GtkEditable *editable, gpointer data) {

    GUI *appGUI = (GUI *)data;

    if (strlen (gtk_entry_get_text (GTK_ENTRY (editable)))) {
        appGUI->tsk->tasks_accept_state = TRUE;
    } else {
        appGUI->tsk->tasks_accept_state = FALSE;
    }
    gtk_widget_set_sensitive (appGUI->tsk->tasks_ok_button, appGUI->tsk->tasks_accept_state);
}

/*------------------------------------------------------------------------------*/

void
tasks_remove(GtkTreeRowReference *ref, GUI *appGUI) {
    GtkTreePath *path;
    GtkTreeIter iter, filter_iter, sort_iter;
    guint id;
    GtkTreeModel *model;

    model = gtk_tree_row_reference_get_model(ref);
    path = gtk_tree_row_reference_get_path(ref);
    if (path != NULL) {
        if (gtk_tree_model_get_iter(model, &sort_iter, path)) {
            gtk_tree_model_get(model, &sort_iter,
                    TA_COLUMN_ID, &id, -1);

#ifdef HAVE_LIBNOTIFY
            delete_task_notification(id, appGUI);
#endif /* HAVE_LIBNOTIFY */
            gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(model), &filter_iter, &sort_iter);
            gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(model))), &iter, &filter_iter);

            gtk_list_store_remove(appGUI->tsk->tasks_list_store, &iter);
        }
        gtk_tree_path_free(path);
    }
}

/*------------------------------------------------------------------------------*/

void
tasks_remove_dialog_show (GUI *appGUI) {

    gint response;
    gchar tmpbuf[BUFFER_SIZE];
 
    g_snprintf(tmpbuf, BUFFER_SIZE, "%s\n\n%s", _("Selected task will be removed."), _("Are you sure?"));

    response = utl_gui_create_dialog(GTK_MESSAGE_QUESTION, tmpbuf, GTK_WINDOW(appGUI->main_window));

    if (response == GTK_RESPONSE_YES) {
        tasks_selection_activate (FALSE, appGUI);
        utl_gui_foreach_selected(appGUI->tsk->tasks_list_selection, GTK_TREE_MODEL(appGUI->tsk->tasks_list_store),
                (GFunc)tasks_remove, appGUI);
        tasks_selection_activate (TRUE, appGUI);

        tasks_select_first_position_in_list(appGUI);
        g_signal_emit_by_name(G_OBJECT(appGUI->cal->calendar), "day-selected");
        gui_systray_tooltip_update(appGUI);
        if (config.save_data_after_modification) {
            write_tasks_entries(appGUI);
        }
    }
}

/*------------------------------------------------------------------------------*/

void
recurrent_task_enable_cb (GtkToggleButton *togglebutton, gpointer user_data) {

    GUI *appGUI = (GUI *)user_data;

    gtk_widget_set_sensitive (appGUI->tsk->recurrent_task_vbox,
                              gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(togglebutton)));
}

/*------------------------------------------------------------------------------*/

gint
alarm_cmd_entry_changed_cb (GtkEditable *editable, gpointer user_data)
{
	GUI *appGUI = (GUI *) user_data;
    utl_gui_update_command_status (GTK_EDITABLE(appGUI->tsk->alarm_cmd_entry), appGUI->tsk->alarm_cmd_valid_image, appGUI);

	return FALSE;
}
/*------------------------------------------------------------------------------*/
static GtkWidget *
create_styled_label(const gchar *format, const gchar *text) {
    gchar *text_with_style = g_strdup_printf(format, text);
    GtkWidget *label = gtk_label_new(text_with_style);
    gtk_label_set_use_markup(GTK_LABEL(label), TRUE);
    g_free(text_with_style);
    return label;
}

static GtkWidget *
create_basic_tab(GUI *appGUI) {
    GtkWidget *grid;
    GtkWidget *label;
    GtkWidget *select_date_button;
    GtkWidget *scrolledwindow;
    gchar *category;

    grid = gtk_grid_new();
    gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 6);

    label = create_styled_label("<b>%s:</b>", _("Summary"));
    gtk_widget_set_halign(label, GTK_ALIGN_START);
    gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);

    appGUI->tsk->summary_entry = gtk_entry_new();
    g_signal_connect(G_OBJECT(appGUI->tsk->summary_entry), "changed",
            G_CALLBACK(tasks_add_edit_summary_changed_cb), appGUI);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->summary_entry, 1, 0, 4, 1);


    label = create_styled_label("<b>%s:</b>", _("Due date"));
    gtk_widget_set_halign(label, GTK_ALIGN_START);
    gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);

    appGUI->tsk->due_date_entry = gtk_entry_new();
    gtk_widget_set_can_focus(appGUI->tsk->due_date_entry, FALSE);
    gtk_editable_set_editable(GTK_EDITABLE(appGUI->tsk->due_date_entry), FALSE);
    gtk_widget_set_hexpand(appGUI->tsk->due_date_entry, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->due_date_entry, 1, 1, 2, 1);

    select_date_button = gtk_button_new_with_mnemonic(_("Select date and time"));
    gtk_widget_set_can_focus(select_date_button, FALSE);
    g_signal_connect(select_date_button, "clicked",
            G_CALLBACK(select_date_cb), appGUI);
    gtk_grid_attach(GTK_GRID(grid), select_date_button, 3, 1, 2, 1);

    label = create_styled_label("<b>%s:</b>", _("Category"));
    gtk_widget_set_halign(label, GTK_ALIGN_START);
    gtk_grid_attach(GTK_GRID(grid), label, 0, 2, 1, 1);

    appGUI->tsk->category_combobox = gtk_combo_box_text_new();
    gtk_combo_box_set_focus_on_click(GTK_COMBO_BOX(appGUI->tsk->category_combobox), FALSE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->category_combobox, 1, 2, 2, 1);
    utl_gui_create_category_combobox(GTK_COMBO_BOX(appGUI->tsk->category_combobox),
            appGUI->opt->tasks_category_store, TRUE);
    category = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(appGUI->tsk->cf_combobox));
    gtk_combo_box_set_active(GTK_COMBO_BOX(appGUI->tsk->category_combobox),
            utl_gui_list_store_get_text_index(appGUI->opt->tasks_category_store, category));
    g_free(category);

    label = create_styled_label("<b>%s:</b>", _("Priority"));
    gtk_widget_set_halign(label, GTK_ALIGN_START);
    gtk_grid_attach(GTK_GRID(grid), label, 3, 2, 1, 1);

    appGUI->tsk->priority_combobox = gtk_combo_box_text_new();
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(appGUI->tsk->priority_combobox), NULL, _("Low"));
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(appGUI->tsk->priority_combobox), NULL, _("Medium"));
    gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(appGUI->tsk->priority_combobox), NULL, _("High"));
    gtk_combo_box_set_focus_on_click(GTK_COMBO_BOX(appGUI->tsk->priority_combobox), FALSE);
    gtk_combo_box_set_active(GTK_COMBO_BOX(appGUI->tsk->priority_combobox), MEDIUM_PRIORITY);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->priority_combobox, 4, 2, 1, 1);


    label = create_styled_label("<b>%s:</b>", _("Description"));
    gtk_widget_set_halign(label, GTK_ALIGN_START);
    gtk_grid_attach(GTK_GRID(grid), label, 0, 3, 5, 1);

    scrolledwindow = gtk_scrolled_window_new(NULL, NULL);
    gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
    gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolledwindow), GTK_SHADOW_IN);
    gtk_widget_set_vexpand(scrolledwindow, TRUE);
    gtk_grid_attach(GTK_GRID(grid), scrolledwindow, 0, 4, 5, 1);

    appGUI->tsk->desc_textview = gtk_text_view_new();
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(appGUI->tsk->desc_textview), GTK_WRAP_WORD);
    gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(appGUI->tsk->desc_textview), 4);
    gtk_text_view_set_left_margin(GTK_TEXT_VIEW(appGUI->tsk->desc_textview), 4);
    gtk_text_view_set_right_margin(GTK_TEXT_VIEW(appGUI->tsk->desc_textview), 4);
    gtk_container_add(GTK_CONTAINER(scrolledwindow), appGUI->tsk->desc_textview);

    label = create_styled_label("<b>%s:</b>", _("Options"));
    gtk_widget_set_halign(label, GTK_ALIGN_START);
    gtk_grid_attach(GTK_GRID(grid), label, 0, 5, 5, 1);

    appGUI->tsk->checkb_sound_enable = gtk_check_button_new_with_mnemonic(_("Enable sound notification"));
    gtk_widget_set_sensitive(appGUI->tsk->checkb_sound_enable, FALSE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(appGUI->tsk->checkb_sound_enable), TRUE);
    gtk_widget_set_halign(appGUI->tsk->checkb_sound_enable, GTK_ALIGN_START);
    gtk_widget_set_margin_left(appGUI->tsk->checkb_sound_enable, 6);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->checkb_sound_enable, 0, 6, 2, 1);

    appGUI->tsk->checkb_ndialog_enable = gtk_check_button_new_with_mnemonic(_("Enable notification dialog"));
    gtk_widget_set_sensitive(appGUI->tsk->checkb_ndialog_enable, FALSE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(appGUI->tsk->checkb_ndialog_enable), TRUE);
    gtk_widget_set_halign(appGUI->tsk->checkb_ndialog_enable, GTK_ALIGN_START);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->checkb_ndialog_enable, 2, 6, 3, 1);

    gtk_widget_show_all (grid);

    return grid;
}

/*------------------------------------------------------------------------------*/
static GtkWidget *
create_spinner(gdouble value, gdouble lower, gdouble upper) {
    GtkAdjustment *adjustment = gtk_adjustment_new(value, lower, upper, 1, 10, 0);
    return gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), 1, 0);
}

static GtkWidget *
create_alarm_section(GUI *appGUI) {
    GtkWidget *frame;
    GtkWidget *grid;
    GtkWidget *label;

    frame = gtk_frame_new(NULL);
    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);

    label = create_styled_label("<b>%s:</b>", _("Alarm warning"));
    gtk_frame_set_label_widget(GTK_FRAME(frame), label);


    grid = gtk_grid_new();
    gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    gtk_container_add(GTK_CONTAINER(frame), grid);

    label = create_styled_label("%s:", _("Days"));
    gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);

    appGUI->tsk->aw_days_spinbutton = create_spinner(0, 0, 10000);
    gtk_widget_set_hexpand(appGUI->tsk->aw_days_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->aw_days_spinbutton, 1, 0, 1, 1);

    label = create_styled_label("%s:", _("Hours"));
    gtk_grid_attach(GTK_GRID(grid), label, 2, 0, 1, 1);

    appGUI->tsk->aw_hours_spinbutton = create_spinner(0, 0, 23);
    gtk_widget_set_hexpand(appGUI->tsk->aw_hours_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->aw_hours_spinbutton, 3, 0, 1, 1);

    label = create_styled_label("%s:", _("Minutes"));
    gtk_grid_attach(GTK_GRID(grid), label, 4, 0, 1, 1);

    appGUI->tsk->aw_minutes_spinbutton = create_spinner(0, 0, 59);
    gtk_widget_set_hexpand(appGUI->tsk->aw_minutes_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->aw_minutes_spinbutton, 5, 0, 1, 1);

    return frame;
}

static GtkWidget *
create_postpone_section(GUI *appGUI) {
    GtkWidget *frame;
    GtkWidget *grid;
    GtkWidget *label;

    frame = gtk_frame_new(NULL);
    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);

    label = create_styled_label("<b>%s:</b>", _("Postpone time"));
    gtk_frame_set_label_widget(GTK_FRAME(frame), label);


    grid = gtk_grid_new();
    gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    gtk_container_add(GTK_CONTAINER(frame), grid);

    label = create_styled_label("%s:", _("Minutes"));
    gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);

    appGUI->tsk->postpone_spinbutton = create_spinner(config.postpone_time, 0, 1440);
    gtk_widget_set_hexpand(appGUI->tsk->postpone_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->postpone_spinbutton, 1, 0, 1, 1);

    return frame;
}

static GtkWidget *
create_alarm_command_section(GUI *appGUI) {
    GtkWidget *frame;
    GtkWidget *box;
    GtkWidget *label;

    frame = gtk_frame_new(NULL);
    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);

    label = create_styled_label("<b>%s:</b>", _("Alarm command"));
    gtk_frame_set_label_widget(GTK_FRAME(frame), label);


    box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_container_add(GTK_CONTAINER(frame), box);

    appGUI->tsk->alarm_cmd_entry = gtk_entry_new();
    g_signal_connect(G_OBJECT(appGUI->tsk->alarm_cmd_entry), "changed",
            G_CALLBACK(alarm_cmd_entry_changed_cb), appGUI);
    gtk_widget_set_hexpand(appGUI->tsk->alarm_cmd_entry, TRUE);
    gtk_box_pack_start(GTK_BOX(box), appGUI->tsk->alarm_cmd_entry, TRUE, TRUE, 0);

    appGUI->tsk->alarm_cmd_valid_image = gtk_image_new();
    gtk_box_pack_start(GTK_BOX(box), appGUI->tsk->alarm_cmd_valid_image, FALSE, FALSE, 0);

    return frame;
}

static GtkWidget *
create_date_subsection(GUI *appGUI) {
    GtkWidget *frame;
    GtkWidget *grid;
    GtkWidget *days_grid;
    GtkWidget *label;

    frame = gtk_frame_new(NULL);
    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);

    label = create_styled_label("<b>%s</b>", _("Date period"));
    gtk_frame_set_label_widget(GTK_FRAME(frame), label);


    grid = gtk_grid_new();
    gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    gtk_container_add(GTK_CONTAINER(frame), grid);

    label = create_styled_label("%s:", _("Days"));
    gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);

    appGUI->tsk->rt_dp_day_spinbutton = create_spinner(0, 0, 100000);
    gtk_widget_set_hexpand(appGUI->tsk->rt_dp_day_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->rt_dp_day_spinbutton, 1, 0, 1, 1);

    label = create_styled_label("%s:", _("Months"));
    gtk_grid_attach(GTK_GRID(grid), label, 2, 0, 1, 1);

    appGUI->tsk->rt_dp_month_spinbutton = create_spinner(0, 0, 100000);
    gtk_widget_set_hexpand(appGUI->tsk->rt_dp_month_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->rt_dp_month_spinbutton, 3, 0, 1, 1);

    label = create_styled_label("%s:", _("Repeat"));
    gtk_grid_attach(GTK_GRID(grid), label, 4, 0, 1, 1);

    appGUI->tsk->repeat_counter_spinbutton = create_spinner(0, 0, 100000);
    gtk_widget_set_hexpand(appGUI->tsk->repeat_counter_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->repeat_counter_spinbutton, 5, 0, 1, 1);


    label = create_styled_label("%s:", _("Repeat in the following days"));
    gtk_widget_set_halign(label, GTK_ALIGN_START);
    gtk_grid_attach(GTK_GRID(grid), label, 0, 3, 6, 1);

    days_grid = gtk_grid_new();
    gtk_grid_set_column_spacing(GTK_GRID(days_grid), 8);
    gtk_grid_attach(GTK_GRID(grid), days_grid, 0, 4, 6, 1);

    appGUI->tsk->dp_1_checkbutton = gtk_check_button_new_with_mnemonic(utl_get_day_name(1, FALSE));
    gtk_widget_set_hexpand(appGUI->tsk->dp_1_checkbutton, TRUE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(appGUI->tsk->dp_1_checkbutton), TRUE);
    gtk_grid_attach(GTK_GRID(days_grid), appGUI->tsk->dp_1_checkbutton, 0, 0, 1, 1);

    appGUI->tsk->dp_2_checkbutton = gtk_check_button_new_with_mnemonic(utl_get_day_name(2, FALSE));
    gtk_widget_set_hexpand(appGUI->tsk->dp_2_checkbutton, TRUE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(appGUI->tsk->dp_2_checkbutton), TRUE);
    gtk_grid_attach(GTK_GRID(days_grid), appGUI->tsk->dp_2_checkbutton, 1, 0, 1, 1);

    appGUI->tsk->dp_3_checkbutton = gtk_check_button_new_with_mnemonic(utl_get_day_name(3, FALSE));
    gtk_widget_set_hexpand(appGUI->tsk->dp_3_checkbutton, TRUE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(appGUI->tsk->dp_3_checkbutton), TRUE);
    gtk_grid_attach(GTK_GRID(days_grid), appGUI->tsk->dp_3_checkbutton, 2, 0, 1, 1);

    appGUI->tsk->dp_4_checkbutton = gtk_check_button_new_with_mnemonic(utl_get_day_name(4, FALSE));
    gtk_widget_set_hexpand(appGUI->tsk->dp_4_checkbutton, TRUE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(appGUI->tsk->dp_4_checkbutton), TRUE);
    gtk_grid_attach(GTK_GRID(days_grid), appGUI->tsk->dp_4_checkbutton, 3, 0, 1, 1);

    appGUI->tsk->dp_5_checkbutton = gtk_check_button_new_with_mnemonic(utl_get_day_name(5, FALSE));
    gtk_widget_set_hexpand(appGUI->tsk->dp_5_checkbutton, TRUE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(appGUI->tsk->dp_5_checkbutton), TRUE);
    gtk_grid_attach(GTK_GRID(days_grid), appGUI->tsk->dp_5_checkbutton, 0, 1, 1, 1);

    appGUI->tsk->dp_6_checkbutton = gtk_check_button_new_with_mnemonic(utl_get_day_name(6, FALSE));
    gtk_widget_set_hexpand(appGUI->tsk->dp_6_checkbutton, TRUE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(appGUI->tsk->dp_6_checkbutton), TRUE);
    gtk_grid_attach(GTK_GRID(days_grid), appGUI->tsk->dp_6_checkbutton, 1, 1, 1, 1);

    appGUI->tsk->dp_7_checkbutton = gtk_check_button_new_with_mnemonic(utl_get_day_name(7, FALSE));
    gtk_widget_set_hexpand(appGUI->tsk->dp_7_checkbutton, TRUE);
    gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(appGUI->tsk->dp_7_checkbutton), TRUE);
    gtk_grid_attach(GTK_GRID(days_grid), appGUI->tsk->dp_7_checkbutton, 2, 1, 1, 1);

    return frame;
}

static GtkWidget *
create_time_subsection(GUI *appGUI) {
    GtkWidget *frame;
    GtkWidget *grid;
    GtkWidget *label;

    frame = gtk_frame_new(NULL);
    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);

    label = create_styled_label("<b>%s</b>", _("Time period"));
    gtk_frame_set_label_widget(GTK_FRAME(frame), label);


    grid = gtk_grid_new();
    gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    gtk_container_add(GTK_CONTAINER(frame), grid);

    label = gtk_label_new(_("Start"));
    gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 2, 1);

    label = gtk_label_new(_("End"));
    gtk_grid_attach(GTK_GRID(grid), label, 2, 0, 2, 1);

    label = gtk_label_new(_("Interval"));
    gtk_grid_attach(GTK_GRID(grid), label, 4, 0, 2, 1);

    label = create_styled_label("<small>%s</small>", _("Hour"));
    gtk_grid_attach(GTK_GRID(grid), label, 0, 1, 1, 1);

    label = create_styled_label("<small>%s</small>", _("Minute"));
    gtk_grid_attach(GTK_GRID(grid), label, 1, 1, 1, 1);

    label = create_styled_label("<small>%s</small>", _("Hour"));
    gtk_grid_attach(GTK_GRID(grid), label, 2, 1, 1, 1);

    label = create_styled_label("<small>%s</small>", _("Minute"));
    gtk_grid_attach(GTK_GRID(grid), label, 3, 1, 1, 1);

    label = create_styled_label("<small>%s</small>", _("Hour"));
    gtk_grid_attach(GTK_GRID(grid), label, 4, 1, 1, 1);

    label = create_styled_label("<small>%s</small>", _("Minute"));
    gtk_grid_attach(GTK_GRID(grid), label, 5, 1, 1, 1);

    appGUI->tsk->rt_start_hour_spinbutton = create_spinner(0, 0, 23);
    gtk_widget_set_hexpand(appGUI->tsk->rt_start_hour_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->rt_start_hour_spinbutton, 0, 2, 1, 1);

    appGUI->tsk->rt_start_minute_spinbutton = create_spinner(0, 0, 59);
    gtk_widget_set_hexpand(appGUI->tsk->rt_start_minute_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->rt_start_minute_spinbutton, 1, 2, 1, 1);

    appGUI->tsk->rt_end_hour_spinbutton = create_spinner(23, 0, 23);
    gtk_widget_set_hexpand(appGUI->tsk->rt_end_hour_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->rt_end_hour_spinbutton, 2, 2, 1, 1);

    appGUI->tsk->rt_end_minute_spinbutton = create_spinner(59, 0, 59);
    gtk_widget_set_hexpand(appGUI->tsk->rt_end_minute_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->rt_end_minute_spinbutton, 3, 2, 1, 1);

    appGUI->tsk->rt_interval_hour_spinbutton = create_spinner(0, 0, 23);
    gtk_widget_set_hexpand(appGUI->tsk->rt_interval_hour_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->rt_interval_hour_spinbutton, 4, 2, 1, 1);

    appGUI->tsk->rt_interval_minute_spinbutton = create_spinner(0, 0, 59);
    gtk_widget_set_hexpand(appGUI->tsk->rt_interval_minute_spinbutton, TRUE);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->rt_interval_minute_spinbutton, 5, 2, 1, 1);

    return frame;
}

static GtkWidget *
create_options_subsection(GUI *appGUI) {
    GtkWidget *frame;
    GtkWidget *label;

    frame = gtk_frame_new(NULL);
    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);

    label = create_styled_label("<b>%s</b>", _("Options"));
    gtk_frame_set_label_widget(GTK_FRAME(frame), label);

    appGUI->tsk->ignore_alarm_checkbutton = gtk_check_button_new_with_mnemonic(_("Ignore alarm when task expired offline"));
    gtk_widget_set_margin_left(appGUI->tsk->ignore_alarm_checkbutton, 6);
    gtk_container_add(GTK_CONTAINER(frame), appGUI->tsk->ignore_alarm_checkbutton);

    return frame;
}

static GtkWidget *
create_recurrent_section(GUI *appGUI) {
    GtkWidget *frame;
    GtkWidget *grid;
    GtkWidget *label;


    frame = gtk_frame_new(NULL);
    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_NONE);

    label = create_styled_label("<b>%s:</b>", _("Recurrent task"));
    gtk_frame_set_label_widget(GTK_FRAME(frame), label);


    grid = gtk_grid_new();
    gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    gtk_container_add(GTK_CONTAINER(frame), grid);

    appGUI->tsk->rt_enable_checkbutton = gtk_check_button_new_with_mnemonic(_("Enable"));
    g_signal_connect(G_OBJECT(appGUI->tsk->rt_enable_checkbutton), "toggled",
            G_CALLBACK(recurrent_task_enable_cb), appGUI);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->rt_enable_checkbutton, 0, 0, 1, 1);

    appGUI->tsk->recurrent_task_vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_grid_attach(GTK_GRID(grid), appGUI->tsk->recurrent_task_vbox, 0, 1, 1, 1);

    gtk_box_pack_start(GTK_BOX(appGUI->tsk->recurrent_task_vbox), create_time_subsection(appGUI), TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(appGUI->tsk->recurrent_task_vbox), create_date_subsection(appGUI), TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(appGUI->tsk->recurrent_task_vbox), create_options_subsection(appGUI), TRUE, TRUE, 0);

    return frame;
}

static GtkWidget *
create_advanced_tab(GUI *appGUI) {
    GtkWidget *grid;
    grid = gtk_grid_new();
    gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 6);

    gtk_grid_attach(GTK_GRID(grid), create_alarm_section(appGUI), 0, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), gtk_separator_new(GTK_ORIENTATION_VERTICAL), 1, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), create_postpone_section(appGUI), 2, 0, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), create_alarm_command_section(appGUI), 0, 1, 3, 1);
    gtk_grid_attach(GTK_GRID(grid), create_recurrent_section(appGUI), 0, 2, 3, 1);

    gtk_widget_show_all(grid);
    return grid;
}

/*------------------------------------------------------------------------------*/
void
tasks_add_edit_dialog_show (gboolean tasks_edit_mode, guint32 julian_date, gint time, GUI *appGUI) {

GtkWidget *vbox0, *basic_tab, *advanced_tab;
GtkWidget *label;
GtkWidget *hseparator;
GtkWidget *hbuttonbox;
GtkWidget *cancel_button;
GtkWidget *notebook;
GtkTreeIter iter, filter_iter, sort_iter;
GtkTreeModel *model;
GtkTextIter titer;
GtkTextBuffer *text_buffer;
TASK_ITEM *item;


    appGUI->tsk->tasks_add_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    if(tasks_edit_mode == TRUE) {
        gtk_window_set_title (GTK_WINDOW (appGUI->tsk->tasks_add_window), _("Edit task"));
    } else {
        gtk_window_set_title (GTK_WINDOW (appGUI->tsk->tasks_add_window), _("Add task"));
        appGUI->tsk->tasks_due_julian_day = 0;
        appGUI->tsk->tasks_due_time = -1;
    }

    gtk_window_move (GTK_WINDOW (appGUI->tsk->tasks_add_window),
                     config.tasks_addedit_win_x, config.tasks_addedit_win_y);
    gtk_window_set_default_size (GTK_WINDOW(appGUI->tsk->tasks_add_window),
                                 config.tasks_addedit_win_w, config.tasks_addedit_win_h);

	if (config.fullscreen == FALSE) {
        gtk_window_set_transient_for(GTK_WINDOW(appGUI->tsk->tasks_add_window), GTK_WINDOW(appGUI->main_window));
	}
    gtk_window_set_modal(GTK_WINDOW(appGUI->tsk->tasks_add_window), TRUE);

    g_signal_connect (G_OBJECT (appGUI->tsk->tasks_add_window), "key_press_event",
                      G_CALLBACK (tasks_add_edit_key_press_cb), appGUI);

    g_signal_connect (G_OBJECT (appGUI->tsk->tasks_add_window), "delete_event",
                      G_CALLBACK(tasks_add_edit_window_close_cb), appGUI);

    vbox0 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
    gtk_widget_show (vbox0);
    gtk_container_add (GTK_CONTAINER (appGUI->tsk->tasks_add_window), vbox0);

	notebook = gtk_notebook_new ();
    gtk_widget_set_can_focus (notebook, FALSE);
    gtk_widget_show (notebook);
    gtk_notebook_set_tab_pos (GTK_NOTEBOOK(notebook), GTK_POS_TOP);
    gtk_container_set_border_width (GTK_CONTAINER(notebook), 6);
    gtk_box_pack_start (GTK_BOX (vbox0), notebook, TRUE, TRUE, 0);

	/* First Tab */

    basic_tab = create_basic_tab(appGUI);
    gtk_widget_set_margin_left(basic_tab, 6);
    gtk_widget_set_margin_right(basic_tab, 6);
    gtk_widget_set_margin_top(basic_tab, 6);
    gtk_widget_set_margin_bottom(basic_tab, 6);
    label = gtk_label_new (_("Basic"));
    gtk_widget_show (label);
    gtk_notebook_append_page (GTK_NOTEBOOK(notebook), basic_tab, label);

	/* Second Tab */

    advanced_tab = create_advanced_tab(appGUI);
    gtk_widget_set_margin_left(advanced_tab, 6);
    gtk_widget_set_margin_right(advanced_tab, 6);
    gtk_widget_set_margin_top(advanced_tab, 6);
    gtk_widget_set_margin_bottom(advanced_tab, 6);
    label = gtk_label_new (_("Advanced"));
    gtk_widget_show (label);
    gtk_notebook_append_page (GTK_NOTEBOOK(notebook), advanced_tab, label);

	/* Common */

    tasks_related_set_state (FALSE, FALSE, appGUI);

    hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_widget_set_margin_left(hseparator, 6);
    gtk_widget_set_margin_right(hseparator, 6);
    gtk_widget_show (hseparator);
    gtk_box_pack_start (GTK_BOX (vbox0), hseparator, FALSE, FALSE, 0);

    hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_widget_show (hbuttonbox);
    gtk_box_pack_start (GTK_BOX (vbox0), hbuttonbox, FALSE, FALSE, 0);
    gtk_container_set_border_width (GTK_CONTAINER (hbuttonbox), 6);
    gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
    gtk_box_set_spacing (GTK_BOX (hbuttonbox), 16);

	cancel_button = gtk_button_new_with_mnemonic (_("_Cancel"));
    gtk_widget_show (cancel_button);
    gtk_container_add (GTK_CONTAINER (hbuttonbox), cancel_button);
	g_signal_connect (cancel_button, "clicked",
	                  G_CALLBACK (button_tasks_add_edit_window_close_cb), appGUI);

	appGUI->tsk->tasks_ok_button = gtk_button_new_with_mnemonic (_("_OK"));
    gtk_widget_show (appGUI->tsk->tasks_ok_button);
    gtk_container_add (GTK_CONTAINER (hbuttonbox), appGUI->tsk->tasks_ok_button);
	g_signal_connect (appGUI->tsk->tasks_ok_button, "clicked",
	                  G_CALLBACK (tasks_item_entered_cb), appGUI);

    appGUI->tsk->tasks_edit_state = tasks_edit_mode;
    appGUI->tsk->tasks_accept_state = FALSE;

    gtk_entry_set_text (GTK_ENTRY(appGUI->tsk->due_date_entry), _("No date"));

    if (julian_date != 0 ) {
        appGUI->tsk->tasks_due_julian_day = julian_date;
        appGUI->tsk->tasks_due_time = -1;
		gtk_entry_set_text (GTK_ENTRY (appGUI->tsk->due_date_entry),
		                    get_date_time_full_str (appGUI->tsk->tasks_due_julian_day, appGUI->tsk->tasks_due_time));
    }

    if (tasks_edit_mode == TRUE) {

        appGUI->tsk->tasks_accept_state = TRUE;

        /* fill gui fields */

        text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(appGUI->tsk->desc_textview));
        utl_gui_clear_text_buffer (GTK_TEXT_BUFFER(text_buffer), &titer);

        sort_iter = utl_gui_get_first_selection_iter(appGUI->tsk->tasks_list_selection, &model);
        gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(appGUI->tsk->tasks_sort), &filter_iter, &sort_iter);
        gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(appGUI->tsk->tasks_filter), &iter, &filter_iter);

  
        item = tsk_get_item (&iter, appGUI);

        if (item != NULL) {

            appGUI->tsk->tasks_due_julian_day = item->due_date_julian;
            appGUI->tsk->tasks_due_time = item->due_time;


            gtk_entry_set_text (GTK_ENTRY (appGUI->tsk->due_date_entry),
                                                                   get_date_time_full_str (item->due_date_julian, item->due_time));
            gtk_entry_set_text(GTK_ENTRY(appGUI->tsk->summary_entry), item->summary);

                                    gtk_combo_box_set_active (GTK_COMBO_BOX (appGUI->tsk->category_combobox),
                                                              utl_gui_list_store_get_text_index (appGUI->opt->tasks_category_store, 
                                                                                                                                                             item->category));
                                    gtk_combo_box_set_active (GTK_COMBO_BOX (appGUI->tsk->priority_combobox),
                                                              tsk_get_priority_index (item->priority));

            gtk_text_buffer_get_iter_at_offset(GTK_TEXT_BUFFER(text_buffer), &titer, 0);

            if (item->desc != NULL) {
                gtk_text_buffer_insert(text_buffer, &titer, item->desc, -1);
                gtk_text_view_set_buffer(GTK_TEXT_VIEW(appGUI->tsk->desc_textview), text_buffer);
            }

            if (item->due_date_julian != 0) {

                if (item->due_time != -1) {
                    tasks_related_set_state (TRUE, TRUE, appGUI);
                } else {
                    tasks_related_set_state (TRUE, FALSE, appGUI);
                }

                                            gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->aw_days_spinbutton),
                                                                       item->warning_days);
                                            gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->aw_hours_spinbutton),
                                                                       item->warning_time / 60);
                                            gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->aw_minutes_spinbutton),
                                                                       item->warning_time % 60);
                                            gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->postpone_spinbutton),
                                                                       item->postpone_time);
                                            gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->rt_start_hour_spinbutton),
                                                                       item->repeat_time_start / 60);
                                            gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->rt_start_minute_spinbutton),
                                                                       item->repeat_time_start % 60);

                                            gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->rt_end_hour_spinbutton),
                                                                       item->repeat_time_end / 60);
                                            gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->rt_end_minute_spinbutton),
                                                                       item->repeat_time_end % 60);

                                            gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->rt_interval_hour_spinbutton),
                                                                       item->repeat_time_interval / 60);
                                            gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->rt_interval_minute_spinbutton),
                                                                       item->repeat_time_interval % 60);

                                            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->rt_enable_checkbutton),
                                                                          item->repeat);
                                            gtk_widget_set_sensitive (GTK_WIDGET(appGUI->tsk->recurrent_task_vbox), item->repeat);

                                            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->ignore_alarm_checkbutton),
                                                                          item->offline_ignore);
                                            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->checkb_sound_enable),
                                                                          item->sound_enable);
                                            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->checkb_ndialog_enable),
                                                                          item->ndialog_enable);

                if (item->alarm_command) {
                    gtk_entry_set_text(GTK_ENTRY(appGUI->tsk->alarm_cmd_entry), item->alarm_command);
                }
                utl_gui_update_command_status (GTK_EDITABLE(appGUI->tsk->alarm_cmd_entry),
                        appGUI->tsk->alarm_cmd_valid_image, appGUI);

                gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->rt_dp_day_spinbutton), 
                                                                                               item->repeat_day_interval);
                gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->rt_dp_month_spinbutton), 
                                                                                               item->repeat_month_interval);
                gtk_spin_button_set_value (GTK_SPIN_BUTTON (appGUI->tsk->repeat_counter_spinbutton), 
                                                                                               item->repeat_counter);

                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_1_checkbutton), 
                                                                                                      item->repeat_day & 1);
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_2_checkbutton), 
                                                                                                      item->repeat_day & 2);
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_3_checkbutton), 
                                                                                                      item->repeat_day & 4);
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_4_checkbutton), 
                                                                                                      item->repeat_day & 8);
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_5_checkbutton), 
                                                                                                      item->repeat_day & 16);
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_6_checkbutton), 
                                                                                                      item->repeat_day & 32);
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (appGUI->tsk->dp_7_checkbutton), 
                                                                                                      item->repeat_day & 64);

            }

            tsk_item_free (item);
        }
    }

    gtk_widget_set_sensitive(appGUI->tsk->tasks_ok_button, appGUI->tsk->tasks_accept_state);

    gtk_widget_show(appGUI->tsk->tasks_add_window);

	gtk_widget_grab_focus(appGUI->tsk->summary_entry);
}

/*------------------------------------------------------------------------------*/

void
read_tasks_entries (GUI *appGUI)
{
xmlDocPtr doc;
xmlChar *key;
xmlNodePtr node, cnode, category_node, main_node;
GtkTreeIter iter;
gchar *calendar_prop, *tasks_prop;
gboolean calendar_state, tasks_state;
TASK_ITEM *item;
gint priority_n;
gchar *prop;
gint tasks_version;

	if (g_file_test (prefs_get_data_filename (TASKS_ENTRIES_FILENAME, appGUI), G_FILE_TEST_IS_REGULAR) == FALSE)
		return;

	if ((doc = xmlParseFile (prefs_get_data_filename (TASKS_ENTRIES_FILENAME, appGUI)))) {

		if (!(node = xmlDocGetRootElement (doc))) {
			xmlFreeDoc (doc);
			return;
		}

		if (xmlStrcmp (node->name, (const xmlChar *) TASKS_NAME)) {
			xmlFreeDoc (doc);
			return;
		} else {
			prop = (gchar *) xmlGetProp (node, (const xmlChar *) "version");
			if (prop != NULL) {
				tasks_version = atoi (prop);
				xmlFree (prop);
			} else
				tasks_version = 0;
		}

		main_node = node->xmlChildrenNode;

		while (main_node != NULL) {

			if (!xmlStrcmp (main_node->name, (xmlChar *) TASKS_CATEGORY_ENTRIES_NAME)) {

				/* read note */
				category_node = main_node->xmlChildrenNode;

				while (category_node != NULL) {
					calendar_state = tasks_state = TRUE;

					if ((!xmlStrcmp (category_node->name, (const xmlChar *) "name"))) {
						key = xmlNodeListGetString (doc, category_node->xmlChildrenNode, 1);
						calendar_prop = (gchar *) xmlGetProp (category_node, (const xmlChar *) "calendar");
						if (calendar_prop != NULL) {
							calendar_state = atoi (calendar_prop);
							xmlFree (calendar_prop);
						}
						tasks_prop = (gchar *) xmlGetProp (category_node, (const xmlChar *) "tasks");
						if (tasks_prop != NULL) {
							tasks_state = atoi (tasks_prop);
							xmlFree (tasks_prop);
						}
						if (key != NULL) {
							gtk_list_store_append (appGUI->opt->tasks_category_store, &iter);
							gtk_list_store_set (appGUI->opt->tasks_category_store, &iter,
							                    TC_COLUMN_NAME, (gchar *) key,
							                    TC_COLUMN_CALENDAR, calendar_state,
							                    TC_COLUMN_TASKS, tasks_state, -1);
							xmlFree (key);
						}
					}

					category_node = category_node->next;
				}
			}

			/*---------------------------------------------------------------------------------------*/

			if (!xmlStrcmp (main_node->name, (xmlChar *) TASKS_ENTRIES_NAME)) {
				node = main_node->xmlChildrenNode;

				while (node != NULL) {

					if (!xmlStrcmp (node->name, (xmlChar *) "entry")) {
						cnode = node->xmlChildrenNode;

						item = g_new0 (TASK_ITEM, 1);
						if (item == NULL) continue;

						item->id = 0;
						item->done = FALSE;
						item->active = TRUE;
						item->offline_ignore = FALSE;
						item->repeat = FALSE;
						item->repeat_day = 127;
						item->repeat_day_interval = 0;
						item->repeat_start_day = 0;
						item->repeat_month_interval = 0;
						item->repeat_time_start = 0;
						item->repeat_time_end = 0;
						item->repeat_time_interval = 0;
						item->repeat_counter = 0;
						item->alarm_command = NULL;
						item->warning_days = 0;
						item->warning_time = 0;
						item->postpone_time = 0;
						item->due_date_julian = 0;
						item->due_time = -1;
						item->start_date_julian = 0;
						item->done_date_julian = 0;
						item->priority = NULL;
						item->category = NULL;
						item->summary = NULL;
						item->desc = NULL;
						item->sound_enable = TRUE;
						item->ndialog_enable = TRUE;
						priority_n = MEDIUM_PRIORITY;

						while (cnode != NULL) {
							utl_xml_get_uint ("id", &(item->id), cnode);
							utl_xml_get_int ("status", &(item->done), cnode);
							utl_xml_get_uint ("due_date", &(item->due_date_julian), cnode);
							utl_xml_get_int ("due_time", &(item->due_time), cnode);
							utl_xml_get_uint ("start_date", &(item->start_date_julian), cnode);
							utl_xml_get_uint ("done_date", &(item->done_date_julian), cnode);
							utl_xml_get_int ("active", &(item->active), cnode);
							utl_xml_get_int ("offline_ignore", &(item->offline_ignore), cnode);
							utl_xml_get_int ("repeat", &(item->repeat), cnode);
							utl_xml_get_int ("repeat_day", &(item->repeat_day), cnode);
							utl_xml_get_int ("repeat_month_interval", &(item->repeat_month_interval), cnode);
							utl_xml_get_int ("repeat_day_interval", &(item->repeat_day_interval), cnode);
							utl_xml_get_int ("repeat_start_day", &(item->repeat_start_day), cnode);
							utl_xml_get_int ("repeat_time_start", &(item->repeat_time_start), cnode);
							utl_xml_get_int ("repeat_time_end", &(item->repeat_time_end), cnode);
							utl_xml_get_int ("repeat_time_interval", &(item->repeat_time_interval), cnode);
							utl_xml_get_int ("repeat_counter", &(item->repeat_counter), cnode);
							utl_xml_get_int ("warning_days", &(item->warning_days), cnode);
							utl_xml_get_int ("warning_time", &(item->warning_time), cnode);
							utl_xml_get_int ("postpone_time", &(item->postpone_time), cnode);
							utl_xml_get_int ("sound_enable", &(item->sound_enable), cnode);
							utl_xml_get_int ("notification_dialog_enable", &(item->ndialog_enable), cnode);
							utl_xml_get_int ("priority", &priority_n, cnode);
							utl_xml_get_str ("alarm_command", &(item->alarm_command), cnode);
							utl_xml_get_str ("category", &(item->category), cnode);
							utl_xml_get_str ("summary", &(item->summary), cnode);
							utl_xml_get_str ("description", &(item->desc), cnode);
							cnode = cnode->next;
						}

						if (item->summary != NULL) {
							item->priority = g_strdup (tsk_get_priority_text (priority_n));

							if (item->due_date_julian == 0) {
								item->due_time = -1;
								item->warning_days = 0;
								item->warning_time = 0;
								item->repeat = FALSE;
								item->active = TRUE;
								item->postpone_time = 0;
							} else if (item->due_time == -1){
								item->warning_time = 0;
							}

							if (tasks_version < 208)
								item->active = TRUE;

							if (item->id == 0) {

								g_return_if_fail (tasks_version < 208);
								item->id = appGUI->tsk->next_id++;

							} else if (item->id >= appGUI->tsk->next_id)
								appGUI->tsk->next_id = item->id + 1;

							tasks_item_add_item_to_list (item, appGUI);
						}

						tsk_item_free (item);
					}

					node = node->next;
				}

			}

			/*---------------------------------------------------------------------------------------*/

			main_node = main_node->next;
		}

		xmlFree (node);
		xmlFreeDoc (doc);
	}
}

/*------------------------------------------------------------------------------*/

void
write_tasks_entries (GUI *appGUI)
{
xmlDocPtr doc;
xmlNodePtr main_node, node, note_node, dc_node;
xmlAttrPtr attr;
GtkTreeIter iter;
gchar *name;
gint tc_calendar, tc_tasks;
TASK_ITEM *item;
gchar temp[BUFFER_SIZE];
gboolean has_next;
xmlChar *escaped;

	if ((appGUI->save_status & WRT_TASKS) != 0) return;

	appGUI->save_status |= WRT_TASKS;

	doc = xmlNewDoc ((const xmlChar *) "1.0");
	attr = xmlNewDocProp (doc, (const xmlChar *) "encoding", (const xmlChar *) "utf-8");
	xmlFreeProp (attr);

	main_node = xmlNewNode (NULL, (const xmlChar *) TASKS_NAME);
	xmlNewProp (main_node, (const xmlChar *) "version", (const xmlChar *) appGUI->version);
	xmlDocSetRootElement (doc, main_node);

	node = xmlNewChild (main_node, NULL, (const xmlChar *) TASKS_CATEGORY_ENTRIES_NAME, (xmlChar *) NULL);

	has_next = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (appGUI->opt->tasks_category_store), &iter);
	while (has_next) {
		gtk_tree_model_get (GTK_TREE_MODEL (appGUI->opt->tasks_category_store), &iter,
		                    TC_COLUMN_NAME, &name, TC_COLUMN_CALENDAR, &tc_calendar, TC_COLUMN_TASKS, &tc_tasks, -1);

		escaped = xmlEncodeEntitiesReentrant(doc, (const xmlChar *) name);
		dc_node = xmlNewChild (node, NULL, (const xmlChar *) "name", (xmlChar *) escaped);
        xmlFree (escaped);

		g_snprintf (temp, BUFFER_SIZE, "%d", tc_calendar);
		escaped = xmlEncodeEntitiesReentrant(doc, (const xmlChar *) temp);
		xmlNewProp (dc_node, (const xmlChar *) "calendar", (xmlChar *) escaped);
        xmlFree (escaped);
		g_snprintf (temp, BUFFER_SIZE, "%d", tc_tasks);
		escaped = xmlEncodeEntitiesReentrant(doc, (const xmlChar *) temp);
		xmlNewProp (dc_node, (const xmlChar *) "tasks", (xmlChar *) escaped);
        xmlFree (escaped);

		g_free (name);
                has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (appGUI->opt->tasks_category_store), &iter);
	}

	node = xmlNewChild (main_node, NULL, (const xmlChar *) TASKS_ENTRIES_NAME, (xmlChar *) NULL);

	has_next = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (appGUI->tsk->tasks_list_store), &iter);
	while (has_next) {
		item = tsk_get_item (&iter, appGUI);

		if (item != NULL) {
			note_node = xmlNewChild (node, NULL, (const xmlChar *) "entry", (xmlChar *) NULL);

			utl_xml_put_int ("id", item->id, note_node);
			utl_xml_put_int ("status", item->done, note_node);
			utl_xml_put_uint ("due_date", item->due_date_julian, note_node);
			utl_xml_put_int ("due_time", item->due_time, note_node);
			utl_xml_put_uint ("start_date", item->start_date_julian, note_node);
			utl_xml_put_uint ("done_date", item->done_date_julian, note_node);
			utl_xml_put_int ("active", item->active, note_node);
			utl_xml_put_int ("offline_ignore", item->offline_ignore, note_node);
			utl_xml_put_int ("repeat", item->repeat, note_node);
			utl_xml_put_int ("repeat_day", item->repeat_day, note_node);
			utl_xml_put_int ("repeat_month_interval", item->repeat_month_interval, note_node);
			utl_xml_put_int ("repeat_day_interval", item->repeat_day_interval, note_node);
			utl_xml_put_int ("repeat_start_day", item->repeat_start_day, note_node);
			utl_xml_put_int ("repeat_time_start", item->repeat_time_start, note_node);
			utl_xml_put_int ("repeat_time_end", item->repeat_time_end, note_node);
			utl_xml_put_int ("repeat_time_interval", item->repeat_time_interval, note_node);
			utl_xml_put_int ("repeat_counter", item->repeat_counter, note_node);
			utl_xml_put_int ("warning_days", item->warning_days, note_node);
			utl_xml_put_int ("warning_time", item->warning_time, note_node);
			utl_xml_put_int ("postpone_time", item->postpone_time, note_node);
			utl_xml_put_int ("sound_enable", item->sound_enable, note_node);
			utl_xml_put_int ("notification_dialog_enable", item->ndialog_enable, note_node);
			utl_xml_put_int ("priority", tsk_get_priority_index (gettext (item->priority)), note_node);
			utl_xml_put_str ("alarm_command", item->alarm_command, note_node);
			utl_xml_put_str ("category", item->category, note_node);
			utl_xml_put_str ("summary", item->summary, note_node);
			utl_xml_put_str ("description", item->desc, note_node);

			tsk_item_free (item);
		}
                has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (appGUI->tsk->tasks_list_store), &iter);
	}

	utl_xml_write_doc (prefs_get_data_filename (TASKS_ENTRIES_FILENAME, appGUI), doc);
	xmlFreeDoc (doc);

	appGUI->save_status &= ~WRT_TASKS;
}

/*------------------------------------------------------------------------------*/

#endif  /* TASKS_ENABLED */

