
/*
 * 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 "about.h"
#include "calendar.h"
#include "backup.h"
#include "i18n.h"
#include "calendar_print.h"
#include "calendar_widget.h"
#include "calendar_jumpto.h"
#include "calendar_fullyear.h"
#include "tasks.h"
#include "tasks_items.h"
#include "contacts.h"
#include "utils.h"
#include "utils_gui.h"
#include "utils_date.h"
#include "options_prefs.h"
#include "tasks_utils.h"
#include "calendar_notes.h"
#include "calendar_timeline.h"
#include "calendar_calc.h"
#include "calendar_ical.h"
#include "check_events.h"
#include "stock_icons.h"
#include "preferences_gui.h"

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

static void
show_preferences_window_cb (GtkToolButton *toolbutton, gpointer data)
{
    GUI *appGUI = (GUI *) data;
    appGUI->opt->window = opt_create_preferences_window (appGUI);
    gtk_widget_show (appGUI->opt->window);

    gint page = gtk_notebook_page_num (GTK_NOTEBOOK (appGUI->opt->notebook), appGUI->opt->calendar);
    gtk_notebook_set_current_page (GTK_NOTEBOOK (appGUI->opt->notebook), page);
}

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

#ifndef HAVE_LIBWEBKIT

static GdkPixbuf *
cal_get_moon_icon(gint phase) {
    GdkPixbuf *icon;
    gchar *filename;
    if (phase > 7) return NULL;
    filename = g_strdup_printf(PIXMAPSDIR G_DIR_SEPARATOR_S "moonphase_%d_data.png", phase);
    icon = gdk_pixbuf_new_from_file(filename, NULL);
    g_free(filename);
    return icon;
}

static void
cal_set_moon_icon (gint moon_phase, GUI *appGUI)
{
GdkPixbuf *icon;
gchar tmpbuf[BUFFER_SIZE];

    icon = cal_get_moon_icon(moon_phase);
    gtk_image_set_from_pixbuf (GTK_IMAGE (appGUI->cal->moon_icon), icon);
    g_object_unref (icon);

    g_snprintf (tmpbuf, BUFFER_SIZE, "(%s)", utl_get_moon_phase_name (moon_phase));
    gtk_label_set_text (GTK_LABEL (appGUI->cal->moon_phase_label), tmpbuf);
}

#else

static gchar *
cal_get_moonphase_img(guint phase) {
    gchar *moonimg = NULL;
    static gchar *phases[8] = {NULL}; /* TODO this should be freed at some point */

    if (phase > 7) return g_strdup("");

    if (phases[phase] == NULL) {
        gboolean rc;
        gchar *content;
        gsize length;
        gchar *filename = g_strdup_printf(PIXMAPSDIR G_DIR_SEPARATOR_S "moonphase_%d_data.png", phase);
        rc = g_file_get_contents(filename, &content, &length, NULL);
        if(rc) {
            phases[phase] = g_base64_encode((const guchar *)content, length);
        } else {
            fprintf(stderr, _("Cannot read file."));
        }
        g_free(content);
        g_free(filename);
    }
    moonimg = g_strdup_printf("<img src=\"data:image/png;base64,%s\">", phases[phase]);
    return moonimg;
}

#endif  /* HAVE_LIBWEBKIT */

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

static void
cal_mark_days_with_notes (GDate *date, GUI *appGUI)
{
GDate *tmpdate;
gint i, days;

    tmpdate = g_date_new_dmy (1, g_date_get_month (date), g_date_get_year (date));
    g_return_if_fail (tmpdate != NULL);

    if (appGUI->calendar_only == TRUE) return;

    gui_calendar_clear_marks (GUI_CALENDAR (appGUI->cal->calendar), DAY_NOTE_MARK);
    gui_calendar_clear_marks (GUI_CALENDAR (appGUI->cal->calendar), EVENT_MARK);
    gui_calendar_clear_marks (GUI_CALENDAR (appGUI->cal->calendar), BIRTHDAY_MARK);

    if (config.enable_day_mark == FALSE) return;

    days = utl_date_get_days_in_month (tmpdate);

    for (i = 1; i <= days; i++) {
        g_date_set_day (tmpdate, i);

        if (cal_check_note (g_date_get_julian (tmpdate), appGUI) == TRUE) {
            gui_calendar_set_day_color (GUI_CALENDAR (appGUI->cal->calendar), i, 
                                        cal_get_note_color (g_date_get_julian (tmpdate), appGUI));
        }

        calendar_mark_events (appGUI->cal->calendar, g_date_get_julian (tmpdate), i, appGUI);
    }

    g_date_free (tmpdate);
}

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

void
cal_refresh_marks (GUI *appGUI)
{
    cal_mark_days_with_notes (appGUI->cal->date, appGUI);
}

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

gint
cal_get_marked_days (GDate *date, GUI *appGUI)
{
    guint32 julian;
    gint i, n, days;

    julian = utl_date_dmy_to_julian (1, g_date_get_month (date), g_date_get_year (date));
    days = utl_date_get_days_in_month (date);

    n = 0;

    for (i = 0; i < days; i++)
        if (cal_check_note (julian + i, appGUI) == TRUE)
            n++;

    return n;
}

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

gint
get_marked_days (guint month, guint year, GUI *appGUI)
{
    guint32 julian;
    gint i, n, days;

    n = 0;
    days = g_date_get_days_in_month (month + 1, year);
    julian = utl_date_dmy_to_julian (1, month + 1, year);

    for (i = 0; i < days; i++)
        if (cal_check_note (julian + i, appGUI) == TRUE)
            n++;

    return n;
}

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

static void
calendar_store_note (GDate *date, gchar *color, GUI *appGUI)
{
GtkTextBuffer *textbuffer;
gchar *text, *old_text, *old_color;
gboolean note_changed;

    textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview));
    text = utl_gui_text_buffer_get_text_with_tags (GTK_TEXT_BUFFER (textbuffer));
    old_text = cal_get_note(g_date_get_julian(date), appGUI);
    old_color = cal_get_note_color(g_date_get_julian(date),appGUI);
    note_changed = (text && old_text && g_utf8_collate(text, old_text))
            || (text && !old_text && g_utf8_strlen (text, -1))
            || (!text && old_text && g_utf8_strlen (old_text, -1))
            || (color && old_color && g_utf8_collate(color, old_color))
            || (color && !old_color)
            || (!color && old_color);

    if (text != NULL && note_changed) {
        if (g_utf8_strlen (text, -1)) {
            cal_add_note (g_date_get_julian (date), color, text, appGUI);
        } else {
            cal_remove_note (g_date_get_julian (date), appGUI);
        }

        g_free (text);
    }
    if (config.save_data_after_modification && note_changed) {
        cal_write_notes(appGUI);
    }
}

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

void
cal_mark_events (GtkWidget *calendar, GDate *date, GUI *appGUI)
{
guint month, year;
guint i, days;
GDate *tmpdate;

    if (appGUI->calendar_only == TRUE) return;

    tmpdate = g_date_new_julian (g_date_get_julian (date));

    month = g_date_get_month (tmpdate) - 1;
    year = g_date_get_year (tmpdate);

    gui_calendar_select_day (GUI_CALENDAR (calendar), 1);
    gui_calendar_select_month (GUI_CALENDAR (calendar), month, year);
    gui_calendar_clear_marks (GUI_CALENDAR (calendar), DAY_NOTE_MARK);
    gui_calendar_clear_marks (GUI_CALENDAR (calendar), EVENT_MARK);
    gui_calendar_clear_marks (GUI_CALENDAR (calendar), BIRTHDAY_MARK);

    if (config.enable_day_mark == FALSE) return;

    days = utl_date_get_days_in_month (tmpdate);

    for (i = 1; i <= days; i++) {
        g_date_set_day (tmpdate, i);

        if (cal_check_note (g_date_get_julian (tmpdate), appGUI) == TRUE) {
            gui_calendar_set_day_color (GUI_CALENDAR (calendar), i, cal_get_note_color (g_date_get_julian (tmpdate), appGUI));
        }

        calendar_mark_events (calendar, g_date_get_julian (tmpdate), i, appGUI);
    }

    g_date_free (tmpdate);
}

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

void
mark_events (GtkWidget *calendar, guint month, guint year, GUI *appGUI)
{
    guint32 julian;
    guint i, days;

    if (appGUI->calendar_only == TRUE) return;

    gui_calendar_select_month (GUI_CALENDAR (calendar), month, year);
    gui_calendar_select_day (GUI_CALENDAR (calendar), 1);
    gui_calendar_clear_marks (GUI_CALENDAR (calendar), DAY_NOTE_MARK);
    gui_calendar_clear_marks (GUI_CALENDAR (calendar), EVENT_MARK);
    gui_calendar_clear_marks (GUI_CALENDAR (calendar), BIRTHDAY_MARK);

    if (config.enable_day_mark == FALSE) return;

    days = g_date_get_days_in_month (month + 1, year);

    for (i = 1; i <= days; i++) {
        julian = utl_date_dmy_to_julian (i, month + 1, year);
        if (cal_check_note (julian, appGUI) == TRUE) {
            gui_calendar_set_day_color (GUI_CALENDAR (calendar), i, cal_get_note_color (julian, appGUI));
        }
        calendar_mark_events (calendar, julian, i, appGUI);
    }
}

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

void
update_aux_calendars (GUI *appGUI)
{
gchar buffer[BUFFER_SIZE];
GDate *tmpdate;

    if (appGUI->calendar_only == TRUE) return;

    if (!config.gui_layout) {
        if (appGUI->calendar_only == TRUE || config.enable_auxiliary_calendars == FALSE ||
            config.auxiliary_calendars_state == FALSE) return;
    }

    tmpdate = g_date_new ();
    g_return_if_fail (tmpdate != NULL);

    g_date_set_julian (tmpdate, g_date_get_julian (appGUI->cal->date));
    g_date_subtract_months (tmpdate, 1);
    g_date_strftime (buffer, BUFFER_SIZE, "%B %Y", tmpdate);
    gtk_label_set_text (GTK_LABEL (appGUI->cal->prev_month_label), buffer);
    cal_mark_events (appGUI->cal->calendar_prev, tmpdate, appGUI);

    g_date_set_julian (tmpdate, g_date_get_julian (appGUI->cal->date));
    g_date_add_months (tmpdate, 1);
    g_date_strftime (buffer, BUFFER_SIZE, "%B %Y", tmpdate);
    gtk_label_set_text (GTK_LABEL (appGUI->cal->next_month_label), buffer);
    cal_mark_events (appGUI->cal->calendar_next, tmpdate, appGUI);

    g_date_free (tmpdate);
}

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

#ifdef TASKS_ENABLED

gint
check_add_tasks (GDate *date, gboolean count, gchar **html, GUI *appGUI)
{
GtkTreePath *path;
GtkTreeIter iter;
GtkTreeModel *model;
guint32 julian, sjulian;
gboolean done;
gint time;
gchar *summary, *category;
gchar tmpbuf[BUFFER_SIZE];
gint i;

    model = GTK_TREE_MODEL (appGUI->tsk->tasks_list_store);
    g_return_val_if_fail (model != NULL, 0);

    path = gtk_tree_path_new_first ();
    sjulian = g_date_get_julian (date);
    i = 0;

    while (gtk_tree_model_get_iter (model, &iter, path) == TRUE) {
        gtk_tree_model_get (model, &iter, TA_COLUMN_DUE_DATE_JULIAN, &julian, TA_COLUMN_CATEGORY, &category, -1);

        if (julian == sjulian && tsk_get_category_state (category, STATE_CALENDAR, appGUI) == TRUE) {
            if (count == FALSE) {
                gtk_tree_model_get (model, &iter, TA_COLUMN_DUE_TIME, &time, TA_COLUMN_DONE, &done,
                                    TA_COLUMN_SUMMARY, &summary, -1);

                if (time >= 0) {
                    g_snprintf (tmpbuf, BUFFER_SIZE, "%d. [%02d:%02d] %s", i + 1, time / 3600, time / 60 % 60, summary);
                } else {
                    g_snprintf (tmpbuf, BUFFER_SIZE, "%d. %s", i + 1, summary);
                }

                if (html != NULL) {
            
                    if (done == TRUE) {
                        *(html) = utl_strconcat (*(html), "<s>", tmpbuf, "</s><br />", NULL);
                    } else {
                        *(html) = utl_strconcat (*(html), tmpbuf, "<br />", NULL);
                    }

                } else {
                    if (done == TRUE) {
                        gtk_text_buffer_insert_with_tags_by_name (appGUI->cal->day_desc_text_buffer,
                                                                  &appGUI->cal->day_desc_iter, tmpbuf, -1, "strike", NULL);
                    } else {
                        gtk_text_buffer_insert (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter, tmpbuf, -1);
                    }
                    gtk_text_buffer_insert (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter, "\n", -1);
                }

                g_free (summary);
            }
            i++;
        }

        g_free (category);
        gtk_tree_path_next (path);
    }
    gtk_tree_path_free (path);

    return i;
}

#endif  /* TASKS_ENABLED */

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

#ifdef CONTACTS_ENABLED

gint
check_add_contacts (GDate *sdate, gboolean count, gchar **html, GUI *appGUI)
{
GtkTreePath *path;
GtkTreeIter iter;
GtkTreeModel *model;
guint32 julian;
gchar *first_name, *last_name;
gchar tmpbuf[BUFFER_SIZE], buffer[BUFFER_SIZE];
GDate *date;
gint i, age, syear;

    model = GTK_TREE_MODEL (appGUI->cnt->contacts_list_store);
    g_return_val_if_fail (model != NULL, 0);

    date = g_date_new ();
    g_return_val_if_fail (date != NULL, 0);

    syear = g_date_get_year (sdate);
    path = gtk_tree_path_new_first ();
    i = 0;

    while (gtk_tree_model_get_iter (model, &iter, path) == TRUE) {
        gtk_tree_model_get (model, &iter, COLUMN_BIRTH_DAY_DATE, &julian, -1);

        if (g_date_valid_julian (julian)) {
            g_date_set_julian (date, julian);
            age = syear - g_date_get_year (date);

            if (age >= 0) {
                if (g_date_valid_dmy (g_date_get_day (date), g_date_get_month (date), syear) == FALSE) {
                    g_date_subtract_days (date, 1);
                }
                g_date_set_year (date, syear);

                if (g_date_compare (date, sdate) == 0) {

                    if (count == FALSE) {
                        gtk_tree_model_get (model, &iter, COLUMN_FIRST_NAME, &first_name, COLUMN_LAST_NAME, &last_name, -1);
                        utl_name_strcat (first_name, last_name, buffer);

                        if (age == 0) {
                            g_snprintf (tmpbuf, BUFFER_SIZE, "%s %s\n", buffer, _("was born"));
                        } else {
                            g_snprintf (tmpbuf, BUFFER_SIZE, "%s (%d %s)\n", buffer, age,
                                        ngettext ("year old", "years old", age));
                        }

                        if (html != NULL) {
                            *(html) = utl_strconcat (*(html), tmpbuf, NULL);
                        } else {
                            gtk_text_buffer_insert (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter, tmpbuf, -1);
                        }
                    }
                    i++;
                }
            }
        }
        gtk_tree_path_next (path);
    }
    gtk_tree_path_free (path);
    g_date_free (date);

    return i;
}

#endif /* CONTACTS_ENABLED */

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

gchar *
cal_get_day_category (GDate *date, GUI *appGUI)
{
GtkTreeIter iter;
static gchar buffer[BUFFER_SIZE];
gchar *color_val, *color_name, *color_sel;
gboolean has_next;

    buffer[0] = '\0';
    color_sel = cal_get_note_color (g_date_get_julian (date), appGUI);
    if (color_sel == NULL) return buffer;

    has_next = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (appGUI->opt->calendar_category_store), &iter);
    while (has_next) {
        gtk_tree_model_get (GTK_TREE_MODEL (appGUI->opt->calendar_category_store), &iter, 1, &color_val, 2, &color_name, -1);

        if (!strcmp (color_val, color_sel)) {
            g_snprintf (buffer, BUFFER_SIZE, "%s", color_name);
            g_free (color_val);
            g_free (color_name);
            break;
        }

        g_free (color_val);
        g_free (color_name);
        has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (appGUI->opt->calendar_category_store), &iter);
    }

    return buffer;
}

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

void
update_clock (GUI *appGUI)
{
#ifdef HAVE_LIBWEBKIT
    if (config.di_show_current_time) {
        cal_set_day_info (appGUI);
    }

#else

    gchar *tstr, *text;

    tstr = utl_time_print_default (utl_time_get_current_seconds (), config.di_show_current_time_seconds);
    text = g_strdup_printf ("<tt>%s</tt>", tstr);
    if (appGUI->cal->time_label) {
        gtk_label_set_markup (GTK_LABEL (appGUI->cal->time_label), text);
    }
    g_free (tstr);
    g_free (text);

#endif  /* HAVE_LIBWEBKIT */
}

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

void
cal_set_day_info (GUI *appGUI)
{
static guint cmonth = 0;
gchar tmpbuf[BUFFER_SIZE];
GDate *date;
guint dday, dmonth, dyear;
gint edays, i;
gchar *text;
    
    date = appGUI->cal->date;

    dday = g_date_get_day (date);
    dmonth = g_date_get_month (date) - 1;
    dyear = g_date_get_year (date);

#ifdef HAVE_LIBWEBKIT

gchar *output = g_strdup ("");
/*gchar *icon;*/
/*const guint8 *moon_icon;*/

    /*moon_icon = cal_get_moon_icon (utl_calc_moon_phase (date));*/
    /*icon = utl_inline_image_to_html (moon_icon);*/

    output = utl_strconcat (output, "<html><head>", NULL);
    output = utl_strconcat (output, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />", NULL);
    output = utl_strconcat (output, "<style type=\"text/css\">", NULL);
    output = utl_strconcat (output, "body {", NULL);

    output = utl_strconcat (output, "line-height: 145\%; ", NULL);
    output = utl_strconcat (output, "font-family: ", pango_font_description_get_family (appGUI->cal->fd_notes_font), NULL);
    output = utl_strconcat (output, "}", NULL);
    output = utl_strconcat (output, "table { width: 100\%; vertical-align: middle; text-align: left; }", NULL);
    output = utl_strconcat (output, "img { vertical-align: middle; }", NULL);
    output = utl_strconcat (output, "th { width: 1\%; white-space: pre; }", NULL);
    output = utl_strconcat (output, "</style>", NULL);

    output = utl_strconcat (output, "</head><body>", NULL);
    output = utl_strconcat (output, "<span style=\"white-space: pre-wrap;\">", NULL);

    /* body */
    output = utl_strconcat (output, "<table><tr>", NULL);

    if (config.di_show_current_time) {
        gchar *tstr = utl_time_print_default (utl_time_get_current_seconds (), config.di_show_current_time_seconds);
        g_snprintf (tmpbuf, BUFFER_SIZE, "<th>%s:</th><td>", _("Current time"));
        output = utl_strconcat (output, tmpbuf, tstr, "</td>", NULL);
        g_free (tstr);
    }

    output = utl_strconcat (output, "</tr><tr>", NULL);

    if (config.di_show_day_number) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<th>%s:</th><td>", _("Day number"));
        output = utl_strconcat (output, tmpbuf, NULL);
        g_snprintf (tmpbuf, BUFFER_SIZE, "%d", g_date_get_day_of_year (date));
        output = utl_strconcat (output, tmpbuf, " ", NULL);
        edays = utl_get_days_per_year (g_date_get_year (date)) - g_date_get_day_of_year (date);
        if (edays) {
            g_snprintf (tmpbuf, BUFFER_SIZE, "(%d %s)", edays,
                        ngettext ("day till end of year", "days till end of year", edays));
        } else {
            g_snprintf (tmpbuf, BUFFER_SIZE, "(%s)", _("the last day of the year"));
        }
        output = utl_strconcat (output, tmpbuf, "</td>", NULL);
    }

    output = utl_strconcat (output, "</tr><tr>", NULL);

    if (config.di_show_current_day_distance) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<th>%s:</th><td>", _("Today distance"));
        output = utl_strconcat (output, tmpbuf, 
                              get_current_date_distance_str (g_date_get_julian (date)),
                              "</td>", NULL);
    }

    output = utl_strconcat (output, "</tr><tr>", NULL);

    if (config.di_show_week_number) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<th>%s:</th><td>", _("Week number"));
        output = utl_strconcat (output, tmpbuf, NULL);

        if (utl_get_week_number (dyear, dmonth + 1, dday) > utl_weeks_in_year (dyear)) {
            g_snprintf (tmpbuf, BUFFER_SIZE, "1 / %d", utl_weeks_in_year (dyear+1));
        } else {
            g_snprintf (tmpbuf, BUFFER_SIZE, "%d / %d", utl_get_week_number (dyear, dmonth+1, dday), utl_weeks_in_year (dyear));
        }
        output = utl_strconcat (output, tmpbuf, "</td>", NULL);
    }

    output = utl_strconcat (output, "</tr><tr>", NULL);
        
    if (config.di_show_marked_days) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<th>%s:</th><td>", _("Marked days"));
        output = utl_strconcat (output, tmpbuf, NULL);
        g_snprintf (tmpbuf, BUFFER_SIZE, "%d", get_marked_days (g_date_get_month (date)-1, g_date_get_year (date), appGUI));
        output = utl_strconcat (output, tmpbuf, "</td>", NULL);
    }

    output = utl_strconcat (output, "</tr><tr>", NULL);

    if (config.di_show_weekend_days) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<th>%s:</th><td>", _("Weekend days"));
        output = utl_strconcat (output, tmpbuf, NULL);
        g_snprintf (tmpbuf, BUFFER_SIZE, "%d", utl_get_weekend_days_in_month (date));
        output = utl_strconcat (output, tmpbuf, "</td>", NULL);
    }

    output = utl_strconcat (output, "</tr><tr>", NULL);

    if (config.di_show_moon_phase) {
        gchar *img;
        g_snprintf (tmpbuf, BUFFER_SIZE, "<th>%s:</th><td>", _("Moon phase"));
        output = utl_strconcat (output, tmpbuf, NULL);
        img = cal_get_moonphase_img(utl_calc_moon_phase (date));
        g_snprintf (tmpbuf, BUFFER_SIZE, "%s (%s)", 
					img,
					utl_get_moon_phase_name (utl_calc_moon_phase (date)));
        g_free(img);
        output = utl_strconcat (output, tmpbuf, "</td>", NULL);
    }

    output = utl_strconcat (output, "</tr><tr>", NULL);

    if (config.di_show_zodiac_sign) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<th>%s:</th><td>", _("Zodiac sign"));
        output = utl_strconcat (output, tmpbuf, 
                              utl_get_zodiac_name (g_date_get_day (date), g_date_get_month (date)),
                              "</td>", NULL);
    }

    output = utl_strconcat (output, "</tr></table>", NULL);

    if (config.di_show_notes && config.enable_day_mark) {
        text = cal_get_note (g_date_get_julian (date), appGUI);

        if (text != NULL) {
            g_snprintf (tmpbuf, BUFFER_SIZE, "%s:\n", _("Day notes"));
            output = utl_strconcat (output, "<p><b>", tmpbuf, "</b>", NULL);
            gchar *txt = utl_text_with_tags_to_html (text);

            if (g_date_get_julian (date) < utl_date_get_current_julian () && config.strikethrough_past_notes == TRUE) {
                output = utl_strconcat (output, "<s>", txt, "</s></p>", NULL);
            } else {
                output = utl_strconcat (output, txt, "</p>", NULL);
            }

            g_free (txt);
        }
    }

    if (appGUI->calendar_only != TRUE && appGUI->all_pages_added != FALSE && config.enable_day_mark) {

#ifdef TASKS_ENABLED
        /* check tasks */
        i = check_add_tasks (date, TRUE, NULL, appGUI);

        if (i) {
            g_snprintf (tmpbuf, BUFFER_SIZE, "%s:\n", _("Day tasks"));
            output = utl_strconcat (output, "<p><b>", tmpbuf, "</b>", NULL);
            check_add_tasks (date, FALSE, &output, appGUI);
            output = utl_strconcat (output, "</p>", NULL);
        }
#endif  /* TASKS_ENABLED */

#ifdef CONTACTS_ENABLED
        /* check contacts */
        i = check_add_contacts (date, TRUE, NULL, appGUI);

        if (i) {
            g_snprintf (tmpbuf, BUFFER_SIZE, "%s:\n", _("Birthday"));
            output = utl_strconcat (output, "<p><b>", tmpbuf, "</b>", NULL);
            check_add_contacts (date, FALSE, &output, appGUI);
            output = utl_strconcat (output, "</p>", NULL);
        }
#endif  /* CONTACTS_ENABLED */

    }

#ifdef HAVE_LIBICAL
    output = utl_strconcat (output, "<p>", NULL);
    calendar_display_ics (date, &output, appGUI);
    output = utl_strconcat (output, "</p>", NULL);
#endif  /* HAVE_LIBICAL */

    output = utl_strconcat (output, "</span>", NULL);

    output = utl_strconcat (output, "</body></html>", NULL);

#ifndef HAVE_LIBWEBKIT
    g_free (icon);
#endif

    webkit_settings_set_default_font_size (webkit_web_view_get_settings(appGUI->cal->html_webkitview), PANGO_PIXELS(pango_font_description_get_size (appGUI->cal->fd_notes_font)));
    webkit_web_view_load_html (appGUI->cal->html_webkitview, output, "file://");

    g_free (output);

#else

GtkTextChildAnchor *anchor = NULL;
GtkWidget *table = NULL, *label;
gint rows;
gchar *stripped;
gchar *day_category;

    day_category = cal_get_day_category (date, appGUI);

    utl_gui_clear_text_buffer (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter);

    rows = config.di_show_current_time + config.di_show_day_number + config.di_show_marked_days + 
           config.di_show_week_number + config.di_show_weekend_days + config.di_show_moon_phase +
           config.di_show_zodiac_sign + config.di_show_current_day_distance + config.di_show_day_category;

    if (rows != 0) {
        anchor = gtk_text_buffer_create_child_anchor (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter);
        table = gtk_grid_new ();
        gtk_widget_show (table);
        gtk_grid_set_row_spacing (GTK_GRID (table), 4);
        gtk_grid_set_column_spacing (GTK_GRID (table), 8);
    }

    i = 0;

    if (config.di_show_current_time) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Current time"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_day_number) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Day number"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_current_day_distance) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Today distance"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_week_number) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Week number"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_marked_days) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Marked days"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_weekend_days) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Weekend days"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_day_category && g_utf8_strlen (day_category, -1) && config.enable_day_mark) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Day category"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_moon_phase) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Moon phase"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_zodiac_sign) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Zodiac sign"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 0, i, 1, 1);
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
    }

    i = 0;

    appGUI->cal->time_label = gtk_label_new (NULL);
    if (config.di_show_current_time) {
        update_clock (appGUI);
        gtk_widget_show (appGUI->cal->time_label);
        gtk_grid_attach (GTK_GRID (table), appGUI->cal->time_label, 1, i, 2, 1);
        gtk_widget_set_valign(appGUI->cal->time_label, GTK_ALIGN_START);
        gtk_widget_set_halign(appGUI->cal->time_label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_day_number) {
        appGUI->cal->day_number_label = gtk_label_new (NULL);
        gtk_widget_show (appGUI->cal->day_number_label);
        gtk_grid_attach (GTK_GRID (table), appGUI->cal->day_number_label, 1, i, 1, 1);
        gtk_widget_set_valign(appGUI->cal->day_number_label, GTK_ALIGN_START);
        gtk_widget_set_halign(appGUI->cal->day_number_label, GTK_ALIGN_CENTER);

        appGUI->cal->day_number_year_label = gtk_label_new (NULL);
        gtk_widget_show (appGUI->cal->day_number_year_label);
        gtk_grid_attach (GTK_GRID (table), appGUI->cal->day_number_year_label, 2, i, 1, 1);
        gtk_widget_set_valign(appGUI->cal->day_number_year_label, GTK_ALIGN_START);
        gtk_widget_set_halign(appGUI->cal->day_number_year_label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_current_day_distance) {
        label = gtk_label_new (NULL);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 1, i, 2, 1);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
        gtk_label_set_text (GTK_LABEL (label), get_current_date_distance_str (g_date_get_julian (date)));
        i++;
    }

    if (config.di_show_week_number) {
        appGUI->cal->week_number_label = gtk_label_new (NULL);
        gtk_widget_show (appGUI->cal->week_number_label);
        gtk_grid_attach (GTK_GRID (table), appGUI->cal->week_number_label, 1, i, 2, 1);
        gtk_widget_set_valign(appGUI->cal->week_number_label, GTK_ALIGN_START);
        gtk_widget_set_halign(appGUI->cal->week_number_label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_marked_days) {
        appGUI->cal->marked_days_label = gtk_label_new (NULL);
        gtk_widget_show (appGUI->cal->marked_days_label);
        gtk_grid_attach (GTK_GRID (table), appGUI->cal->marked_days_label, 1, i, 2, 1);
        gtk_widget_set_valign(appGUI->cal->marked_days_label, GTK_ALIGN_START);
        gtk_widget_set_halign(appGUI->cal->marked_days_label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_weekend_days) {
        appGUI->cal->weekend_days_label = gtk_label_new (NULL);
        gtk_widget_show (appGUI->cal->weekend_days_label);
        gtk_grid_attach (GTK_GRID (table), appGUI->cal->weekend_days_label, 1, i, 2, 1);
        gtk_widget_set_valign(appGUI->cal->weekend_days_label, GTK_ALIGN_START);
        gtk_widget_set_halign(appGUI->cal->weekend_days_label, GTK_ALIGN_CENTER);
        i++;
    }

    if (config.di_show_day_category && g_utf8_strlen (day_category, -1) && config.enable_day_mark) {
        appGUI->cal->day_category_label = gtk_label_new (NULL);
        gtk_widget_show (appGUI->cal->day_category_label);
        gtk_grid_attach (GTK_GRID (table), appGUI->cal->day_category_label, 1, i, 2, 1);
        gtk_widget_set_valign(appGUI->cal->day_category_label, GTK_ALIGN_START);
        gtk_widget_set_halign(appGUI->cal->day_category_label, GTK_ALIGN_CENTER);
        i++;
    }

#ifndef HAVE_LIBWEBKIT
    if (config.di_show_moon_phase) {
        appGUI->cal->moon_icon = gtk_image_new();
        gtk_widget_show (appGUI->cal->moon_icon);
        gtk_grid_attach (GTK_GRID (table), appGUI->cal->moon_icon, 1, i, 1, 1);
        gtk_widget_set_valign(appGUI->cal->moon_icon, GTK_ALIGN_START);
        gtk_widget_set_halign(appGUI->cal->moon_icon, GTK_ALIGN_CENTER);

        appGUI->cal->moon_phase_label = gtk_label_new (NULL);
        gtk_widget_show (appGUI->cal->moon_phase_label);
        gtk_grid_attach (GTK_GRID (table), appGUI->cal->moon_phase_label, 2, i, 1, 1);
        gtk_widget_set_valign(appGUI->cal->moon_phase_label, GTK_ALIGN_START);
        gtk_widget_set_halign(appGUI->cal->moon_phase_label, GTK_ALIGN_CENTER);

        cal_set_moon_icon (utl_calc_moon_phase (date), appGUI);
        i++;
    }
#endif

    if (config.di_show_zodiac_sign) {
        label = gtk_label_new (NULL);
        gtk_widget_show (label);
        gtk_grid_attach (GTK_GRID (table), label, 1, i, 2, 1);
        gtk_widget_set_valign(label, GTK_ALIGN_START);
        gtk_widget_set_halign(label, GTK_ALIGN_CENTER);
        gtk_label_set_text (GTK_LABEL (label), utl_get_zodiac_name (g_date_get_day (date), g_date_get_month (date)));
    }

    if (config.di_show_day_number) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "%d", g_date_get_day_of_year (date));
        gtk_label_set_text (GTK_LABEL (appGUI->cal->day_number_label), tmpbuf);

        edays = utl_get_days_per_year (g_date_get_year (date)) - g_date_get_day_of_year (date);
        if (edays) {
            g_snprintf (tmpbuf, BUFFER_SIZE, "(%d %s)", edays,
                        ngettext ("day till end of year", "days till end of year", edays));
        } else {
            g_snprintf (tmpbuf, BUFFER_SIZE, "(%s)", _("the last day of the year"));
        }
        gtk_label_set_text (GTK_LABEL (appGUI->cal->day_number_year_label), tmpbuf);
    }

    if (config.di_show_week_number) {
        if (utl_get_week_number (dyear, dmonth + 1, dday) > utl_weeks_in_year (dyear)) {
            g_snprintf (tmpbuf, BUFFER_SIZE, "1 / %d", utl_weeks_in_year (dyear+1));
        } else {
            g_snprintf (tmpbuf, BUFFER_SIZE, "%d / %d", utl_get_week_number (dyear, dmonth+1, dday), utl_weeks_in_year (dyear));
        }
        gtk_label_set_text (GTK_LABEL (appGUI->cal->week_number_label), tmpbuf);
    }

    if (config.di_show_marked_days) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "%d", get_marked_days (g_date_get_month (date)-1, g_date_get_year (date), appGUI));
        gtk_label_set_text (GTK_LABEL (appGUI->cal->marked_days_label), tmpbuf);
    }

    if (config.di_show_weekend_days) {
        g_snprintf (tmpbuf, BUFFER_SIZE, "%d", utl_get_weekend_days_in_month (date));
        gtk_label_set_text (GTK_LABEL (appGUI->cal->weekend_days_label), tmpbuf);
    }

    if (config.di_show_day_category && g_utf8_strlen (day_category, -1) && config.enable_day_mark) {
        gtk_label_set_text (GTK_LABEL (appGUI->cal->day_category_label), day_category);
    }

    if (rows != 0) {
        gtk_text_view_add_child_at_anchor (GTK_TEXT_VIEW(appGUI->cal->day_desc_textview), table, anchor);
        gtk_text_buffer_insert (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter, "\n\n", -1);
    }

    if (config.di_show_notes && config.enable_day_mark) {
        text = cal_get_note (g_date_get_julian (date), appGUI);

        if (text != NULL) {
            g_snprintf (tmpbuf, BUFFER_SIZE, "%s:\n", _("Day notes"));
            gtk_text_buffer_insert_with_tags_by_name (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter,
                                                      tmpbuf, -1, "bold", NULL);

            if (g_date_get_julian (date) < utl_date_get_current_julian () && config.strikethrough_past_notes == TRUE) {
                stripped = utl_gui_text_strip_tags (text);
                gtk_text_buffer_insert_with_tags_by_name (appGUI->cal->day_desc_text_buffer,
                                                          &appGUI->cal->day_desc_iter, stripped, -1, "strike", NULL);
                g_free (stripped);
            } else {
                utl_gui_text_buffer_set_text_with_tags (appGUI->cal->day_desc_text_buffer, text, FALSE);
                gtk_text_buffer_get_end_iter (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter);
            }

            if (text[g_utf8_strlen (text, -1) - 1] != '\n') {
                gtk_text_buffer_insert (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter, "\n\n", -1);
            } else {
                gtk_text_buffer_insert (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter, "\n", -1);
            }
        }

    }

    if (appGUI->calendar_only != TRUE && appGUI->all_pages_added != FALSE && config.enable_day_mark) {

#ifdef TASKS_ENABLED
        /* check tasks */
        i = check_add_tasks (date, TRUE, NULL, appGUI);

        if (i) {
            g_snprintf (tmpbuf, BUFFER_SIZE, "%s:\n", _("Day tasks"));
            gtk_text_buffer_insert_with_tags_by_name (appGUI->cal->day_desc_text_buffer,
                                                      &appGUI->cal->day_desc_iter, tmpbuf, -1, "bold", NULL);
            check_add_tasks (date, FALSE, NULL, appGUI);
            gtk_text_buffer_insert (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter, "\n", -1);
        }
#endif  /* TASKS_ENABLED */

#ifdef CONTACTS_ENABLED
        /* check contacts */
        i = check_add_contacts (date, TRUE, NULL, appGUI);

        if (i) {
            g_snprintf (tmpbuf, BUFFER_SIZE, "%s:\n", _("Birthday"));
            gtk_text_buffer_insert_with_tags_by_name (appGUI->cal->day_desc_text_buffer,
                                                      &appGUI->cal->day_desc_iter, tmpbuf, -1, "bold", NULL);
            check_add_contacts (date, FALSE, NULL, appGUI);
            gtk_text_buffer_insert (appGUI->cal->day_desc_text_buffer, &appGUI->cal->day_desc_iter, "\n", -1);
        }
#endif  /* CONTACTS_ENABLED */

    }

#ifdef HAVE_LIBICAL
    calendar_display_ics (date, NULL, appGUI);
#endif  /* HAVE_LIBICAL */

#endif  /* HAVE_LIBWEBKIT */

    if (cmonth != g_date_get_month (date)) {
        cmonth = g_date_get_month (date);
        update_aux_calendars (appGUI);
    }
}

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

static void
calendar_display_note (GDate *date, GUI *appGUI)
{
GtkTextBuffer *textbuffer;
GtkTextIter iter_start, iter_end;
gchar *t;

    textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview));
    t = cal_get_note (g_date_get_julian (date), appGUI);

    if (t != NULL) {
        utl_gui_text_buffer_set_text_with_tags (GTK_TEXT_BUFFER (textbuffer), t, TRUE);
    } else {
        gtk_text_buffer_get_start_iter (GTK_TEXT_BUFFER (textbuffer), &iter_start);
        gtk_text_buffer_get_end_iter (GTK_TEXT_BUFFER (textbuffer), &iter_end);
        gtk_text_buffer_delete (GTK_TEXT_BUFFER (textbuffer), &iter_start, &iter_end);
    }
}

/*------------------------------------------------------------------------------*/
void
cal_refresh_notes(GUI *appGUI) {
    cal_refresh_marks(appGUI);
    calendar_display_note(appGUI->cal->date, appGUI);
    cal_set_day_info(appGUI);
    enable_disable_note_buttons(appGUI);
}

/*------------------------------------------------------------------------------*/
static void
calendar_update_note(guint32 note_date_julian, GUI *appGUI) {
    if (appGUI->calendar_only == FALSE) {
        GDate *note_date = g_date_new_julian(note_date_julian);

        calendar_store_note(note_date, cal_get_note_color(note_date_julian, appGUI), appGUI);
        cal_refresh_notes(appGUI);
        g_date_free(note_date);
    }
}

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

void
day_notes_toggled_cb (GtkToggleToolButton *togglebutton, gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;

    config.day_notes_visible = gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (appGUI->cal->notes_button));

    if (!config.day_notes_visible) {
#ifdef HAVE_GSPELL
        utl_gui_set_enable_spell_check(appGUI->cal->calendar_note_spelltextview, FALSE);
#endif /* HAVE_GSPELL */
        config.enable_day_mark = TRUE;
        calendar_update_note(g_date_get_julian (appGUI->cal->date), appGUI);
        gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview), FALSE);
        gtk_text_view_set_editable (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview), FALSE);
        gtk_widget_hide (appGUI->cal->notes_vbox);
        gtk_widget_show (appGUI->cal->day_info_vbox);
        gui_systray_tooltip_update (appGUI);
    } else {
        /* enable (optionally) spell checker */
#ifdef HAVE_GSPELL
        appGUI->cal->calendar_note_spelltextview = utl_gui_create_spell_check_textview(GTK_TEXT_VIEW(appGUI->cal->calendar_note_textview),
                config.day_note_spell_checker);
#endif /* HAVE_GSPELL */

        gtk_widget_show (appGUI->cal->notes_vbox);
        gtk_widget_hide (appGUI->cal->day_info_vbox);
        gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview), TRUE);
        gtk_text_view_set_editable (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview), TRUE);
        gtk_widget_grab_focus (GTK_WIDGET (appGUI->cal->calendar_note_textview));
    }
}

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

void
cal_set_date (GDate *date, GUI *appGUI)
{
    g_date_set_julian (appGUI->cal->date, g_date_get_julian (date));
    gui_calendar_select_day (GUI_CALENDAR (appGUI->cal->calendar), 1);     /* Trick: always select valid day number */
    gui_calendar_select_month (GUI_CALENDAR (appGUI->cal->calendar), g_date_get_month (date) - 1, g_date_get_year (date));
    gui_calendar_select_day (GUI_CALENDAR (appGUI->cal->calendar), g_date_get_day (date));
    gtk_label_set_text (GTK_LABEL (appGUI->cal->date_label), utl_get_date_name_format (date, config.date_header_format));
}

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

void
cal_jump_to_date(GDate *date, GUI *appGUI) {
    guint32 note_date = g_date_get_julian(appGUI->cal->date);
    appGUI->cal->dont_update = TRUE;
    cal_set_date (date, appGUI);

    calendar_update_note(note_date, appGUI);
    update_aux_calendars(appGUI);

    appGUI->cal->dont_update = FALSE;
}
/*------------------------------------------------------------------------------*/

void
calendar_set_today(GUI *appGUI) {
    GDate *date = g_date_new();

    g_date_set_time_t(date, time(NULL));
    cal_jump_to_date(date, appGUI);
    g_date_free(date);
}

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

void
calendar_close_text_cb (GtkWidget *widget, gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;

    gtk_widget_hide (appGUI->cal->notes_vbox);
    gtk_widget_show (appGUI->cal->day_info_vbox);
    gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (appGUI->cal->notes_button), FALSE);
    gtk_widget_grab_focus (GTK_WIDGET (appGUI->cal->calendar));
}

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

gchar *
calendar_get_note_text (GUI *appGUI)
{
GtkTextBuffer *textbuffer;

    if (appGUI->calendar_only == TRUE) return NULL;

    textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview));
    return utl_gui_text_buffer_get_text_with_tags (GTK_TEXT_BUFFER (textbuffer));
}

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

void
calendar_clear_text_cb (GtkWidget *widget, gpointer user_data)
{
    gchar *text = NULL;
    gchar tmpbuf[BUFFER_SIZE];
    gint response;

    GUI *appGUI = (GUI *) user_data;
    text = calendar_get_note_text (appGUI);
    if (text == NULL) return;
    if (!g_utf8_strlen (text, -1)) {
        g_free (text);
        return;
    }

    g_snprintf (tmpbuf, BUFFER_SIZE, "%s\n\n%s", _("Selected day note will be removed."), _("Continue?"));
    response = utl_gui_create_dialog (GTK_MESSAGE_QUESTION, tmpbuf, GTK_WINDOW (appGUI->main_window));

    if (response == GTK_RESPONSE_YES) {
        gtk_text_buffer_set_text (GTK_TEXT_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview))), "", -1);
        enable_disable_note_buttons (appGUI);
        calendar_store_note(appGUI->cal->date, NULL, appGUI);
        cal_refresh_notes(appGUI);
        gui_systray_tooltip_update (appGUI);
    }
    g_free (text);
}

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

void
calendar_insert_timeline_cb (GtkWidget *widget, gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;
    calendar_create_insert_timeline_window (appGUI);
}

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

void
calendar_select_color_cb (GtkWidget *widget, gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;
    calendar_create_color_selector_window (FALSE, appGUI);
}

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

void
calendar_update_date (guint day, guint month, guint year, GUI *appGUI)
{
guint max_day;
GDate *date;

    max_day = g_date_get_days_in_month (month, year);

    if (day > max_day)
        day = max_day;

    date = g_date_new_dmy (day, month, year);
    g_return_if_fail (date != NULL);

    cal_jump_to_date (date, appGUI);
    g_date_free (date);
}

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

void
calendar_btn_prev_day(GUI *appGUI) {
    GDate *date = g_date_new();

    gui_calendar_get_gdate(GUI_CALENDAR(appGUI->cal->calendar), date);
    if (g_date_get_julian(date) > 1) {
        if ((g_date_get_day(date) > 1) || (config.display_options & GUI_CALENDAR_NO_MONTH_CHANGE) == FALSE)
            g_date_subtract_days(date, 1);

        cal_jump_to_date(date, appGUI);
    }
    g_date_free(date);
}

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

void
calendar_btn_next_day(GUI *appGUI) {
    GDate *date = g_date_new();

    gui_calendar_get_gdate(GUI_CALENDAR(appGUI->cal->calendar), date);
    if ((g_date_get_day(date) < utl_date_get_days_in_month(date) ||
            (config.display_options & GUI_CALENDAR_NO_MONTH_CHANGE) == FALSE)) {
        g_date_add_days(date, 1);
    }
    cal_jump_to_date(date, appGUI);
    g_date_free(date);
}

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

static void
calendar_btn_today (GUI *appGUI)
{
    calendar_set_today (appGUI);
}
/*------------------------------------------------------------------------------*/

void
calendar_btn_prev_week(GUI *appGUI) {
    GDate *date = g_date_new();

    gui_calendar_get_gdate(GUI_CALENDAR(appGUI->cal->calendar), date);
    if (g_date_get_julian(date) > 7) {
        if ((g_date_get_day(date) > 7) || (config.display_options & GUI_CALENDAR_NO_MONTH_CHANGE) == FALSE)
            g_date_subtract_days(date, 7);

        cal_jump_to_date(date, appGUI);
    }
    g_date_free(date);
}
/*------------------------------------------------------------------------------*/

void
calendar_btn_next_week(GUI *appGUI) {
    GDate *date = g_date_new();

    gui_calendar_get_gdate(GUI_CALENDAR(appGUI->cal->calendar), date);
    if ((g_date_get_day(date + 7) <= utl_date_get_days_in_month(date)) ||
            (config.display_options & GUI_CALENDAR_NO_MONTH_CHANGE) == FALSE) {
        g_date_add_days(date, 7);
    }
    cal_jump_to_date(date, appGUI);
    g_date_free(date);
}
/*------------------------------------------------------------------------------*/

void
calendar_btn_prev_month(GUI *appGUI) {
    GDate *date = g_date_new();

    gui_calendar_get_gdate(GUI_CALENDAR(appGUI->cal->calendar), date);
    if (g_date_get_julian(date) > 31) {
        g_date_subtract_months(date, 1);
        cal_jump_to_date(date, appGUI);
    }
    g_date_free(date);
}
/*------------------------------------------------------------------------------*/

void
calendar_btn_next_month(GUI *appGUI) {
    GDate *date = g_date_new();

    gui_calendar_get_gdate(GUI_CALENDAR(appGUI->cal->calendar), date);
    g_date_add_months(date, 1);
    cal_jump_to_date(date, appGUI);
    g_date_free(date);
}

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

void
calendar_btn_prev_year(GUI *appGUI) {
    GDate *date = g_date_new();

    gui_calendar_get_gdate(GUI_CALENDAR(appGUI->cal->calendar), date);
    if (g_date_get_year(date) > 1) {
        g_date_subtract_years(date, 1);
        cal_jump_to_date(date, appGUI);
    }
    g_date_free(date);
}
/*------------------------------------------------------------------------------*/

void
calendar_btn_next_year(GUI *appGUI) {
    GDate *date = g_date_new();

    gui_calendar_get_gdate(GUI_CALENDAR(appGUI->cal->calendar), date);
    g_date_add_years(date, 1);
    cal_jump_to_date(date, appGUI);
    g_date_free(date);
}

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

void
calendar_day_selected_cb (GuiCalendar *calendar, GUI *appGUI)
{
    guint32 prev_date = g_date_get_julian (appGUI->cal->date);

    if (appGUI->cal->dont_update == FALSE)
        gui_calendar_get_gdate (GUI_CALENDAR (calendar), appGUI->cal->date);

    gtk_label_set_text (GTK_LABEL (appGUI->cal->date_label), utl_get_date_name_format (appGUI->cal->date, config.date_header_format));

    if (appGUI->cal->dont_update == FALSE) {
        calendar_update_note(prev_date, appGUI);
    }


    if (appGUI->calendar_only == FALSE) {
        /* enable/disable 'select day color' popup entry */
        if (cal_check_note (g_date_get_julian (appGUI->cal->date), appGUI) == TRUE) {
            gtk_widget_show (appGUI->cal->popup_menu_select_day_color_entry);
        } else {
            gtk_widget_hide (appGUI->cal->popup_menu_select_day_color_entry);
        }
    }
}

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

void
calendar_dc_day_selected_cb (GuiCalendar *calendar, gpointer user_data) {

    GUI *appGUI = (GUI *)user_data;

    if (appGUI->calendar_only == FALSE) {
        if (!config.day_notes_visible) {
                enable_disable_note_buttons(appGUI);
                gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(appGUI->cal->notes_button), 
                                             !gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(appGUI->cal->notes_button)));
        }
    }
}

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

void
enable_disable_note_buttons (GUI *appGUI)
{
    gboolean state = FALSE;
    gchar *text = calendar_get_note_text (appGUI);

    if (g_utf8_strlen (text, -1))
        state = TRUE;

    gtk_widget_set_sensitive (appGUI->cal->n_clear_button, state);
    gtk_widget_set_sensitive (appGUI->cal->n_select_color_button, state);

    g_free (text);
}

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

gint
calendar_textbuffer_changed_cb (GtkTextBuffer *textbuffer, gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;
    enable_disable_note_buttons (appGUI);

    return FALSE;
}

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

gboolean
click_handler_cb (GtkWidget * widget, GdkEventButton * event, gpointer data) {

    GUI *appGUI = (GUI *)data;

    if ((event->type == GDK_BUTTON_PRESS && event->button == 1) ||    /* LMB */
        (event->type == GDK_BUTTON_PRESS && event->button == 3)) {    /* RMB */
        gtk_menu_popup(GTK_MENU(appGUI->cal->month_selector_menu), NULL, NULL, NULL, NULL, event->button, event->time);
        return TRUE;
    } else if (event->type == GDK_BUTTON_PRESS && event->button == 2) {     /* MMB */
        calendar_update_date (g_date_get_day (appGUI->cal->date), utl_date_get_current_month (),
                              g_date_get_year (appGUI->cal->date), appGUI);
    }
    return FALSE;
}

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

static void
calendar_create_jumpto_window_cb (GtkToolButton *toolbutton, gpointer data)
{
    GUI *appGUI = (GUI *) data;
    calendar_create_jumpto_window (appGUI);
}

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

static void
calendar_create_fullyear_window_cb (GtkToolButton *toolbutton, gpointer data) {

    GUI *appGUI = (GUI *)data;
    calendar_create_fullyear_window (appGUI);
}

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

static void
calendar_create_datecalc_window_cb (GtkToolButton *toolbutton, gpointer data) {

    GUI *appGUI = (GUI *)data;
    calendar_create_calc_window (appGUI);
}

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

static void
calendar_btn_prev_year_cb (GtkToolButton *toolbutton, gpointer data) {

    GUI *appGUI = (GUI *)data;
    calendar_btn_prev_year (appGUI);
}

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

static void
calendar_btn_next_year_cb (GtkToolButton *toolbutton, gpointer data) {

    GUI *appGUI = (GUI *)data;
    calendar_btn_next_year (appGUI);
}

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

static void
calendar_btn_prev_month_cb (GtkToolButton *toolbutton, gpointer data) {

    GUI *appGUI = (GUI *)data;
    calendar_btn_prev_month (appGUI);
}

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

static void
calendar_btn_next_month_cb (GtkToolButton *toolbutton, gpointer data) {

    GUI *appGUI = (GUI *)data;
    calendar_btn_next_month (appGUI);
}

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

static void
calendar_btn_prev_day_cb (GtkToolButton *toolbutton, gpointer data) {

    GUI *appGUI = (GUI *)data;
    calendar_btn_prev_day (appGUI);
}

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

static void
calendar_btn_next_day_cb (GtkToolButton *toolbutton, gpointer data) {

    GUI *appGUI = (GUI *)data;
    calendar_btn_next_day (appGUI);
}

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

static void
calendar_btn_today_cb (GtkToolButton *toolbutton, gpointer data) {

    GUI *appGUI = (GUI *)data;
    calendar_btn_today (appGUI);
}

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

static void
calendar_edit_note_cb (GtkToggleToolButton *toggle_tool_button, gpointer data) {

    GUI *appGUI = (GUI *)data;
    day_notes_toggled_cb (toggle_tool_button, appGUI);
}

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

void
aux_cal_expander_cb (GObject *object, GParamSpec *param_spec, gpointer user_data) {

    GUI *appGUI = (GUI *)user_data;
    config.auxiliary_calendars_state = gtk_expander_get_expanded (GTK_EXPANDER(appGUI->cal->aux_cal_expander));
    update_aux_calendars (appGUI);
}

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

gboolean
mouse_button_click_handler_cb (GtkWidget * widget, GdkEventButton * event, gpointer data) {

    GUI *appGUI = (GUI *)data;

    if (event->type == GDK_BUTTON_PRESS && event->button == 3 && appGUI->calendar_only == FALSE) {    /* RMB */
        gtk_menu_popup(GTK_MENU(appGUI->cal->popup_menu), NULL, NULL, NULL, NULL, event->button, event->time);
        return TRUE;
    }
    return FALSE;
}

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

#ifdef TASKS_ENABLED
void
popup_add_task_entry_selected_cb (gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;
    GDate *date = g_date_new ();

    gui_calendar_get_gdate (GUI_CALENDAR (appGUI->cal->calendar), date);
    tasks_add_edit_dialog_show (FALSE, g_date_get_julian (date), utl_time_get_current_seconds (), appGUI);
    g_date_free (date);
}
#endif  /* TASKS_ENABLED */

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

void
popup_select_day_color_entry_selected_cb (gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;
    calendar_create_color_selector_window (TRUE, appGUI);
}

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

void
popup_browse_notes_cb (gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;
    cal_notes_browser (appGUI);
}

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

#ifdef PRINTING_SUPPORT
static void
calendar_print_cb (GtkToolButton *toolbutton, gpointer data) {

    GUI *appGUI = (GUI *)data;
    calendar_create_print_window (appGUI);
}
#endif /* PRINTING_SUPPORT */

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

#ifdef HAVE_LIBICAL
void
popup_ical_export_cb (gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;
    ical_export (appGUI);
}

void
popup_ical_browse_cb (gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;
    ical_events_browser (appGUI);
}
#endif  /* HAVE_LIBICAL */

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

void
calendar_set_text_attribute_cb (GtkWidget *widget, gpointer user_data) {

GtkTextBuffer *buffer;
gchar *tagname;

    GUI *appGUI = (GUI *)user_data;

    tagname = (gchar*) g_object_get_data (G_OBJECT (widget), "tag");
    buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview));
    utl_gui_text_buffer_toggle_tags (buffer, tagname);
    g_signal_emit_by_name(G_OBJECT(buffer), "changed");
}

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

void
date_selected_cb (GtkCalendar *calendar, gpointer user_data)
{
    GUI *appGUI = (GUI *)user_data;
    GDate *date = g_date_new ();

    if (!config.gui_layout) {
        if (gtk_expander_get_expanded (GTK_EXPANDER(appGUI->cal->aux_cal_expander)) == FALSE) {
            g_date_free (date);
            return;
        }
    }

    gui_calendar_get_gdate (GUI_CALENDAR (calendar), date);
    cal_jump_to_date (date, appGUI);
    g_date_free (date);
}

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

#if defined(BACKUP_SUPPORT) && defined(HAVE_LIBGRINGOTTS)

static void
button_create_backup_cb(GtkToolButton *toolbutton, gpointer data) {
    GUI *appGUI = (GUI *) data;
    backup_create(appGUI);
}

static void
button_restore_backup_cb(GtkToolButton *toolbutton, gpointer data) {
    GUI *appGUI = (GUI *) data;
    backup_restore(appGUI);
}

#endif  /* BACKUP_SUPPORT && HAVE_LIBGRINGOTTS */

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

void
gui_set_calendar_defaults(GtkWidget *calendar) {

    gui_calendar_set_color (GUI_CALENDAR (calendar), 
							config.background_color, 0,  BACKGROUND_COLOR);
    gui_calendar_set_color (GUI_CALENDAR (calendar), 
							config.header_bg_color, 0,  HEADER_BG_COLOR);
    gui_calendar_set_color (GUI_CALENDAR (calendar), 
							config.header_fg_color, 0, HEADER_FG_COLOR);
    gui_calendar_set_color (GUI_CALENDAR (calendar), 
							config.day_color, 0, DAY_COLOR);
    gui_calendar_set_color (GUI_CALENDAR (calendar), 
							config.pf_day_color, 0, PF_DAY_COLOR);
    gui_calendar_set_color (GUI_CALENDAR (calendar), 
							config.weekend_color, 0, WEEKEND_COLOR);
    gui_calendar_set_color (GUI_CALENDAR (calendar), 
							config.selection_color, config.selector_alpha, SELECTOR_COLOR);
	gui_calendar_set_color (GUI_CALENDAR (calendar), 
							config.mark_color, 0, EVENT_MARKER_COLOR);
    gui_calendar_set_color (GUI_CALENDAR (calendar), 
							config.mark_current_day_color, config.mark_current_day_alpha, TODAY_MARKER_COLOR);
    gui_calendar_set_color (GUI_CALENDAR (calendar), 
							config.birthday_mark_color, 0, BIRTHDAY_MARKER_COLOR);
    gui_calendar_set_marker (GUI_CALENDAR (calendar), 
							 config.event_marker_type, EVENT_MARKER);
    gui_calendar_set_marker (GUI_CALENDAR (calendar), 
							 config.today_marker_type, TODAY_MARKER);
    gui_calendar_set_day_note_marker_symbol (GUI_CALENDAR (calendar), 
											 config.day_note_marker);
}

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

void
gui_create_calendar(GtkWidget *notebook, GUI *appGUI) {

GtkWidget       *vbox1;
GtkWidget       *vbox2;
GtkWidget       *vbox3;
GtkWidget       *hbox1 = NULL;
GtkWidget       *hbox2;
GtkWidget       *hbox3;
GtkWidget       *eventbox;
GtkWidget       *hseparator;
GtkWidget       *label;
GtkWidget       *frame;
GtkWidget       *vseparator;
#ifdef PRINTING_SUPPORT
GtkToolItem     *print_button;
#endif /* PRINTING_SUPPORT */
GtkToolItem     *preferences_button, *about_button;
#if defined(BACKUP_SUPPORT) && defined(HAVE_LIBGRINGOTTS)
GtkToolItem     *backup_button, *restore_button;
#endif  /* BACKUP_SUPPORT && HAVE_LIBGRINGOTTS */
GtkWidget       *note_scrolledwindow;
#ifdef TASKS_ENABLED
GtkWidget       *popup_menu_add_task_entry;
#endif  /* TASKS_ENABLED */
GtkWidget       *popup_menu_separator;
GtkWidget       *popup_menu_browse_notes;
GtkTextBuffer   *buffer;

#ifdef HAVE_LIBICAL
GtkWidget       *popup_menu_ical_browse;
GtkWidget       *popup_menu_ical_export;
#endif  /* HAVE_LIBICAL */


gchar tmpbuf[BUFFER_SIZE];

    vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
    gtk_widget_show (vbox1);
    gtk_container_set_border_width (GTK_CONTAINER (vbox1), 0);
    g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s</b>", _("Calendar"));
    gui_add_to_notebook (vbox1, tmpbuf, appGUI);

    appGUI->cal->vbox = GTK_BOX(vbox1);

    if (config.hide_calendar == TRUE) {
        gtk_widget_hide(GTK_WIDGET(appGUI->cal->vbox));
    }

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

    appGUI->cal->calendar_toolbar = GTK_TOOLBAR(gtk_toolbar_new());
    gtk_box_pack_start(GTK_BOX(vbox1), GTK_WIDGET(appGUI->cal->calendar_toolbar), FALSE, FALSE, 0);

    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_PREV_YEAR, _("Previous year"), calendar_btn_prev_year_cb), -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_PREV_MONTH, _("Previous month"), calendar_btn_prev_month_cb), -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_PREV_DAY, _("Previous day"), calendar_btn_prev_day_cb), -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_TODAY, _("Today"), calendar_btn_today_cb), -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_NEXT_DAY, _("Next day"), calendar_btn_next_day_cb), -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_NEXT_MONTH, _("Next month"), calendar_btn_next_month_cb), -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_NEXT_YEAR, _("Next year"), calendar_btn_next_year_cb), -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gtk_separator_tool_item_new(), -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_JUMPTO, _("Jump to date"), calendar_create_jumpto_window_cb), -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_FULLYEAR, _("Full-year calendar"), calendar_create_fullyear_window_cb), -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gui_create_toolbar_button(appGUI, OSMO_STOCK_CALCULATOR, _("Date calculator"), calendar_create_datecalc_window_cb), -1);
#ifdef PRINTING_SUPPORT
    print_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_PRINT, _("Print calendar"), calendar_print_cb);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, print_button, -1);
#endif /* PRINTING_SUPPORT */
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gtk_separator_tool_item_new(), -1);
    appGUI->cal->notes_button = gui_create_toolbar_toggle_button(appGUI, OSMO_STOCK_EDIT_NOTE, _("Toggle day note panel"), calendar_edit_note_cb);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, appGUI->cal->notes_button, -1);
    gui_append_toolbar_spring(appGUI->cal->calendar_toolbar);
#if defined(BACKUP_SUPPORT) && defined(HAVE_LIBGRINGOTTS)
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gtk_separator_tool_item_new(), -1);
    backup_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_BACKUP, _("Backup data"), button_create_backup_cb);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, backup_button, -1);
    restore_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_RESTORE, _("Restore data"), button_restore_backup_cb);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, restore_button, -1);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, gtk_separator_tool_item_new(), -1);
#endif  /* BACKUP_SUPPORT && HAVE_LIBGRINGOTTS */
    preferences_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_PREFERENCES, _("Preferences"), show_preferences_window_cb);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, preferences_button, -1);
    about_button = gui_create_toolbar_button(appGUI, OSMO_STOCK_ABOUT, _("About"), gui_show_about_window_cb);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, about_button, -1);
    appGUI->cal->quit_button = gui_create_toolbar_button(appGUI, "application-exit", _("Quit"), gui_quit_osmo_cb);
    gtk_toolbar_insert(appGUI->cal->calendar_toolbar, appGUI->cal->quit_button, -1);

    gtk_toolbar_set_style (appGUI->cal->calendar_toolbar, GTK_TOOLBAR_ICONS);
    gtk_toolbar_set_icon_size(appGUI->cal->calendar_toolbar, GTK_ICON_SIZE_LARGE_TOOLBAR);
    gtk_widget_show_all(GTK_WIDGET(appGUI->cal->calendar_toolbar));

    if (appGUI->calendar_only == TRUE) {
        gtk_widget_hide(GTK_WIDGET(appGUI->cal->notes_button));
        gtk_widget_set_sensitive(GTK_WIDGET(appGUI->cal->notes_button), FALSE);
#ifdef PRINTING_SUPPORT
        gtk_widget_hide (GTK_WIDGET(print_button));
#endif /* PRINTING_SUPPORT */
        gtk_widget_hide (GTK_WIDGET(preferences_button));
        gtk_widget_hide (GTK_WIDGET(about_button));
#if defined(BACKUP_SUPPORT) && defined(HAVE_LIBGRINGOTTS)
        gtk_widget_hide (GTK_WIDGET(backup_button));
        gtk_widget_hide (GTK_WIDGET(restore_button));
#endif  /* BACKUP_SUPPORT && HAVE_LIBGRINGOTTS */
    }

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

    vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
    gtk_widget_show (vbox2);
    gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0);

    if (config.gui_layout && appGUI->calendar_only == FALSE) {
        hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
        gtk_widget_show (hbox1);
        gtk_box_pack_start (GTK_BOX (vbox2), hbox1, TRUE, TRUE, 0);
    }

    vbox3 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	gtk_widget_set_hexpand (vbox3, FALSE);
	gtk_widget_set_margin_left(vbox3, 8);
	gtk_widget_set_margin_right(vbox3, 8);
	gtk_widget_set_margin_bottom(vbox3, 8);
    gtk_widget_show (vbox3);
    if (appGUI->calendar_only == TRUE) {
            gtk_box_pack_start (GTK_BOX (vbox2), vbox3, TRUE, TRUE, 0);
    } else {
        if (!config.gui_layout) {
            gtk_box_pack_start (GTK_BOX (vbox2), vbox3, TRUE, TRUE, 0);
        } else {
            gtk_box_pack_start (GTK_BOX (hbox1), vbox3, FALSE, FALSE, 0);
        }
    }

    hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_widget_show (hseparator);
    gtk_box_pack_start (GTK_BOX (vbox3), hseparator, FALSE, FALSE, 6);

    eventbox = gtk_event_box_new ();
    gtk_widget_show (eventbox);
    gtk_box_pack_start (GTK_BOX (vbox3), eventbox, FALSE, FALSE, 0);
    g_signal_connect (G_OBJECT(eventbox), "button_press_event", G_CALLBACK(click_handler_cb), appGUI);

    hbox2 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
    gtk_widget_show (hbox2);
    gtk_container_add (GTK_CONTAINER (eventbox), hbox2);

    /* Calendar popup menu */

    if (appGUI->calendar_only == FALSE) {

        appGUI->cal->popup_menu = gtk_menu_new();

#ifdef TASKS_ENABLED
        popup_menu_add_task_entry = gtk_menu_item_new_with_label(_("Add task"));
        gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->cal->popup_menu), popup_menu_add_task_entry);
        g_signal_connect_swapped(G_OBJECT(popup_menu_add_task_entry), "activate", 
                                 G_CALLBACK(popup_add_task_entry_selected_cb), appGUI);
        gtk_widget_show(popup_menu_add_task_entry);
#endif  /* TASKS_ENABLED */

        appGUI->cal->popup_menu_select_day_color_entry = gtk_menu_item_new_with_label(_("Select day color"));
        gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->cal->popup_menu), appGUI->cal->popup_menu_select_day_color_entry);
        g_signal_connect_swapped(G_OBJECT(appGUI->cal->popup_menu_select_day_color_entry), "activate", 
                                 G_CALLBACK(popup_select_day_color_entry_selected_cb), appGUI);
        gtk_widget_show(appGUI->cal->popup_menu_select_day_color_entry);

        popup_menu_separator = gtk_separator_menu_item_new();
        gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->cal->popup_menu), popup_menu_separator);
        gtk_widget_show(popup_menu_separator);

        popup_menu_browse_notes = gtk_menu_item_new_with_label(_("Browse notes"));
        gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->cal->popup_menu), popup_menu_browse_notes);
        g_signal_connect_swapped(G_OBJECT(popup_menu_browse_notes), "activate", 
                                 G_CALLBACK(popup_browse_notes_cb), appGUI);
        gtk_widget_show(popup_menu_browse_notes);

#ifdef HAVE_LIBICAL

        popup_menu_ical_browse = gtk_menu_item_new_with_label(_("Browse iCal events"));
        gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->cal->popup_menu), popup_menu_ical_browse);
        g_signal_connect_swapped(G_OBJECT(popup_menu_ical_browse), "activate", 
                                 G_CALLBACK(popup_ical_browse_cb), appGUI);
        gtk_widget_show(popup_menu_ical_browse);

        popup_menu_separator = gtk_separator_menu_item_new();
        gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->cal->popup_menu), popup_menu_separator);
        gtk_widget_show(popup_menu_separator);

        popup_menu_ical_export = gtk_menu_item_new_with_label(_("Export to iCal file"));
        gtk_menu_shell_append(GTK_MENU_SHELL(appGUI->cal->popup_menu), popup_menu_ical_export);
        g_signal_connect_swapped(G_OBJECT(popup_menu_ical_export), "activate", 
                                 G_CALLBACK(popup_ical_export_cb), appGUI);
        gtk_widget_show(popup_menu_ical_export);

#endif  /* HAVE_LIBICAL */

    }

    appGUI->cal->date_label = gtk_label_new (NULL);
    gtk_widget_show (appGUI->cal->date_label);
    gtk_box_pack_start (GTK_BOX (hbox2), appGUI->cal->date_label, TRUE, FALSE, 8);

    hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_widget_show (hseparator);
    gtk_box_pack_start (GTK_BOX (vbox3), hseparator, FALSE, FALSE, 6); 

    appGUI->cal->calendar = gui_calendar_new ();
    gtk_widget_show (appGUI->cal->calendar);
    gui_calendar_set_cursor_type(GUI_CALENDAR(appGUI->cal->calendar), config.cursor_type);
    gtk_widget_set_can_focus (appGUI->cal->calendar, FALSE);
    gui_calendar_set_display_options (GUI_CALENDAR (appGUI->cal->calendar), config.display_options);
    gtk_widget_override_font (GTK_WIDGET(appGUI->cal->calendar), appGUI->cal->fd_cal_font);
    gtk_box_pack_start (GTK_BOX (vbox3), appGUI->cal->calendar, FALSE, FALSE, 0);
    g_signal_connect (G_OBJECT (appGUI->cal->calendar), "day-selected", 
                      G_CALLBACK (calendar_day_selected_cb), appGUI);
    g_signal_connect (G_OBJECT (appGUI->cal->calendar), "day-selected-double-click", 
                      G_CALLBACK (calendar_dc_day_selected_cb), appGUI);
    g_signal_connect (G_OBJECT(appGUI->cal->calendar), "button_press_event", 
                      G_CALLBACK(mouse_button_click_handler_cb), appGUI);
    gui_calendar_enable_cursor (GUI_CALENDAR (appGUI->cal->calendar), TRUE);
	gui_set_calendar_defaults(appGUI->cal->calendar);

    appGUI->cal->month_selector_menu = gtk_menu_new();
    calendar_create_popup_menu (appGUI->cal->month_selector_menu, appGUI);

    hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_widget_show (hseparator);
    gtk_box_pack_start (GTK_BOX (vbox3), hseparator, FALSE, FALSE, 6);

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

    if (appGUI->calendar_only == FALSE) {

        if (!config.gui_layout) {
            appGUI->cal->aux_cal_expander = gtk_expander_new (_("Previous and next month"));
            gtk_widget_set_can_focus (appGUI->cal->aux_cal_expander, FALSE);
            gtk_box_pack_start (GTK_BOX (vbox3), appGUI->cal->aux_cal_expander, FALSE, TRUE, 0);
        }

        appGUI->cal->aux_calendars_table = gtk_grid_new ();
        if (!config.gui_layout) {
            gtk_container_add (GTK_CONTAINER (appGUI->cal->aux_cal_expander), appGUI->cal->aux_calendars_table);
        } else {
            gtk_box_pack_start (GTK_BOX (vbox3), appGUI->cal->aux_calendars_table, FALSE, TRUE, 0);
        }
        gtk_grid_set_row_spacing (GTK_GRID (appGUI->cal->aux_calendars_table), 4);
        gtk_grid_set_column_spacing (GTK_GRID (appGUI->cal->aux_calendars_table), 4);

        if (config.enable_auxiliary_calendars == TRUE) {
            if (!config.gui_layout) {
                gtk_widget_show (appGUI->cal->aux_cal_expander);
            }
            gtk_widget_show (appGUI->cal->aux_calendars_table);
        }

        appGUI->cal->prev_month_label = gtk_label_new ("");
        gtk_widget_show (appGUI->cal->prev_month_label);
        gtk_widget_set_hexpand(appGUI->cal->prev_month_label, TRUE);
        gtk_grid_attach (GTK_GRID (appGUI->cal->aux_calendars_table), appGUI->cal->prev_month_label, 0, 0, 1, 1);

        appGUI->cal->next_month_label = gtk_label_new ("");
        gtk_widget_show (appGUI->cal->next_month_label);
        gtk_widget_set_hexpand(appGUI->cal->next_month_label, TRUE);
        gtk_grid_attach (GTK_GRID (appGUI->cal->aux_calendars_table), appGUI->cal->next_month_label, 1, 0, 1, 1);

        appGUI->cal->calendar_prev = gui_calendar_new ();
        gtk_widget_show (appGUI->cal->calendar_prev);
        gtk_widget_set_can_focus (appGUI->cal->calendar_prev, FALSE);
        gtk_grid_attach (GTK_GRID (appGUI->cal->aux_calendars_table), appGUI->cal->calendar_prev, 0, 1, 1, 1);
        gui_calendar_set_display_options (GUI_CALENDAR (appGUI->cal->calendar_prev), 
                                          (config.display_options & (GUI_CALENDAR_SHOW_DAY_NAMES | GUI_CALENDAR_WEEK_START_MONDAY)) | GUI_CALENDAR_NO_MONTH_CHANGE);
        gui_calendar_enable_cursor (GUI_CALENDAR (appGUI->cal->calendar_prev), FALSE);
 		gui_set_calendar_defaults(appGUI->cal->calendar_prev);

        g_signal_connect (G_OBJECT (appGUI->cal->calendar_prev), "day_selected_double_click",
                                  G_CALLBACK (date_selected_cb), appGUI);

        appGUI->cal->calendar_next = gui_calendar_new ();
        gtk_widget_show (appGUI->cal->calendar_next);
        gtk_widget_set_can_focus (appGUI->cal->calendar_next, FALSE);
        gtk_grid_attach (GTK_GRID (appGUI->cal->aux_calendars_table), appGUI->cal->calendar_next, 1, 1, 1, 1);
        gui_calendar_set_display_options (GUI_CALENDAR (appGUI->cal->calendar_next), 
                                          (config.display_options & (GUI_CALENDAR_SHOW_DAY_NAMES | GUI_CALENDAR_WEEK_START_MONDAY)) | GUI_CALENDAR_NO_MONTH_CHANGE);
        gui_calendar_enable_cursor (GUI_CALENDAR (appGUI->cal->calendar_next), FALSE);
		gui_set_calendar_defaults(appGUI->cal->calendar_next);

        g_signal_connect (G_OBJECT (appGUI->cal->calendar_next), "day_selected_double_click",
                                  G_CALLBACK (date_selected_cb), appGUI);

    /*-------------------------------------------------------------------------------------*/
    /* notes */

        appGUI->cal->notes_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
        gtk_widget_show (appGUI->cal->notes_vbox);
		gtk_widget_set_margin_right(GTK_WIDGET(appGUI->cal->notes_vbox), 8);
		gtk_widget_set_margin_bottom(GTK_WIDGET(appGUI->cal->notes_vbox), 8);
        if (!config.gui_layout) {
            gtk_box_pack_start (GTK_BOX (vbox3), appGUI->cal->notes_vbox, TRUE, TRUE, 0);
        } else {
            gtk_box_pack_start (GTK_BOX (hbox1), appGUI->cal->notes_vbox, TRUE, TRUE, 0);
        }

        hbox3 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
        gtk_widget_show (hbox3);
        gtk_box_pack_start (GTK_BOX (appGUI->cal->notes_vbox), hbox3, FALSE, FALSE, 0);

        g_snprintf (tmpbuf, BUFFER_SIZE, "%s:", _("Notes"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_box_pack_start (GTK_BOX (hbox3), label, FALSE, FALSE, 4);

        appGUI->cal->n_close_button = gtk_button_new_from_icon_name("window-close", GTK_ICON_SIZE_BUTTON);
        gtk_widget_set_can_focus (appGUI->cal->n_close_button, FALSE);
        gtk_button_set_relief (GTK_BUTTON(appGUI->cal->n_close_button), GTK_RELIEF_NONE);
        if (config.enable_tooltips) {
            gtk_widget_set_tooltip_text (appGUI->cal->n_close_button, _("Close note panel"));
        }
        gtk_box_pack_end (GTK_BOX (hbox3), appGUI->cal->n_close_button, FALSE, FALSE, 1);
        g_signal_connect (G_OBJECT (appGUI->cal->n_close_button), "clicked",
                            G_CALLBACK (calendar_close_text_cb), appGUI);

        appGUI->cal->ta_highlight_button = gtk_button_new_from_icon_name (OSMO_STOCK_EDITOR_HIGHLIGHT_S, GTK_ICON_SIZE_BUTTON);
        gtk_widget_show (appGUI->cal->ta_highlight_button);
        gtk_widget_set_can_focus (appGUI->cal->ta_highlight_button, FALSE);
        gtk_button_set_relief (GTK_BUTTON(appGUI->cal->ta_highlight_button), GTK_RELIEF_NONE);
        if (config.enable_tooltips) {
            gtk_widget_set_tooltip_text (appGUI->cal->ta_highlight_button, _("Highlight"));
        }
        gtk_box_pack_end (GTK_BOX (hbox3), appGUI->cal->ta_highlight_button, FALSE, FALSE, 1);
        g_object_set_data (G_OBJECT (appGUI->cal->ta_highlight_button), "tag", "mark_color");
        g_signal_connect (G_OBJECT (appGUI->cal->ta_highlight_button), "clicked", 
                          G_CALLBACK (calendar_set_text_attribute_cb), appGUI);

        appGUI->cal->ta_strikethrough_button = gtk_button_new_from_icon_name (OSMO_STOCK_EDITOR_STRIKETHROUGH_S, GTK_ICON_SIZE_BUTTON);
        gtk_widget_show (appGUI->cal->ta_strikethrough_button);
        gtk_widget_set_can_focus (appGUI->cal->ta_strikethrough_button, FALSE);
        gtk_button_set_relief (GTK_BUTTON(appGUI->cal->ta_strikethrough_button), GTK_RELIEF_NONE);
        if (config.enable_tooltips) {
            gtk_widget_set_tooltip_text (appGUI->cal->ta_strikethrough_button, _("Strikethrough"));
        }
        gtk_box_pack_end (GTK_BOX (hbox3), appGUI->cal->ta_strikethrough_button, FALSE, FALSE, 1);
        g_object_set_data (G_OBJECT (appGUI->cal->ta_strikethrough_button), "tag", "strike");
        g_signal_connect (G_OBJECT (appGUI->cal->ta_strikethrough_button), "clicked", 
                          G_CALLBACK (calendar_set_text_attribute_cb), appGUI);

        appGUI->cal->ta_underline_button = gtk_button_new_from_icon_name (OSMO_STOCK_EDITOR_UNDERLINE_S, GTK_ICON_SIZE_BUTTON);
        gtk_widget_show (appGUI->cal->ta_underline_button);
        gtk_widget_set_can_focus (appGUI->cal->ta_underline_button, FALSE);
        gtk_button_set_relief (GTK_BUTTON(appGUI->cal->ta_underline_button), GTK_RELIEF_NONE);
        if (config.enable_tooltips) {
            gtk_widget_set_tooltip_text (appGUI->cal->ta_underline_button, _("Underline"));
        }
        gtk_box_pack_end (GTK_BOX (hbox3), appGUI->cal->ta_underline_button, FALSE, FALSE, 1);
        g_object_set_data (G_OBJECT (appGUI->cal->ta_underline_button), "tag", "underline");
        g_signal_connect (G_OBJECT (appGUI->cal->ta_underline_button), "clicked", 
                          G_CALLBACK (calendar_set_text_attribute_cb), appGUI);

        appGUI->cal->ta_italic_button = gtk_button_new_from_icon_name (OSMO_STOCK_EDITOR_ITALIC_S, GTK_ICON_SIZE_BUTTON);
        gtk_widget_show (appGUI->cal->ta_italic_button);
        gtk_widget_set_can_focus (appGUI->cal->ta_italic_button, FALSE);
        gtk_button_set_relief (GTK_BUTTON(appGUI->cal->ta_italic_button), GTK_RELIEF_NONE);
        if (config.enable_tooltips) {
            gtk_widget_set_tooltip_text (appGUI->cal->ta_italic_button, _("Italic"));
        }
        gtk_box_pack_end (GTK_BOX (hbox3), appGUI->cal->ta_italic_button, FALSE, FALSE, 1);
        g_object_set_data (G_OBJECT (appGUI->cal->ta_italic_button), "tag", "italic");
        g_signal_connect (G_OBJECT (appGUI->cal->ta_italic_button), "clicked", 
                          G_CALLBACK (calendar_set_text_attribute_cb), appGUI);

        appGUI->cal->ta_bold_button = gtk_button_new_from_icon_name (OSMO_STOCK_EDITOR_BOLD_S, GTK_ICON_SIZE_BUTTON);
        gtk_widget_show (appGUI->cal->ta_bold_button);
        gtk_widget_set_can_focus (appGUI->cal->ta_bold_button, FALSE);
        gtk_button_set_relief (GTK_BUTTON(appGUI->cal->ta_bold_button), GTK_RELIEF_NONE);
        if (config.enable_tooltips) {
            gtk_widget_set_tooltip_text (appGUI->cal->ta_bold_button, _("Bold"));
        }
        gtk_box_pack_end (GTK_BOX (hbox3), appGUI->cal->ta_bold_button, FALSE, FALSE, 1);
        g_object_set_data (G_OBJECT (appGUI->cal->ta_bold_button), "tag", "bold");
        g_signal_connect (G_OBJECT (appGUI->cal->ta_bold_button), "clicked", 
                          G_CALLBACK (calendar_set_text_attribute_cb), appGUI);

        vseparator = gtk_separator_new (GTK_ORIENTATION_VERTICAL);
        gtk_widget_show (vseparator);
        gtk_box_pack_end (GTK_BOX (hbox3), vseparator, FALSE, TRUE, 0);

        appGUI->cal->n_timeline_button = gtk_button_new_from_icon_name (OSMO_STOCK_BUTTON_INSERT_TIMELINE, GTK_ICON_SIZE_BUTTON);
        gtk_widget_show (appGUI->cal->n_timeline_button);
        gtk_widget_set_can_focus (appGUI->cal->n_timeline_button, FALSE);
        gtk_button_set_relief (GTK_BUTTON(appGUI->cal->n_timeline_button), GTK_RELIEF_NONE);
        if (config.enable_tooltips) {
            gtk_widget_set_tooltip_text (appGUI->cal->n_timeline_button, _("Insert timeline"));
        }
        gtk_box_pack_end (GTK_BOX (hbox3), appGUI->cal->n_timeline_button, FALSE, FALSE, 1);
        g_signal_connect (G_OBJECT (appGUI->cal->n_timeline_button), "clicked",
                            G_CALLBACK (calendar_insert_timeline_cb), appGUI);

        appGUI->cal->n_clear_button = gtk_button_new_from_icon_name("edit-clear", GTK_ICON_SIZE_BUTTON);
        gtk_widget_show (appGUI->cal->n_clear_button);
        gtk_widget_set_can_focus  (appGUI->cal->n_clear_button, FALSE);
        gtk_button_set_relief (GTK_BUTTON(appGUI->cal->n_clear_button), GTK_RELIEF_NONE);
        if (config.enable_tooltips) {
            gtk_widget_set_tooltip_text (appGUI->cal->n_clear_button, _("Clear text"));
        }
        gtk_box_pack_end (GTK_BOX (hbox3), appGUI->cal->n_clear_button, FALSE, FALSE, 1);
        g_signal_connect (G_OBJECT (appGUI->cal->n_clear_button), "clicked",
                            G_CALLBACK (calendar_clear_text_cb), appGUI);

        appGUI->cal->n_select_color_button = gtk_button_new_from_icon_name (OSMO_STOCK_BUTTON_SELECT_COLOR, GTK_ICON_SIZE_BUTTON);
        gtk_widget_show (appGUI->cal->n_select_color_button);
        gtk_widget_set_can_focus  (appGUI->cal->n_select_color_button, FALSE);
        gtk_button_set_relief (GTK_BUTTON(appGUI->cal->n_select_color_button), GTK_RELIEF_NONE);
        if (config.enable_tooltips) {
            gtk_widget_set_tooltip_text (appGUI->cal->n_select_color_button, _("Select day color"));
        }
        gtk_box_pack_end (GTK_BOX (hbox3), appGUI->cal->n_select_color_button, FALSE, FALSE, 1);
        g_signal_connect (G_OBJECT (appGUI->cal->n_select_color_button), "clicked",
                            G_CALLBACK (calendar_select_color_cb), appGUI);

        note_scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
        gtk_widget_show (note_scrolledwindow);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (note_scrolledwindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
        gtk_box_pack_start (GTK_BOX (appGUI->cal->notes_vbox), note_scrolledwindow, TRUE, TRUE, 0);
        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (note_scrolledwindow), GTK_SHADOW_IN);

        appGUI->cal->calendar_note_textview = gtk_text_view_new ();
        gtk_widget_show (appGUI->cal->calendar_note_textview);
        buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview));
        g_signal_connect (G_OBJECT (buffer), "changed",
                          G_CALLBACK (calendar_textbuffer_changed_cb), appGUI);
        gtk_container_add (GTK_CONTAINER (note_scrolledwindow), appGUI->cal->calendar_note_textview);
        gtk_text_view_set_accepts_tab (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview), TRUE);
        gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (appGUI->cal->calendar_note_textview), GTK_WRAP_WORD_CHAR);
        gtk_widget_override_font (GTK_WIDGET(appGUI->cal->calendar_note_textview), appGUI->cal->fd_notes_font);
        gtk_text_view_set_pixels_above_lines(GTK_TEXT_VIEW(appGUI->cal->calendar_note_textview), 4);
        gtk_text_view_set_left_margin(GTK_TEXT_VIEW(appGUI->cal->calendar_note_textview), 4);
        gtk_text_view_set_right_margin(GTK_TEXT_VIEW(appGUI->cal->calendar_note_textview), 4);
    
        gtk_text_buffer_create_tag (buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL);
        gtk_text_buffer_create_tag (buffer, "italic", "style", PANGO_STYLE_ITALIC, NULL);
        gtk_text_buffer_create_tag (buffer, "strike", "strikethrough", TRUE, NULL);
        gtk_text_buffer_create_tag (buffer, "underline", "underline", PANGO_UNDERLINE_SINGLE, NULL);
        gtk_text_buffer_create_tag (buffer, "mark_color", "background", "#FFFF00", NULL);

#ifdef HAVE_GSPELL
        utl_gui_set_enable_spell_check(appGUI->cal->calendar_note_spelltextview, config.day_note_spell_checker);
#endif  /* HAVE_GSPELL */
    /*-------------------------------------------------------------------------------------*/
    /* day info */

        appGUI->cal->day_info_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
        gtk_widget_show (appGUI->cal->day_info_vbox);
        if (!config.gui_layout) {
            gtk_box_pack_start (GTK_BOX (vbox3), appGUI->cal->day_info_vbox, TRUE, TRUE, 0);
        } else {
            gtk_box_pack_start (GTK_BOX (hbox1), appGUI->cal->day_info_vbox, TRUE, TRUE, 0);
        }

        frame = gtk_frame_new (NULL);
        gtk_widget_show (frame);
        gtk_box_pack_start (GTK_BOX (appGUI->cal->day_info_vbox), frame, TRUE, TRUE, 0);
        gtk_widget_set_margin_right(GTK_WIDGET(frame), 8);
        gtk_widget_set_margin_bottom(GTK_WIDGET(frame), 8);
        gtk_frame_set_label_align (GTK_FRAME (frame), 0.98, 0.5);
        gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);

        g_snprintf (tmpbuf, BUFFER_SIZE, "<b>%s</b>", _("Info"));
        label = gtk_label_new (tmpbuf);
        gtk_widget_show (label);
        gtk_frame_set_label_widget (GTK_FRAME (frame), label);
        gtk_label_set_use_markup (GTK_LABEL (label), TRUE);

        appGUI->cal->day_info_scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
        gtk_widget_show (appGUI->cal->day_info_scrolledwindow);
        gtk_container_add (GTK_CONTAINER (frame), appGUI->cal->day_info_scrolledwindow);
        gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (appGUI->cal->day_info_scrolledwindow), 
                                             GTK_SHADOW_NONE);
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (appGUI->cal->day_info_scrolledwindow), 
                                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);

#ifdef HAVE_LIBWEBKIT
        appGUI->cal->html_webkitview = utl_create_webkit_web_view(appGUI);

        g_signal_connect (appGUI->cal->html_webkitview, "context-menu",
                          G_CALLBACK (utl_webkit_on_menu), appGUI);
        g_signal_connect (appGUI->cal->html_webkitview, "decide-policy",
                          G_CALLBACK (utl_webkit_link_clicked), appGUI);

        gtk_widget_show (GTK_WIDGET(appGUI->cal->html_webkitview));
        gtk_container_add (GTK_CONTAINER (appGUI->cal->day_info_scrolledwindow), 
                           GTK_WIDGET(appGUI->cal->html_webkitview));

#else
        appGUI->cal->day_desc_textview = gtk_text_view_new ();
        gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (appGUI->cal->day_desc_textview), GTK_WRAP_WORD);
        gtk_text_view_set_pixels_above_lines (GTK_TEXT_VIEW(appGUI->cal->day_desc_textview), 4);
        gtk_text_view_set_left_margin (GTK_TEXT_VIEW(appGUI->cal->day_desc_textview), 4);
        gtk_text_view_set_right_margin (GTK_TEXT_VIEW(appGUI->cal->day_desc_textview), 4);
        gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW(appGUI->cal->day_desc_textview), FALSE);
        gtk_text_view_set_editable (GTK_TEXT_VIEW(appGUI->cal->day_desc_textview), FALSE);
        gtk_widget_show (appGUI->cal->day_desc_textview);
        gtk_container_add (GTK_CONTAINER (appGUI->cal->day_info_scrolledwindow), appGUI->cal->day_desc_textview);
        gtk_widget_realize (appGUI->cal->day_desc_textview);

        appGUI->cal->day_desc_text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(appGUI->cal->day_desc_textview));
        gtk_text_buffer_create_tag (appGUI->cal->day_desc_text_buffer, "bold", "weight", PANGO_WEIGHT_BOLD, NULL);
        gtk_text_buffer_create_tag (appGUI->cal->day_desc_text_buffer, "italic", "style", PANGO_STYLE_ITALIC, NULL);
        gtk_text_buffer_create_tag (appGUI->cal->day_desc_text_buffer, "strike", "strikethrough", TRUE, NULL);
        gtk_text_buffer_create_tag (appGUI->cal->day_desc_text_buffer, "underline", "underline", PANGO_UNDERLINE_SINGLE, NULL);
        gtk_text_buffer_create_tag (appGUI->cal->day_desc_text_buffer, "mark_color", "background", "#FFFF00", NULL);

#endif  /* HAVE_LIBWEBKIT */

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

    }

    gtk_widget_override_font (GTK_WIDGET(appGUI->cal->date_label), appGUI->cal->fd_day_name_font);

    gui_calendar_get_gdate (GUI_CALENDAR (appGUI->cal->calendar), appGUI->cal->date);

    gui_calendar_set_frame_cursor_thickness (GUI_CALENDAR (appGUI->cal->calendar), config.frame_cursor_thickness);

    if (appGUI->calendar_only == FALSE) {
        if (!config.day_notes_visible) {
            gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(appGUI->cal->notes_button), FALSE);
            gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(appGUI->cal->calendar_note_textview), FALSE);
            gtk_text_view_set_editable(GTK_TEXT_VIEW(appGUI->cal->calendar_note_textview), FALSE);
            gtk_widget_show(appGUI->cal->day_info_vbox);
            gtk_widget_hide(appGUI->cal->notes_vbox);
        } else {
            gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON(appGUI->cal->notes_button), TRUE);
            gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(appGUI->cal->calendar_note_textview), TRUE);
            gtk_text_view_set_editable(GTK_TEXT_VIEW(appGUI->cal->calendar_note_textview), TRUE);
            gtk_widget_hide(appGUI->cal->day_info_vbox);
            gtk_widget_show(appGUI->cal->notes_vbox);
        }

        gtk_widget_realize(GTK_WIDGET(appGUI->cal->calendar_note_textview));
        gtk_widget_grab_focus(GTK_WIDGET(appGUI->cal->calendar_note_textview));
    }

    if (appGUI->calendar_only == FALSE) {
        if (!config.gui_layout) {
            g_signal_connect (G_OBJECT(appGUI->cal->aux_cal_expander), "notify::expanded", 
                              G_CALLBACK(aux_cal_expander_cb), appGUI);
            gtk_expander_set_expanded (GTK_EXPANDER(appGUI->cal->aux_cal_expander), config.auxiliary_calendars_state);
        } else {
            update_aux_calendars (appGUI);
        }
    }
    gtk_label_set_text (GTK_LABEL (appGUI->cal->date_label), utl_get_date_name_format (appGUI->cal->date, config.date_header_format));
}

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

void
select_bg_color_close_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;
    gtk_widget_destroy (appGUI->cal->select_bg_color_window);
}

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

void
button_select_bg_color_close_cb (GtkWidget *widget, gpointer user_data)
{
    select_bg_color_close_cb (widget, NULL, user_data);
}

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

void
colors_category_selected (GUI *appGUI)
{
    GtkTreeModel *model;
    GtkTreeIter iter;

    if (gtk_tree_selection_get_selected(appGUI->cal->colors_category_select, &model, &iter)) {
        gchar *color_val = NULL;

        gtk_tree_model_get(GTK_TREE_MODEL(appGUI->cal->colors_category_store), &iter, 1, &color_val, -1);
        calendar_store_note(appGUI->cal->date, color_val, appGUI);
        cal_refresh_notes(appGUI);
        select_bg_color_close_cb(NULL, NULL, appGUI);
        g_free(color_val);
    }

}

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

void
select_bg_color_apply_cb (GtkWidget *widget, gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;

    config.enable_day_mark = TRUE;
    colors_category_selected (appGUI);
}

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

gint
select_bg_color_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;

    switch (event->keyval) {

        case GDK_KEY_Return:
            config.enable_day_mark = TRUE;
            colors_category_selected (appGUI);
            return TRUE;

        case GDK_KEY_Escape:
            select_bg_color_close_cb (NULL, NULL, appGUI);
            return TRUE;
    }

    return FALSE;
}

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

gint
colors_list_dbclick_cb (GtkWidget *widget, GdkEventButton *event, gpointer user_data)
{
    GUI *appGUI = (GUI *) user_data;

    if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) {
        config.enable_day_mark = TRUE;
        colors_category_selected (appGUI);
        return TRUE;
    }

    return FALSE;
}

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

void
calendar_create_color_selector_window (gboolean window_pos, GUI *appGUI) {

GtkWidget *vbox1;
GtkWidget *scrolledwindow;
GtkWidget *colors_category_treeview;
GtkWidget *hseparator;
GtkWidget *hbuttonbox;
GtkWidget *ok_button;
GtkWidget *cancel_button;
GtkTreeIter iter;
GtkCellRenderer     *renderer;
GtkTreeViewColumn   *column;
GtkTreePath     *path;
GdkPixbuf *image;
gchar *color_val, *color_name, *color_sel;
gboolean has_next;

    if (cal_check_note (g_date_get_julian (appGUI->cal->date), appGUI) == FALSE && !config.day_notes_visible) return;
    
    config.enable_day_mark = TRUE;
    cal_refresh_marks (appGUI);
    update_aux_calendars (appGUI);

    appGUI->cal->select_bg_color_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    gtk_container_set_border_width (GTK_CONTAINER (appGUI->cal->select_bg_color_window), 4);
    gtk_window_set_title (GTK_WINDOW (appGUI->cal->select_bg_color_window), _("Select color"));
    gtk_window_set_default_size (GTK_WINDOW(appGUI->cal->select_bg_color_window), 200, 280);
    gtk_window_set_transient_for(GTK_WINDOW(appGUI->cal->select_bg_color_window), GTK_WINDOW(appGUI->main_window));
    if (window_pos == TRUE) {
        gtk_window_set_position(GTK_WINDOW(appGUI->cal->select_bg_color_window), GTK_WIN_POS_CENTER_ON_PARENT);
    } else {
        gtk_window_set_position(GTK_WINDOW(appGUI->cal->select_bg_color_window), GTK_WIN_POS_MOUSE);
    }
    gtk_window_set_modal(GTK_WINDOW(appGUI->cal->select_bg_color_window), TRUE);
    g_signal_connect (G_OBJECT (appGUI->cal->select_bg_color_window), "delete_event",
                      G_CALLBACK(select_bg_color_close_cb), appGUI);
    g_signal_connect (G_OBJECT (appGUI->cal->select_bg_color_window), "key_press_event",
                      G_CALLBACK (select_bg_color_key_press_cb), appGUI);

    vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
    gtk_widget_show (vbox1);
    gtk_container_add (GTK_CONTAINER (appGUI->cal->select_bg_color_window), vbox1);

    scrolledwindow = gtk_scrolled_window_new (NULL, NULL);
    gtk_widget_show (scrolledwindow);
    gtk_box_pack_start (GTK_BOX (vbox1), scrolledwindow, TRUE, TRUE, 0);
    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);

    appGUI->cal->colors_category_store = gtk_list_store_new(3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);

    colors_category_treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(appGUI->cal->colors_category_store));
    g_signal_connect(G_OBJECT(colors_category_treeview), "button_press_event",
                     G_CALLBACK(colors_list_dbclick_cb), appGUI);
    appGUI->cal->colors_category_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(colors_category_treeview));
    gtk_widget_show (colors_category_treeview);
    gtk_container_add (GTK_CONTAINER (scrolledwindow), colors_category_treeview);
    gtk_container_set_border_width (GTK_CONTAINER (colors_category_treeview), 4);
    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (colors_category_treeview), FALSE);
    gtk_tree_view_set_enable_search (GTK_TREE_VIEW (colors_category_treeview), FALSE);

    renderer = gtk_cell_renderer_pixbuf_new();
    column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "pixbuf", 0, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(colors_category_treeview), column);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "text", 1, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(colors_category_treeview), column);
    gtk_tree_view_column_set_visible (column, FALSE);

    renderer = gtk_cell_renderer_text_new();
    column = gtk_tree_view_column_new_with_attributes(NULL, renderer, "text", 2, NULL);
    gtk_tree_view_append_column(GTK_TREE_VIEW(colors_category_treeview), column);

    image = utl_gui_create_color_swatch ("None");
    gtk_list_store_append(appGUI->cal->colors_category_store, &iter);
    gtk_list_store_set(appGUI->cal->colors_category_store, &iter, 0, image, 1, NULL, 2, _("None"), -1);
    g_object_unref (image);

    color_sel = cal_get_note_color (g_date_get_julian (appGUI->cal->date), appGUI);

    has_next = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(appGUI->opt->calendar_category_store), &iter);
    while (has_next) {
        GtkTreeIter color_iter;
        gtk_tree_model_get(GTK_TREE_MODEL(appGUI->opt->calendar_category_store), &iter, 1, &color_val, 2, &color_name, -1);
        image = utl_gui_create_color_swatch (color_val);
        gtk_list_store_append(appGUI->cal->colors_category_store, &color_iter);
        gtk_list_store_set(appGUI->cal->colors_category_store, &color_iter, 0, image, 1, color_val, 2, color_name, -1);

        if (color_sel != NULL) {
            if (!strcmp(color_val, color_sel)) {
                path = gtk_tree_model_get_path (GTK_TREE_MODEL(appGUI->cal->colors_category_store), &color_iter);
                if (path != NULL) {
                    gtk_tree_view_set_cursor (GTK_TREE_VIEW (colors_category_treeview), path, NULL, FALSE);
                    gtk_tree_path_free(path);
                }
            }
        }

        g_object_unref (image);
        g_free(color_val);
        g_free(color_name);
        has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL(appGUI->opt->calendar_category_store), &iter);
    }

    hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_widget_show (hseparator);
    gtk_box_pack_start (GTK_BOX (vbox1), hseparator, FALSE, TRUE, 4);

    hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
    gtk_widget_show (hbuttonbox);
    gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox, FALSE, FALSE, 0);
    gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
    gtk_box_set_spacing (GTK_BOX (hbuttonbox), 4);

    cancel_button = gtk_button_new_with_mnemonic (_("_Cancel"));
    gtk_widget_set_can_focus (cancel_button, FALSE);
    gtk_widget_show (cancel_button);
    gtk_container_add (GTK_CONTAINER (hbuttonbox), cancel_button);
    g_signal_connect (G_OBJECT (cancel_button), "clicked",
                        G_CALLBACK (button_select_bg_color_close_cb), appGUI);

    ok_button = gtk_button_new_with_mnemonic (_("_OK"));
    gtk_widget_set_can_focus (ok_button, FALSE);
    gtk_widget_show (ok_button);
    gtk_container_add (GTK_CONTAINER (hbuttonbox), ok_button);
    g_signal_connect (G_OBJECT (ok_button), "clicked",
                        G_CALLBACK (select_bg_color_apply_cb), appGUI);

    gtk_widget_show (appGUI->cal->select_bg_color_window);
}

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

void
menu_entry_selected_cb (gpointer user_data)
{
    MESSAGE *msg = (MESSAGE *) user_data;
    calendar_update_date (g_date_get_day (msg->appGUI->cal->date), (size_t) msg->data,
                          g_date_get_year (msg->appGUI->cal->date), msg->appGUI);
}

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

void
calendar_create_popup_menu (GtkWidget *menu, GUI *appGUI)
{
static MESSAGE msg_month[MAX_MONTHS];
GtkWidget *menu_entry;
gchar buffer[BUFFER_SIZE];
GDate *tmpdate;
gint i;

    tmpdate = g_date_new_dmy (1, 1, utl_date_get_current_year ());
    g_return_if_fail (tmpdate != NULL);

    for (i = G_DATE_JANUARY; i <= G_DATE_DECEMBER; i++) {
        g_date_set_month (tmpdate, i);
        g_date_strftime (buffer, BUFFER_SIZE, "%B", tmpdate);

        menu_entry = gtk_menu_item_new_with_label (buffer);
        gtk_menu_shell_append (GTK_MENU_SHELL (appGUI->cal->month_selector_menu), menu_entry);
        msg_month[i-1].data = (gpointer) ((size_t)i);
        msg_month[i-1].appGUI = appGUI;
        g_signal_connect_swapped (G_OBJECT (menu_entry), "activate",
                                  G_CALLBACK (menu_entry_selected_cb), &msg_month[i-1]);
        gtk_widget_show (menu_entry);
    }

    g_date_free (tmpdate);
}

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

void
calendar_mark_events (GtkWidget *calendar, guint32 julian_day, guint i, GUI *appGUI) {

gboolean flag = FALSE;

    if (appGUI->calendar_only == TRUE || appGUI->all_pages_added == FALSE) 
        return;

#ifdef TASKS_ENABLED
    if (tsk_check_tasks (julian_day, julian_day, STATE_CALENDAR, appGUI) == TRUE) {
        gui_calendar_mark_day (GUI_CALENDAR (calendar), i, EVENT_MARK);
        flag = TRUE;
    }
#endif  /* TASKS_ENABLED */

#ifdef HAVE_LIBICAL
    if (flag == FALSE) {
        if (ics_check_event (julian_day, appGUI) == TRUE) {
            gui_calendar_mark_day (GUI_CALENDAR (calendar), i, EVENT_MARK);
        }
    }
#endif  /* HAVE_LIBICAL */

#ifdef CONTACTS_ENABLED
    if (check_contacts (julian_day, appGUI) == TRUE) {
        gui_calendar_mark_day (GUI_CALENDAR (calendar), i, BIRTHDAY_MARK);
    }
#endif  /* CONTACTS_ENABLED */

}

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

