From 806673dd9b256e879d1483255886a8881d1d8115 Mon Sep 17 00:00:00 2001
From: Lukas Fleischer <calcurse@cryptocrack.de>
Date: Thu, 14 Feb 2013 10:52:44 +0100
Subject: calendar.c: Rename to "ui-calendar.c"

This unit belongs to the presentation layer -- rename the file
accordingly.

Also, rename calendar_*() to ui_calendar_*().

Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
---
 src/Makefile.am   |   2 +-
 src/calcurse.c    |  40 +--
 src/calcurse.h    |  44 +--
 src/calendar.c    | 915 ------------------------------------------------------
 src/config.c      |  12 +-
 src/custom.c      |   4 +-
 src/day.c         |   4 +-
 src/pcal.c        |  10 +-
 src/ui-calendar.c | 915 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ui-day.c      |  28 +-
 src/utils.c       |   2 +-
 src/vars.c        |   4 +-
 src/wins.c        |   2 +-
 13 files changed, 991 insertions(+), 991 deletions(-)
 delete mode 100644 src/calendar.c
 create mode 100644 src/ui-calendar.c

(limited to 'src')

diff --git a/src/Makefile.am b/src/Makefile.am
index 438106d..44d1ae8 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -13,7 +13,6 @@ calcurse_SOURCES = \
 	sha1.h \
 	apoint.c \
 	args.c \
-	calendar.c \
 	config.c \
 	custom.c \
 	day.c \
@@ -31,6 +30,7 @@ calcurse_SOURCES = \
 	sha1.c \
 	sigs.c \
 	todo.c \
+	ui-calendar.c \
 	ui-day.c \
 	ui-todo.c \
 	utf8.c \
diff --git a/src/calcurse.c b/src/calcurse.c
index 227c83f..6fd2ecb 100644
--- a/src/calcurse.c
+++ b/src/calcurse.c
@@ -49,7 +49,7 @@ int count, reg;
  */
 static struct day_items_nb do_storage(int day_changed)
 {
-  struct day_items_nb inday = day_process_storage(calendar_get_slctd_day(),
+  struct day_items_nb inday = day_process_storage(ui_calendar_get_slctd_day(),
                                                   day_changed);
 
   if (day_changed) {
@@ -92,8 +92,8 @@ static inline void key_generic_other_cmd(void)
 static inline void key_generic_goto(void)
 {
   wins_erase_status_bar();
-  calendar_set_current_date();
-  calendar_change_day(conf.input_datefmt);
+  ui_calendar_set_current_date();
+  ui_calendar_change_day(conf.input_datefmt);
   inday = do_storage(1);
   wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
 }
@@ -101,8 +101,8 @@ static inline void key_generic_goto(void)
 static inline void key_generic_goto_today(void)
 {
   wins_erase_status_bar();
-  calendar_set_current_date();
-  calendar_goto_today();
+  ui_calendar_set_current_date();
+  ui_calendar_goto_today();
   inday = do_storage(1);
   wins_update(FLAG_CAL | FLAG_APP | FLAG_STA);
 }
@@ -287,7 +287,7 @@ static inline void key_generic_import(void)
 {
   wins_erase_status_bar();
   io_import_data(IO_IMPORT_ICAL, NULL);
-  calendar_monthly_view_cache_set_invalid();
+  ui_calendar_monthly_view_cache_set_invalid();
   inday = do_storage(0);
   wins_update(FLAG_ALL);
 }
@@ -317,7 +317,7 @@ static inline void key_generic_export()
 
 static inline void key_generic_prev_day(void)
 {
-  calendar_move(DAY_PREV, count);
+  ui_calendar_move(DAY_PREV, count);
   inday = do_storage(1);
   wins_update(FLAG_CAL | FLAG_APP);
 }
@@ -330,7 +330,7 @@ static inline void key_move_left(void)
 
 static inline void key_generic_next_day(void)
 {
-  calendar_move(DAY_NEXT, count);
+  ui_calendar_move(DAY_NEXT, count);
   inday = do_storage(1);
   wins_update(FLAG_CAL | FLAG_APP);
 }
@@ -343,7 +343,7 @@ static inline void key_move_right(void)
 
 static inline void key_generic_prev_week(void)
 {
-  calendar_move(WEEK_PREV, count);
+  ui_calendar_move(WEEK_PREV, count);
   inday = do_storage(1);
   wins_update(FLAG_CAL | FLAG_APP);
 }
@@ -370,7 +370,7 @@ static inline void key_move_up(void)
 
 static inline void key_generic_next_week(void)
 {
-  calendar_move(WEEK_NEXT, count);
+  ui_calendar_move(WEEK_NEXT, count);
   inday = do_storage(1);
   wins_update(FLAG_CAL | FLAG_APP);
 }
@@ -397,28 +397,28 @@ static inline void key_move_down(void)
 
 static inline void key_generic_prev_month(void)
 {
-  calendar_move(MONTH_PREV, count);
+  ui_calendar_move(MONTH_PREV, count);
   inday = do_storage(1);
   wins_update(FLAG_CAL | FLAG_APP);
 }
 
 static inline void key_generic_next_month(void)
 {
-  calendar_move(MONTH_NEXT, count);
+  ui_calendar_move(MONTH_NEXT, count);
   inday = do_storage(1);
   wins_update(FLAG_CAL | FLAG_APP);
 }
 
 static inline void key_generic_prev_year(void)
 {
-  calendar_move(YEAR_PREV, count);
+  ui_calendar_move(YEAR_PREV, count);
   inday = do_storage(1);
   wins_update(FLAG_CAL | FLAG_APP);
 }
 
 static inline void key_generic_next_year(void)
 {
-  calendar_move(YEAR_NEXT, count);
+  ui_calendar_move(YEAR_NEXT, count);
   inday = do_storage(1);
   wins_update(FLAG_CAL | FLAG_APP);
 }
@@ -426,7 +426,7 @@ static inline void key_generic_next_year(void)
 static inline void key_start_of_week(void)
 {
   if (wins_slctd() == CAL) {
-    calendar_move(WEEK_START, count);
+    ui_calendar_move(WEEK_START, count);
     inday = do_storage(1);
     wins_update(FLAG_CAL | FLAG_APP);
   }
@@ -435,7 +435,7 @@ static inline void key_start_of_week(void)
 static inline void key_end_of_week(void)
 {
   if (wins_slctd() == CAL) {
-    calendar_move(WEEK_END, count);
+    ui_calendar_move(WEEK_END, count);
     inday = do_storage(1);
     wins_update(FLAG_CAL | FLAG_APP);
   }
@@ -444,7 +444,7 @@ static inline void key_end_of_week(void)
 static inline void key_generic_scroll_up(void)
 {
   if (wins_slctd() == CAL) {
-    calendar_view_prev();
+    ui_calendar_view_prev();
     wins_update(FLAG_CAL | FLAG_APP);
   }
 }
@@ -452,7 +452,7 @@ static inline void key_generic_scroll_up(void)
 static inline void key_generic_scroll_down(void)
 {
   if (wins_slctd() == CAL) {
-    calendar_view_next();
+    ui_calendar_view_next();
     wins_update(FLAG_CAL | FLAG_APP);
   }
 }
@@ -519,7 +519,7 @@ int main(int argc, char **argv)
   cbreak();                     /* control chars generate a signal */
   noecho();                     /* controls echoing of typed chars */
   curs_set(0);                  /* make cursor invisible */
-  calendar_set_current_date();
+  ui_calendar_set_current_date();
   notify_init_vars();
   wins_get_config();
 
@@ -586,7 +586,7 @@ int main(int argc, char **argv)
   /* Start miscellaneous threads. */
   if (notify_bar())
     notify_start_main_thread();
-  calendar_start_date_thread();
+  ui_calendar_start_date_thread();
   if (conf.periodic_save > 0)
     io_start_psave_thread();
 
diff --git a/src/calcurse.h b/src/calcurse.h
index 22c4fe8..8d76bba 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -631,28 +631,28 @@ void apoint_paste_item(struct apoint *, long);
 int parse_args(int, char **);
 
 /* calendar.c */
-void calendar_view_next(void);
-void calendar_view_prev(void);
-void calendar_set_view(int);
-int calendar_get_view(void);
-void calendar_start_date_thread(void);
-void calendar_stop_date_thread(void);
-void calendar_set_current_date(void);
-void calendar_set_first_day_of_week(enum wday);
-void calendar_change_first_day_of_week(void);
-unsigned calendar_week_begins_on_monday(void);
-void calendar_store_current_date(struct date *);
-void calendar_init_slctd_day(void);
-struct date *calendar_get_slctd_day(void);
-long calendar_get_slctd_day_sec(void);
-void calendar_monthly_view_cache_set_invalid(void);
-void calendar_update_panel(struct window *);
-void calendar_goto_today(void);
-void calendar_change_day(int);
-void calendar_move(enum move, int);
-long calendar_start_of_year(void);
-long calendar_end_of_year(void);
-const char *calendar_get_pom(time_t);
+void ui_calendar_view_next(void);
+void ui_calendar_view_prev(void);
+void ui_calendar_set_view(int);
+int ui_calendar_get_view(void);
+void ui_calendar_start_date_thread(void);
+void ui_calendar_stop_date_thread(void);
+void ui_calendar_set_current_date(void);
+void ui_calendar_set_first_day_of_week(enum wday);
+void ui_calendar_change_first_day_of_week(void);
+unsigned ui_calendar_week_begins_on_monday(void);
+void ui_calendar_store_current_date(struct date *);
+void ui_calendar_init_slctd_day(void);
+struct date *ui_calendar_get_slctd_day(void);
+long ui_calendar_get_slctd_day_sec(void);
+void ui_calendar_monthly_view_cache_set_invalid(void);
+void ui_calendar_update_panel(struct window *);
+void ui_calendar_goto_today(void);
+void ui_calendar_change_day(int);
+void ui_calendar_move(enum move, int);
+long ui_calendar_start_of_year(void);
+long ui_calendar_end_of_year(void);
+const char *ui_calendar_get_pom(time_t);
 
 /* config.c */
 
diff --git a/src/calendar.c b/src/calendar.c
deleted file mode 100644
index cad9ad9..0000000
--- a/src/calendar.c
+++ /dev/null
@@ -1,915 +0,0 @@
-/*
- * Calcurse - text-based organizer
- *
- * Copyright (c) 2004-2013 calcurse Development Team <misc@calcurse.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- *      - Redistributions of source code must retain the above
- *        copyright notice, this list of conditions and the
- *        following disclaimer.
- *
- *      - Redistributions in binary form must reproduce the above
- *        copyright notice, this list of conditions and the
- *        following disclaimer in the documentation and/or other
- *        materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Send your feedback or comments to : misc@calcurse.org
- * Calcurse home page : http://calcurse.org
- *
- */
-
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#include <time.h>
-#include <math.h>
-
-#include "calcurse.h"
-
-#ifndef M_PI
-#define	M_PI	  3.14159265358979323846
-#endif
-
-#define	EPOCH	  90
-#define	EPSILONg  279.403303    /* solar ecliptic long at EPOCH */
-#define	RHOg	  282.768422    /* solar ecliptic long of perigee at EPOCH */
-#define	ECCEN	  0.016713      /* solar orbit eccentricity */
-#define	lzero	  318.351648    /* lunar mean long at EPOCH */
-#define	Pzero	  36.340410     /* lunar mean long of perigee at EPOCH */
-#define	Nzero	  318.510107    /* lunar mean long of node at EPOCH */
-
-#define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
-
-enum pom {
-  NO_POM,
-  FIRST_QUARTER,
-  FULL_MOON,
-  LAST_QUARTER,
-  NEW_MOON,
-  MOON_PHASES
-};
-
-static struct date today, slctd_day;
-static unsigned calendar_view, week_begins_on_monday;
-static pthread_mutex_t date_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
-static pthread_t calendar_t_date;
-
-static void draw_monthly_view(struct window *, struct date *, unsigned);
-static void draw_weekly_view(struct window *, struct date *, unsigned);
-static void (*draw_calendar[CAL_VIEWS]) (struct window *, struct date *,
-                                         unsigned) = {
-draw_monthly_view, draw_weekly_view};
-
-static int monthly_view_cache[MAXDAYSPERMONTH];
-static int monthly_view_cache_valid = 0;
-static int monthly_view_cache_month = 0;
-
-/* Switch between calendar views (monthly view is selected by default). */
-void calendar_view_next(void)
-{
-  calendar_view++;
-  if (calendar_view == CAL_VIEWS)
-    calendar_view = 0;
-}
-
-void calendar_view_prev(void)
-{
-  if (calendar_view == 0)
-    calendar_view = CAL_VIEWS;
-  calendar_view--;
-}
-
-void calendar_set_view(int view)
-{
-  calendar_view = (view < 0 || view >= CAL_VIEWS) ? CAL_MONTH_VIEW : view;
-}
-
-int calendar_get_view(void)
-{
-  return (int)calendar_view;
-}
-
-/* Thread needed to update current date in calendar. */
-/* ARGSUSED0 */
-static void *calendar_date_thread(void *arg)
-{
-  time_t actual, tomorrow;
-
-  for (;;) {
-    tomorrow = (time_t) (get_today() + DAYINSEC);
-
-    while ((actual = time(NULL)) < tomorrow)
-      sleep(tomorrow - actual);
-
-    calendar_set_current_date();
-    calendar_update_panel(&win[CAL]);
-  }
-
-  return NULL;
-}
-
-/* Launch the calendar date thread. */
-void calendar_start_date_thread(void)
-{
-  pthread_create(&calendar_t_date, NULL, calendar_date_thread, NULL);
-}
-
-/* Stop the calendar date thread. */
-void calendar_stop_date_thread(void)
-{
-  if (calendar_t_date) {
-    pthread_cancel(calendar_t_date);
-    pthread_join(calendar_t_date, NULL);
-  }
-}
-
-/* Set static variable today to current date */
-void calendar_set_current_date(void)
-{
-  time_t timer;
-  struct tm tm;
-
-  timer = time(NULL);
-  localtime_r(&timer, &tm);
-
-  pthread_mutex_lock(&date_thread_mutex);
-  today.dd = tm.tm_mday;
-  today.mm = tm.tm_mon + 1;
-  today.yyyy = tm.tm_year + 1900;
-  pthread_mutex_unlock(&date_thread_mutex);
-}
-
-/* Needed to display sunday or monday as the first day of week in calendar. */
-void calendar_set_first_day_of_week(enum wday first_day)
-{
-  switch (first_day) {
-  case SUNDAY:
-    week_begins_on_monday = 0;
-    break;
-  case MONDAY:
-    week_begins_on_monday = 1;
-    break;
-  default:
-    ERROR_MSG(_("ERROR setting first day of week"));
-    week_begins_on_monday = 0;
-    /* NOTREACHED */
-  }
-}
-
-/* Swap first day of week in calendar. */
-void calendar_change_first_day_of_week(void)
-{
-  week_begins_on_monday = !week_begins_on_monday;
-}
-
-/* Return 1 if week begins on monday, 0 otherwise. */
-unsigned calendar_week_begins_on_monday(void)
-{
-  return week_begins_on_monday;
-}
-
-/* Fill in the given variable with the current date. */
-void calendar_store_current_date(struct date *date)
-{
-  pthread_mutex_lock(&date_thread_mutex);
-  *date = today;
-  pthread_mutex_unlock(&date_thread_mutex);
-}
-
-/* This is to start at the current date in calendar. */
-void calendar_init_slctd_day(void)
-{
-  calendar_store_current_date(&slctd_day);
-}
-
-/* Return the selected day in calendar */
-struct date *calendar_get_slctd_day(void)
-{
-  return &slctd_day;
-}
-
-/* Returned value represents the selected day in calendar (in seconds) */
-long calendar_get_slctd_day_sec(void)
-{
-  return date2sec(slctd_day, 0, 0);
-}
-
-static int calendar_get_wday(struct date *date)
-{
-  struct tm t;
-
-  memset(&t, 0, sizeof(struct tm));
-  t.tm_mday = date->dd;
-  t.tm_mon = date->mm - 1;
-  t.tm_year = date->yyyy - 1900;
-
-  mktime(&t);
-
-  return t.tm_wday;
-}
-
-static unsigned months_to_days(unsigned month)
-{
-  return (month * 3057 - 3007) / 100;
-}
-
-static long years_to_days(unsigned year)
-{
-  return year * 365L + year / 4 - year / 100 + year / 400;
-}
-
-static long ymd_to_scalar(unsigned year, unsigned month, unsigned day)
-{
-  long scalar;
-
-  scalar = day + months_to_days(month);
-  if (month > 2)
-    scalar -= ISLEAP(year) ? 1 : 2;
-  year--;
-  scalar += years_to_days(year);
-
-  return scalar;
-}
-
-/*
- * Used to change date by adding a certain amount of days or weeks.
- * Returns 0 on success, 1 otherwise.
- */
-static int date_change(struct tm *date, int delta_month, int delta_day)
-{
-  struct tm t;
-
-  t = *date;
-  t.tm_mon += delta_month;
-  t.tm_mday += delta_day;
-
-  if (mktime(&t) == -1)
-    return 1;
-  else {
-    *date = t;
-    return 0;
-  }
-}
-
-void calendar_monthly_view_cache_set_invalid(void)
-{
-  monthly_view_cache_valid = 0;
-}
-
-/* Draw the monthly view inside calendar panel. */
-static void
-draw_monthly_view(struct window *cwin, struct date *current_day,
-                  unsigned sunday_first)
-{
-  const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1);
-  struct date check_day;
-  int c_day, c_day_1, day_1_sav, numdays, j;
-  unsigned yr, mo;
-  int OFFX, SBAR_WIDTH, ofs_x, ofs_y;
-  int item_this_day = 0;
-
-  mo = slctd_day.mm;
-  yr = slctd_day.yyyy;
-
-  /* offset for centering calendar in window */
-  SBAR_WIDTH = wins_sbar_width();
-  OFFX = (SBAR_WIDTH - 27) / 2;
-  ofs_y = OFFY;
-  ofs_x = OFFX;
-
-  /* checking the number of days in february */
-  numdays = days[mo - 1];
-  if (2 == mo && ISLEAP(yr))
-    ++numdays;
-
-  /*
-   * the first calendar day will be monday or sunday, depending on
-   * 'week_begins_on_monday' value
-   */
-  c_day_1 = (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - (long)1) % 7L);
-
-  /* Write the current month and year on top of the calendar */
-  WINS_CALENDAR_LOCK;
-  custom_apply_attr(cwin->p, ATTR_HIGHEST);
-  mvwprintw(cwin->p, ofs_y,
-            (SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2,
-            "%s %d", _(monthnames[mo - 1]), slctd_day.yyyy);
-  custom_remove_attr(cwin->p, ATTR_HIGHEST);
-  ++ofs_y;
-
-  /* print the days, with regards to the first day of the week */
-  custom_apply_attr(cwin->p, ATTR_HIGHEST);
-  for (j = 0; j < WEEKINDAYS; j++) {
-    mvwaddstr(cwin->p, ofs_y, ofs_x + 4 * j, _(daynames[1 + j - sunday_first]));
-  }
-  custom_remove_attr(cwin->p, ATTR_HIGHEST);
-  WINS_CALENDAR_UNLOCK;
-
-  day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7;
-
-  /* invalidate cache if a new month is selected */
-  if (yr * YEARINMONTHS + mo != monthly_view_cache_month) {
-    monthly_view_cache_month = yr * YEARINMONTHS + mo;
-    monthly_view_cache_valid = 0;
-  }
-
-  for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) {
-    check_day.dd = c_day;
-    check_day.mm = slctd_day.mm;
-    check_day.yyyy = slctd_day.yyyy;
-
-    /* check if the day contains an event or an appointment */
-    if (monthly_view_cache_valid) {
-      item_this_day = monthly_view_cache[c_day - 1];
-    }
-    else {
-      item_this_day = monthly_view_cache[c_day - 1] =
-        day_check_if_item(check_day);
-    }
-
-    /* Go to next line, the week is over. */
-    if (!c_day_1 && 1 != c_day) {
-      ofs_y++;
-      ofs_x = OFFX - day_1_sav - 4 * c_day;
-    }
-
-    WINS_CALENDAR_LOCK;
-    if (c_day == current_day->dd
-        && current_day->mm == slctd_day.mm
-        && current_day->yyyy == slctd_day.yyyy
-        && current_day->dd != slctd_day.dd) {
-      /* This is today, so print it in yellow. */
-      custom_apply_attr(cwin->p, ATTR_LOWEST);
-      mvwprintw(cwin->p, ofs_y + 1,
-                ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
-      custom_remove_attr(cwin->p, ATTR_LOWEST);
-    } else if (c_day == slctd_day.dd) {
-      /* This is the selected day, print it according to user's theme. */
-      custom_apply_attr(cwin->p, ATTR_HIGHEST);
-      mvwprintw(cwin->p, ofs_y + 1,
-                ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
-      custom_remove_attr(cwin->p, ATTR_HIGHEST);
-    } else if (item_this_day) {
-      custom_apply_attr(cwin->p, ATTR_LOW);
-      mvwprintw(cwin->p, ofs_y + 1,
-                ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
-      custom_remove_attr(cwin->p, ATTR_LOW);
-    } else {
-      /* otherwise, print normal days in black */
-      mvwprintw(cwin->p, ofs_y + 1,
-                ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
-    }
-    WINS_CALENDAR_UNLOCK;
-  }
-
-  monthly_view_cache_valid = 1;
-}
-
-static int weeknum(const struct tm *t, int firstweekday)
-{
-  int wday, wnum;
-
-  wday = t->tm_wday;
-  if (firstweekday == MONDAY) {
-    if (wday == SUNDAY)
-      wday = 6;
-    else
-      wday--;
-  }
-  wnum = ((t->tm_yday + WEEKINDAYS - wday) / WEEKINDAYS);
-  if (wnum < 0)
-    wnum = 0;
-
-  return wnum;
-}
-
-/*
- * Compute the week number according to ISO 8601.
- */
-static int ISO8601weeknum(const struct tm *t)
-{
-  int wnum, jan1day;
-
-  wnum = weeknum(t, MONDAY);
-
-  jan1day = t->tm_wday - (t->tm_yday % WEEKINDAYS);
-  if (jan1day < 0)
-    jan1day += WEEKINDAYS;
-
-  switch (jan1day) {
-  case MONDAY:
-    break;
-  case TUESDAY:
-  case WEDNESDAY:
-  case THURSDAY:
-    wnum++;
-    break;
-  case FRIDAY:
-  case SATURDAY:
-  case SUNDAY:
-    if (wnum == 0) {
-      /* Get week number of last week of last year. */
-      struct tm dec31ly;        /* 12/31 last year */
-
-      dec31ly = *t;
-      dec31ly.tm_year--;
-      dec31ly.tm_mon = 11;
-      dec31ly.tm_mday = 31;
-      dec31ly.tm_wday = (jan1day == SUNDAY) ? 6 : jan1day - 1;
-      dec31ly.tm_yday = 364 + ISLEAP(dec31ly.tm_year + 1900);
-      wnum = ISO8601weeknum(&dec31ly);
-    }
-    break;
-  }
-
-  if (t->tm_mon == 11) {
-    int wday, mday;
-
-    wday = t->tm_wday;
-    mday = t->tm_mday;
-    if ((wday == MONDAY && (mday >= 29 && mday <= 31))
-        || (wday == TUESDAY && (mday == 30 || mday == 31))
-        || (wday == WEDNESDAY && mday == 31))
-      wnum = 1;
-  }
-
-  return wnum;
-}
-
-/* Draw the weekly view inside calendar panel. */
-static void
-draw_weekly_view(struct window *cwin, struct date *current_day,
-                 unsigned sunday_first)
-{
-#define DAYSLICESNO  6
-  const int WCALWIDTH = 30;
-  const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1);
-  struct tm t;
-  int OFFX, j, c_wday, days_to_remove, weeknum;
-
-  OFFX = (wins_sbar_width() - WCALWIDTH) / 2 + 1;
-
-  /* Fill in a tm structure with the first day of the selected week. */
-  c_wday = calendar_get_wday(&slctd_day);
-  if (sunday_first)
-    days_to_remove = c_wday;
-  else
-    days_to_remove = c_wday == 0 ? WEEKINDAYS - 1 : c_wday - 1;
-
-  memset(&t, 0, sizeof(struct tm));
-  t.tm_mday = slctd_day.dd;
-  t.tm_mon = slctd_day.mm - 1;
-  t.tm_year = slctd_day.yyyy - 1900;
-  mktime(&t);
-  date_change(&t, 0, -days_to_remove);
-
-  /* Print the week number. */
-  weeknum = ISO8601weeknum(&t);
-  WINS_CALENDAR_LOCK;
-  custom_apply_attr(cwin->p, ATTR_HIGHEST);
-  mvwprintw(cwin->p, conf.compact_panels ? 0 : 2, cwin->w - 9, "(# %02d)",
-            weeknum);
-  custom_remove_attr(cwin->p, ATTR_HIGHEST);
-  WINS_CALENDAR_UNLOCK;
-
-  /* Now draw calendar view. */
-  for (j = 0; j < WEEKINDAYS; j++) {
-    struct date date;
-    unsigned attr, item_this_day;
-    int i, slices[DAYSLICESNO];
-
-    /* print the day names, with regards to the first day of the week */
-    custom_apply_attr(cwin->p, ATTR_HIGHEST);
-    mvwaddstr(cwin->p, OFFY, OFFX + 4 * j, _(daynames[1 + j - sunday_first]));
-    custom_remove_attr(cwin->p, ATTR_HIGHEST);
-
-    /* Check if the day to be printed has an item or not. */
-    date.dd = t.tm_mday;
-    date.mm = t.tm_mon + 1;
-    date.yyyy = t.tm_year + 1900;
-    item_this_day = day_check_if_item(date);
-
-    /* Print the day numbers with appropriate decoration. */
-    if (t.tm_mday == current_day->dd
-        && current_day->mm == slctd_day.mm
-        && current_day->yyyy == slctd_day.yyyy
-        && current_day->dd != slctd_day.dd)
-      attr = ATTR_LOWEST;       /* today, but not selected */
-    else if (t.tm_mday == slctd_day.dd)
-      attr = ATTR_HIGHEST;      /* selected day */
-    else if (item_this_day)
-      attr = ATTR_LOW;
-    else
-      attr = 0;
-
-    WINS_CALENDAR_LOCK;
-    if (attr)
-      custom_apply_attr(cwin->p, attr);
-    mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday);
-    if (attr)
-      custom_remove_attr(cwin->p, attr);
-    WINS_CALENDAR_UNLOCK;
-
-    /* Draw slices indicating appointment times. */
-    memset(slices, 0, DAYSLICESNO * sizeof *slices);
-    if (day_chk_busy_slices(date, DAYSLICESNO, slices)) {
-      for (i = 0; i < DAYSLICESNO; i++) {
-        if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1) {
-          WINS_CALENDAR_LOCK;
-          mvwhline(cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2);
-          WINS_CALENDAR_UNLOCK;
-        }
-        if (slices[i]) {
-          int highlight;
-
-          highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0;
-          WINS_CALENDAR_LOCK;
-          if (highlight)
-            custom_apply_attr(cwin->p, attr);
-          wattron(cwin->p, A_REVERSE);
-          mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 1 + 4 * j, " ");
-          mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 2 + 4 * j, " ");
-          wattroff(cwin->p, A_REVERSE);
-          if (highlight)
-            custom_remove_attr(cwin->p, attr);
-          WINS_CALENDAR_UNLOCK;
-        }
-      }
-    }
-
-    /* get next day */
-    date_change(&t, 0, 1);
-  }
-
-  /* Draw marks to indicate midday on the sides of the calendar. */
-  WINS_CALENDAR_LOCK;
-  custom_apply_attr(cwin->p, ATTR_HIGHEST);
-  mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1);
-  mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2,
-           OFFX + WCALWIDTH - 3, ACS_S9, 1);
-  custom_remove_attr(cwin->p, ATTR_HIGHEST);
-  WINS_CALENDAR_UNLOCK;
-
-#undef DAYSLICESNO
-}
-
-/* Function used to display the calendar panel. */
-void calendar_update_panel(struct window *cwin)
-{
-  struct date current_day;
-  unsigned sunday_first;
-
-  calendar_store_current_date(&current_day);
-
-  WINS_CALENDAR_LOCK;
-  erase_window_part(cwin->p, 1, conf.compact_panels ? 1 : 3, cwin->w - 2,
-                    cwin->h - 2);
-  if (!conf.compact_panels)
-    mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2);
-  WINS_CALENDAR_UNLOCK;
-
-  sunday_first = calendar_week_begins_on_monday()? 0 : 1;
-
-  draw_calendar[calendar_view] (cwin, &current_day, sunday_first);
-
-  wnoutrefresh(cwin->p);
-}
-
-/* Set the selected day in calendar to current day. */
-void calendar_goto_today(void)
-{
-  struct date today;
-
-  calendar_store_current_date(&today);
-  slctd_day.dd = today.dd;
-  slctd_day.mm = today.mm;
-  slctd_day.yyyy = today.yyyy;
-}
-
-/*
- * Ask for a date to jump to, then check the correctness of that date
- * and jump to it.
- * If the entered date is empty, automatically jump to the current date.
- * slctd_day is updated with the newly selected date.
- */
-void calendar_change_day(int datefmt)
-{
-#define LDAY 11
-  char selected_day[LDAY] = "";
-  char outstr[BUFSIZ];
-  int dday, dmonth, dyear;
-  int wrong_day = 1;
-  const char *mesg_line1 =
-      _("The day you entered is not valid "
-        "(should be between 01/01/1902 and 12/31/2037)");
-  const char *mesg_line2 = _("Press [ENTER] to continue");
-  const char *request_date = _("Enter the day to go to [ENTER for today] : %s");
-
-  while (wrong_day) {
-    snprintf(outstr, BUFSIZ, request_date, DATEFMT_DESC(datefmt));
-    status_mesg(outstr, "");
-    if (getstring(win[STA].p, selected_day, LDAY, 0, 1) == GETSTRING_ESC)
-      return;
-    else {
-      if (strlen(selected_day) == 0) {
-        wrong_day = 0;
-        calendar_goto_today();
-      } else if (parse_date(selected_day, datefmt, &dyear, &dmonth, &dday,
-                            calendar_get_slctd_day())) {
-        wrong_day = 0;
-        /* go to chosen day */
-        slctd_day.dd = dday;
-        slctd_day.mm = dmonth;
-        slctd_day.yyyy = dyear;
-      }
-      if (wrong_day) {
-        status_mesg(mesg_line1, mesg_line2);
-        wgetch(win[KEY].p);
-      }
-    }
-  }
-
-  return;
-}
-
-void calendar_move(enum move move, int count)
-{
-  int ret, days_to_remove, days_to_add;
-  struct tm t;
-
-  memset(&t, 0, sizeof(struct tm));
-  t.tm_mday = slctd_day.dd;
-  t.tm_mon = slctd_day.mm - 1;
-  t.tm_year = slctd_day.yyyy - 1900;
-
-  switch (move) {
-  case DAY_PREV:
-    ret = date_change(&t, 0, -count);
-    break;
-  case DAY_NEXT:
-    ret = date_change(&t, 0, count);
-    break;
-  case WEEK_PREV:
-    ret = date_change(&t, 0, -count * WEEKINDAYS);
-    break;
-  case WEEK_NEXT:
-    ret = date_change(&t, 0, count * WEEKINDAYS);
-    break;
-  case MONTH_PREV:
-    ret = date_change(&t, -count, 0);
-    break;
-  case MONTH_NEXT:
-    ret = date_change(&t, count, 0);
-    break;
-  case YEAR_PREV:
-    ret = date_change(&t, -count * YEARINMONTHS, 0);
-    break;
-  case YEAR_NEXT:
-    ret = date_change(&t, count * YEARINMONTHS, 0);
-    break;
-  case WEEK_START:
-    /* Normalize struct tm to get week day number. */
-    mktime(&t);
-    if (calendar_week_begins_on_monday())
-      days_to_remove = ((t.tm_wday == 0) ? WEEKINDAYS - 1 : t.tm_wday - 1);
-    else
-      days_to_remove = ((t.tm_wday == 0) ? 0 : t.tm_wday);
-    days_to_remove += (count - 1) * WEEKINDAYS;
-    ret = date_change(&t, 0, -days_to_remove);
-    break;
-  case WEEK_END:
-    mktime(&t);
-    if (calendar_week_begins_on_monday())
-      days_to_add = ((t.tm_wday == 0) ? 0 : WEEKINDAYS - t.tm_wday);
-    else
-      days_to_add = ((t.tm_wday == 0) ?
-                     WEEKINDAYS - 1 : WEEKINDAYS - 1 - t.tm_wday);
-    days_to_add += (count - 1) * WEEKINDAYS;
-    ret = date_change(&t, 0, days_to_add);
-    break;
-  default:
-    ret = 1;
-    /* NOTREACHED */
-  }
-
-  if (ret == 0) {
-    if (t.tm_year < 2) {
-      t.tm_mday = 1;
-      t.tm_mon = 0;
-      t.tm_year = 2;
-    } else if (t.tm_year > 137) {
-      t.tm_mday = 31;
-      t.tm_mon = 11;
-      t.tm_year = 137;
-    }
-
-    slctd_day.dd = t.tm_mday;
-    slctd_day.mm = t.tm_mon + 1;
-    slctd_day.yyyy = t.tm_year + 1900;
-  }
-}
-
-/* Returns the beginning of current year as a long. */
-long calendar_start_of_year(void)
-{
-  time_t timer;
-  struct tm tm;
-
-  timer = time(NULL);
-  localtime_r(&timer, &tm);
-  tm.tm_mon = 0;
-  tm.tm_mday = 1;
-  tm.tm_hour = 0;
-  tm.tm_min = 0;
-  tm.tm_sec = 0;
-  timer = mktime(&tm);
-
-  return (long)timer;
-}
-
-long calendar_end_of_year(void)
-{
-  time_t timer;
-  struct tm tm;
-
-  timer = time(NULL);
-  localtime_r(&timer, &tm);
-  tm.tm_mon = 0;
-  tm.tm_mday = 1;
-  tm.tm_hour = 0;
-  tm.tm_min = 0;
-  tm.tm_sec = 0;
-  tm.tm_year++;
-  timer = mktime(&tm);
-
-  return (long)(timer - 1);
-}
-
-/*
- * The pom, potm, dotr, adj360 are used to compute the current
- * phase of the moon.
- * The code is based on the OpenBSD version of pom(6).
- * Below is reported the copyright notice.
- */
-/*
- * Copyright (c) 1989, 1993
- *	The Regents of the University of California.  All rights reserved.
- *
- * This code is derived from software posted to USENET.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-/*
- * dtor --
- *	convert degrees to radians
- */
-static double dtor(double deg)
-{
-  return deg * M_PI / 180;
-}
-
-/*
- * adj360 --
- *	adjust value so 0 <= deg <= 360
- */
-static void adj360(double *deg)
-{
-  for (;;)
-    if (*deg < 0.0)
-      *deg += 360.0;
-    else if (*deg > 360.0)
-      *deg -= 360.0;
-    else
-      break;
-}
-
-/*
- * potm --
- *	return phase of the moon
- */
-static double potm(double days)
-{
-  double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime;
-  double A4, lprime, V, ldprime, D, Nm;
-
-  N = 360.0 * days / 365.242191;        /* sec 46 #3 */
-  adj360(&N);
-  Msol = N + EPSILONg - RHOg;   /* sec 46 #4 */
-  adj360(&Msol);
-  Ec = 360 / M_PI * ECCEN * sin(dtor(Msol));    /* sec 46 #5 */
-  LambdaSol = N + Ec + EPSILONg;        /* sec 46 #6 */
-  adj360(&LambdaSol);
-  l = 13.1763966 * days + lzero;        /* sec 65 #4 */
-  adj360(&l);
-  Mm = l - (0.1114041 * days) - Pzero;  /* sec 65 #5 */
-  adj360(&Mm);
-  Nm = Nzero - (0.0529539 * days);      /* sec 65 #6 */
-  adj360(&Nm);
-  Ev = 1.2739 * sin(dtor(2 * (l - LambdaSol) - Mm));    /* sec 65 #7 */
-  Ac = 0.1858 * sin(dtor(Msol));        /* sec 65 #8 */
-  A3 = 0.37 * sin(dtor(Msol));
-  Mmprime = Mm + Ev - Ac - A3;  /* sec 65 #9 */
-  Ec = 6.2886 * sin(dtor(Mmprime));     /* sec 65 #10 */
-  A4 = 0.214 * sin(dtor(2 * Mmprime));  /* sec 65 #11 */
-  lprime = l + Ev + Ec - Ac + A4;       /* sec 65 #12 */
-  V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol)));     /* sec 65 #13 */
-  ldprime = lprime + V;         /* sec 65 #14 */
-  D = ldprime - LambdaSol;      /* sec 67 #2 */
-  return 50.0 * (1 - cos(dtor(D)));     /* sec 67 #3 */
-}
-
-/*
- * Phase of the Moon.  Calculates the current phase of the moon.
- * Based on routines from `Practical Astronomy with Your Calculator',
- * by Duffett-Smith.  Comments give the section from the book that
- * particular piece of code was adapted from.
- *
- * -- Keith E. Brandt  VIII 1984
- *
- * Updated to the Third Edition of Duffett-Smith's book, IX 1998
- *
- */
-static double pom(time_t tmpt)
-{
-  struct tm *GMT;
-  double days;
-  int cnt;
-
-  GMT = gmtime(&tmpt);
-  days = (GMT->tm_yday + 1) + ((GMT->tm_hour + (GMT->tm_min / 60.0) +
-                                (GMT->tm_sec / 3600.0)) / 24.0);
-  for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt)
-    days += ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365;
-  /* Selected time could be before EPOCH */
-  for (cnt = GMT->tm_year; cnt < EPOCH; ++cnt)
-    days -= ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365;
-
-  return potm(days);
-}
-
-/*
- * Return a pictogram representing the current phase of the moon.
- * Careful: date is the selected day in calendar at 00:00, so it represents
- * the phase of the moon for previous day.
- */
-const char *calendar_get_pom(time_t date)
-{
-  const char *pom_pict[MOON_PHASES] = { "   ", "|) ", "(|)", "(| ", " | " };
-  enum pom phase = NO_POM;
-  double pom_today, relative_pom, pom_yesterday, pom_tomorrow;
-  const double half = 50.0;
-
-  pom_yesterday = pom(date);
-  pom_today = pom(date + DAYINSEC);
-  relative_pom = abs(pom_today - half);
-  pom_tomorrow = pom(date + 2 * DAYINSEC);
-  if (pom_today > pom_yesterday && pom_today > pom_tomorrow)
-    phase = FULL_MOON;
-  else if (pom_today < pom_yesterday && pom_today < pom_tomorrow)
-    phase = NEW_MOON;
-  else if (relative_pom < abs(pom_yesterday - half)
-           && relative_pom < abs(pom_tomorrow - half))
-    phase = (pom_tomorrow > pom_today) ? FIRST_QUARTER : LAST_QUARTER;
-
-  return pom_pict[phase];
-}
diff --git a/src/config.c b/src/config.c
index 83d1a93..72ce7fa 100644
--- a/src/config.c
+++ b/src/config.c
@@ -202,9 +202,9 @@ static int config_parse_color_pair(int *dest1, int *dest2, const char *val)
 static int config_parse_calendar_view(void *dummy, const char *val)
 {
   if (!strcmp(val, "monthly"))
-    calendar_set_view(CAL_MONTH_VIEW);
+    ui_calendar_set_view(CAL_MONTH_VIEW);
   else if (!strcmp(val, "weekly"))
-    calendar_set_view(CAL_WEEK_VIEW);
+    ui_calendar_set_view(CAL_WEEK_VIEW);
   else
     return 0;
 
@@ -228,9 +228,9 @@ static int config_parse_default_panel(void *dummy, const char *val)
 static int config_parse_first_day_of_week(void *dummy, const char *val)
 {
   if (!strcmp(val, "monday"))
-    calendar_set_first_day_of_week(MONDAY);
+    ui_calendar_set_first_day_of_week(MONDAY);
   else if (!strcmp(val, "sunday"))
-    calendar_set_first_day_of_week(SUNDAY);
+    ui_calendar_set_first_day_of_week(SUNDAY);
   else
     return 0;
 
@@ -379,7 +379,7 @@ static void config_color_theme_name(char *theme_name)
 
 static int config_serialize_calendar_view(char *buf, void *dummy)
 {
-  if (calendar_get_view() == CAL_WEEK_VIEW)
+  if (ui_calendar_get_view() == CAL_WEEK_VIEW)
     strcpy(buf, "weekly");
   else
     strcpy(buf, "monthly");
@@ -401,7 +401,7 @@ static int config_serialize_default_panel(char *buf, void *dummy)
 
 static int config_serialize_first_day_of_week(char *buf, void *dummy)
 {
-  if (calendar_week_begins_on_monday())
+  if (ui_calendar_week_begins_on_monday())
     strcpy(buf, "monday");
   else
     strcpy(buf, "sunday");
diff --git a/src/custom.c b/src/custom.c
index df344c2..45cd07a 100644
--- a/src/custom.c
+++ b/src/custom.c
@@ -668,7 +668,7 @@ static int print_general_options(WINDOW * win)
   mvwprintw(win, y, XPOS, "[8] %s      ", opt[FIRST_DAY_OF_WEEK]);
   custom_apply_attr(win, ATTR_HIGHEST);
   mvwaddstr(win, y, XPOS + 4 + strlen(opt[FIRST_DAY_OF_WEEK]),
-            calendar_week_begins_on_monday()? _("Monday") : _("Sunday"));
+            ui_calendar_week_begins_on_monday()? _("Monday") : _("Sunday"));
   custom_remove_attr(win, ATTR_HIGHEST);
   mvwaddstr(win, y + 1, XPOS,
             _("(specifies the first day of week in the calendar view)"));
@@ -773,7 +773,7 @@ void custom_general_config(void)
       conf.progress_bar = !conf.progress_bar;
       break;
     case '8':
-      calendar_change_first_day_of_week();
+      ui_calendar_change_first_day_of_week();
       break;
     case '9':
       status_mesg(output_datefmt_str, "");
diff --git a/src/day.c b/src/day.c
index 4c2f5bf..2e3b4bf 100644
--- a/src/day.c
+++ b/src/day.c
@@ -370,7 +370,7 @@ struct day_items_nb day_process_storage(struct date *slctd_date,
   if (slctd_date)
     day = *slctd_date;
   else
-    calendar_store_current_date(&day);
+    ui_calendar_store_current_date(&day);
 
   date = date2sec(day, 0, 0);
 
@@ -545,7 +545,7 @@ void day_popup_item(struct day_item *day)
     struct apoint apt_tmp;
     apt_tmp.start = day->start;
     apt_tmp.dur = day_item_get_duration(day);
-    apoint_sec2str(&apt_tmp, calendar_get_slctd_day_sec(), a_st, a_end);
+    apoint_sec2str(&apt_tmp, ui_calendar_get_slctd_day_sec(), a_st, a_end);
 
     item_in_popup(a_st, a_end, day_item_get_mesg(day), _("Appointment :"));
   } else {
diff --git a/src/pcal.c b/src/pcal.c
index 8bcc0b5..e2721e6 100644
--- a/src/pcal.c
+++ b/src/pcal.c
@@ -101,7 +101,7 @@ static void pcal_export_header(FILE * stream)
   fputs("# calcurse pcal export\n", stream);
   fputs("\n# =======\n# options\n# =======\n", stream);
   fprintf(stream, "opt -A -K -l -m -F %s\n",
-          calendar_week_begins_on_monday()? "Monday" : "Sunday");
+          ui_calendar_week_begins_on_monday()? "Monday" : "Sunday");
   fputs("# Display week number (i.e. 1-52) on every Monday\n", stream);
   fprintf(stream, "all monday in all week %%w\n");
   fputc('\n', stream);
@@ -172,8 +172,8 @@ static void pcal_export_recur_events(FILE * stream)
         EXIT(_("incoherent repetition type"));
       }
     } else {
-      const long YEAR_START = calendar_start_of_year();
-      const long YEAR_END = calendar_end_of_year();
+      const long YEAR_START = ui_calendar_start_of_year();
+      const long YEAR_END = ui_calendar_end_of_year();
 
       if (rev->day < YEAR_END && rev->day > YEAR_START)
         foreach_date_dump(YEAR_END, rev->rpt, &rev->exc, rev->day, 0,
@@ -237,8 +237,8 @@ static void pcal_export_recur_apoints(FILE * stream)
         EXIT(_("incoherent repetition type"));
       }
     } else {
-      const long YEAR_START = calendar_start_of_year();
-      const long YEAR_END = calendar_end_of_year();
+      const long YEAR_START = ui_calendar_start_of_year();
+      const long YEAR_END = ui_calendar_end_of_year();
 
       if (rapt->start < YEAR_END && rapt->start > YEAR_START)
         foreach_date_dump(YEAR_END, rapt->rpt, &rapt->exc, rapt->start,
diff --git a/src/ui-calendar.c b/src/ui-calendar.c
new file mode 100644
index 0000000..f9749c8
--- /dev/null
+++ b/src/ui-calendar.c
@@ -0,0 +1,915 @@
+/*
+ * Calcurse - text-based organizer
+ *
+ * Copyright (c) 2004-2013 calcurse Development Team <misc@calcurse.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ *      - Redistributions of source code must retain the above
+ *        copyright notice, this list of conditions and the
+ *        following disclaimer.
+ *
+ *      - Redistributions in binary form must reproduce the above
+ *        copyright notice, this list of conditions and the
+ *        following disclaimer in the documentation and/or other
+ *        materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Send your feedback or comments to : misc@calcurse.org
+ * Calcurse home page : http://calcurse.org
+ *
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+#include <math.h>
+
+#include "calcurse.h"
+
+#ifndef M_PI
+#define	M_PI	  3.14159265358979323846
+#endif
+
+#define	EPOCH	  90
+#define	EPSILONg  279.403303    /* solar ecliptic long at EPOCH */
+#define	RHOg	  282.768422    /* solar ecliptic long of perigee at EPOCH */
+#define	ECCEN	  0.016713      /* solar orbit eccentricity */
+#define	lzero	  318.351648    /* lunar mean long at EPOCH */
+#define	Pzero	  36.340410     /* lunar mean long of perigee at EPOCH */
+#define	Nzero	  318.510107    /* lunar mean long of node at EPOCH */
+
+#define ISLEAP(y) ((((y) % 4) == 0 && ((y) % 100) != 0) || ((y) % 400) == 0)
+
+enum pom {
+  NO_POM,
+  FIRST_QUARTER,
+  FULL_MOON,
+  LAST_QUARTER,
+  NEW_MOON,
+  MOON_PHASES
+};
+
+static struct date today, slctd_day;
+static unsigned ui_calendar_view, week_begins_on_monday;
+static pthread_mutex_t date_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t ui_calendar_t_date;
+
+static void draw_monthly_view(struct window *, struct date *, unsigned);
+static void draw_weekly_view(struct window *, struct date *, unsigned);
+static void (*draw_calendar[CAL_VIEWS]) (struct window *, struct date *,
+                                         unsigned) = {
+draw_monthly_view, draw_weekly_view};
+
+static int monthly_view_cache[MAXDAYSPERMONTH];
+static int monthly_view_cache_valid = 0;
+static int monthly_view_cache_month = 0;
+
+/* Switch between calendar views (monthly view is selected by default). */
+void ui_calendar_view_next(void)
+{
+  ui_calendar_view++;
+  if (ui_calendar_view == CAL_VIEWS)
+    ui_calendar_view = 0;
+}
+
+void ui_calendar_view_prev(void)
+{
+  if (ui_calendar_view == 0)
+    ui_calendar_view = CAL_VIEWS;
+  ui_calendar_view--;
+}
+
+void ui_calendar_set_view(int view)
+{
+  ui_calendar_view = (view < 0 || view >= CAL_VIEWS) ? CAL_MONTH_VIEW : view;
+}
+
+int ui_calendar_get_view(void)
+{
+  return (int)ui_calendar_view;
+}
+
+/* Thread needed to update current date in calendar. */
+/* ARGSUSED0 */
+static void *ui_calendar_date_thread(void *arg)
+{
+  time_t actual, tomorrow;
+
+  for (;;) {
+    tomorrow = (time_t) (get_today() + DAYINSEC);
+
+    while ((actual = time(NULL)) < tomorrow)
+      sleep(tomorrow - actual);
+
+    ui_calendar_set_current_date();
+    ui_calendar_update_panel(&win[CAL]);
+  }
+
+  return NULL;
+}
+
+/* Launch the calendar date thread. */
+void ui_calendar_start_date_thread(void)
+{
+  pthread_create(&ui_calendar_t_date, NULL, ui_calendar_date_thread, NULL);
+}
+
+/* Stop the calendar date thread. */
+void ui_calendar_stop_date_thread(void)
+{
+  if (ui_calendar_t_date) {
+    pthread_cancel(ui_calendar_t_date);
+    pthread_join(ui_calendar_t_date, NULL);
+  }
+}
+
+/* Set static variable today to current date */
+void ui_calendar_set_current_date(void)
+{
+  time_t timer;
+  struct tm tm;
+
+  timer = time(NULL);
+  localtime_r(&timer, &tm);
+
+  pthread_mutex_lock(&date_thread_mutex);
+  today.dd = tm.tm_mday;
+  today.mm = tm.tm_mon + 1;
+  today.yyyy = tm.tm_year + 1900;
+  pthread_mutex_unlock(&date_thread_mutex);
+}
+
+/* Needed to display sunday or monday as the first day of week in calendar. */
+void ui_calendar_set_first_day_of_week(enum wday first_day)
+{
+  switch (first_day) {
+  case SUNDAY:
+    week_begins_on_monday = 0;
+    break;
+  case MONDAY:
+    week_begins_on_monday = 1;
+    break;
+  default:
+    ERROR_MSG(_("ERROR setting first day of week"));
+    week_begins_on_monday = 0;
+    /* NOTREACHED */
+  }
+}
+
+/* Swap first day of week in calendar. */
+void ui_calendar_change_first_day_of_week(void)
+{
+  week_begins_on_monday = !week_begins_on_monday;
+}
+
+/* Return 1 if week begins on monday, 0 otherwise. */
+unsigned ui_calendar_week_begins_on_monday(void)
+{
+  return week_begins_on_monday;
+}
+
+/* Fill in the given variable with the current date. */
+void ui_calendar_store_current_date(struct date *date)
+{
+  pthread_mutex_lock(&date_thread_mutex);
+  *date = today;
+  pthread_mutex_unlock(&date_thread_mutex);
+}
+
+/* This is to start at the current date in calendar. */
+void ui_calendar_init_slctd_day(void)
+{
+  ui_calendar_store_current_date(&slctd_day);
+}
+
+/* Return the selected day in calendar */
+struct date *ui_calendar_get_slctd_day(void)
+{
+  return &slctd_day;
+}
+
+/* Returned value represents the selected day in calendar (in seconds) */
+long ui_calendar_get_slctd_day_sec(void)
+{
+  return date2sec(slctd_day, 0, 0);
+}
+
+static int ui_calendar_get_wday(struct date *date)
+{
+  struct tm t;
+
+  memset(&t, 0, sizeof(struct tm));
+  t.tm_mday = date->dd;
+  t.tm_mon = date->mm - 1;
+  t.tm_year = date->yyyy - 1900;
+
+  mktime(&t);
+
+  return t.tm_wday;
+}
+
+static unsigned months_to_days(unsigned month)
+{
+  return (month * 3057 - 3007) / 100;
+}
+
+static long years_to_days(unsigned year)
+{
+  return year * 365L + year / 4 - year / 100 + year / 400;
+}
+
+static long ymd_to_scalar(unsigned year, unsigned month, unsigned day)
+{
+  long scalar;
+
+  scalar = day + months_to_days(month);
+  if (month > 2)
+    scalar -= ISLEAP(year) ? 1 : 2;
+  year--;
+  scalar += years_to_days(year);
+
+  return scalar;
+}
+
+/*
+ * Used to change date by adding a certain amount of days or weeks.
+ * Returns 0 on success, 1 otherwise.
+ */
+static int date_change(struct tm *date, int delta_month, int delta_day)
+{
+  struct tm t;
+
+  t = *date;
+  t.tm_mon += delta_month;
+  t.tm_mday += delta_day;
+
+  if (mktime(&t) == -1)
+    return 1;
+  else {
+    *date = t;
+    return 0;
+  }
+}
+
+void ui_calendar_monthly_view_cache_set_invalid(void)
+{
+  monthly_view_cache_valid = 0;
+}
+
+/* Draw the monthly view inside calendar panel. */
+static void
+draw_monthly_view(struct window *cwin, struct date *current_day,
+                  unsigned sunday_first)
+{
+  const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1);
+  struct date check_day;
+  int c_day, c_day_1, day_1_sav, numdays, j;
+  unsigned yr, mo;
+  int OFFX, SBAR_WIDTH, ofs_x, ofs_y;
+  int item_this_day = 0;
+
+  mo = slctd_day.mm;
+  yr = slctd_day.yyyy;
+
+  /* offset for centering calendar in window */
+  SBAR_WIDTH = wins_sbar_width();
+  OFFX = (SBAR_WIDTH - 27) / 2;
+  ofs_y = OFFY;
+  ofs_x = OFFX;
+
+  /* checking the number of days in february */
+  numdays = days[mo - 1];
+  if (2 == mo && ISLEAP(yr))
+    ++numdays;
+
+  /*
+   * the first calendar day will be monday or sunday, depending on
+   * 'week_begins_on_monday' value
+   */
+  c_day_1 = (int)((ymd_to_scalar(yr, mo, 1 + sunday_first) - (long)1) % 7L);
+
+  /* Write the current month and year on top of the calendar */
+  WINS_CALENDAR_LOCK;
+  custom_apply_attr(cwin->p, ATTR_HIGHEST);
+  mvwprintw(cwin->p, ofs_y,
+            (SBAR_WIDTH - (strlen(_(monthnames[mo - 1])) + 5)) / 2,
+            "%s %d", _(monthnames[mo - 1]), slctd_day.yyyy);
+  custom_remove_attr(cwin->p, ATTR_HIGHEST);
+  ++ofs_y;
+
+  /* print the days, with regards to the first day of the week */
+  custom_apply_attr(cwin->p, ATTR_HIGHEST);
+  for (j = 0; j < WEEKINDAYS; j++) {
+    mvwaddstr(cwin->p, ofs_y, ofs_x + 4 * j, _(daynames[1 + j - sunday_first]));
+  }
+  custom_remove_attr(cwin->p, ATTR_HIGHEST);
+  WINS_CALENDAR_UNLOCK;
+
+  day_1_sav = (c_day_1 + 1) * 3 + c_day_1 - 7;
+
+  /* invalidate cache if a new month is selected */
+  if (yr * YEARINMONTHS + mo != monthly_view_cache_month) {
+    monthly_view_cache_month = yr * YEARINMONTHS + mo;
+    monthly_view_cache_valid = 0;
+  }
+
+  for (c_day = 1; c_day <= numdays; ++c_day, ++c_day_1, c_day_1 %= 7) {
+    check_day.dd = c_day;
+    check_day.mm = slctd_day.mm;
+    check_day.yyyy = slctd_day.yyyy;
+
+    /* check if the day contains an event or an appointment */
+    if (monthly_view_cache_valid) {
+      item_this_day = monthly_view_cache[c_day - 1];
+    }
+    else {
+      item_this_day = monthly_view_cache[c_day - 1] =
+        day_check_if_item(check_day);
+    }
+
+    /* Go to next line, the week is over. */
+    if (!c_day_1 && 1 != c_day) {
+      ofs_y++;
+      ofs_x = OFFX - day_1_sav - 4 * c_day;
+    }
+
+    WINS_CALENDAR_LOCK;
+    if (c_day == current_day->dd
+        && current_day->mm == slctd_day.mm
+        && current_day->yyyy == slctd_day.yyyy
+        && current_day->dd != slctd_day.dd) {
+      /* This is today, so print it in yellow. */
+      custom_apply_attr(cwin->p, ATTR_LOWEST);
+      mvwprintw(cwin->p, ofs_y + 1,
+                ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
+      custom_remove_attr(cwin->p, ATTR_LOWEST);
+    } else if (c_day == slctd_day.dd) {
+      /* This is the selected day, print it according to user's theme. */
+      custom_apply_attr(cwin->p, ATTR_HIGHEST);
+      mvwprintw(cwin->p, ofs_y + 1,
+                ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
+      custom_remove_attr(cwin->p, ATTR_HIGHEST);
+    } else if (item_this_day) {
+      custom_apply_attr(cwin->p, ATTR_LOW);
+      mvwprintw(cwin->p, ofs_y + 1,
+                ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
+      custom_remove_attr(cwin->p, ATTR_LOW);
+    } else {
+      /* otherwise, print normal days in black */
+      mvwprintw(cwin->p, ofs_y + 1,
+                ofs_x + day_1_sav + 4 * c_day + 1, "%2d", c_day);
+    }
+    WINS_CALENDAR_UNLOCK;
+  }
+
+  monthly_view_cache_valid = 1;
+}
+
+static int weeknum(const struct tm *t, int firstweekday)
+{
+  int wday, wnum;
+
+  wday = t->tm_wday;
+  if (firstweekday == MONDAY) {
+    if (wday == SUNDAY)
+      wday = 6;
+    else
+      wday--;
+  }
+  wnum = ((t->tm_yday + WEEKINDAYS - wday) / WEEKINDAYS);
+  if (wnum < 0)
+    wnum = 0;
+
+  return wnum;
+}
+
+/*
+ * Compute the week number according to ISO 8601.
+ */
+static int ISO8601weeknum(const struct tm *t)
+{
+  int wnum, jan1day;
+
+  wnum = weeknum(t, MONDAY);
+
+  jan1day = t->tm_wday - (t->tm_yday % WEEKINDAYS);
+  if (jan1day < 0)
+    jan1day += WEEKINDAYS;
+
+  switch (jan1day) {
+  case MONDAY:
+    break;
+  case TUESDAY:
+  case WEDNESDAY:
+  case THURSDAY:
+    wnum++;
+    break;
+  case FRIDAY:
+  case SATURDAY:
+  case SUNDAY:
+    if (wnum == 0) {
+      /* Get week number of last week of last year. */
+      struct tm dec31ly;        /* 12/31 last year */
+
+      dec31ly = *t;
+      dec31ly.tm_year--;
+      dec31ly.tm_mon = 11;
+      dec31ly.tm_mday = 31;
+      dec31ly.tm_wday = (jan1day == SUNDAY) ? 6 : jan1day - 1;
+      dec31ly.tm_yday = 364 + ISLEAP(dec31ly.tm_year + 1900);
+      wnum = ISO8601weeknum(&dec31ly);
+    }
+    break;
+  }
+
+  if (t->tm_mon == 11) {
+    int wday, mday;
+
+    wday = t->tm_wday;
+    mday = t->tm_mday;
+    if ((wday == MONDAY && (mday >= 29 && mday <= 31))
+        || (wday == TUESDAY && (mday == 30 || mday == 31))
+        || (wday == WEDNESDAY && mday == 31))
+      wnum = 1;
+  }
+
+  return wnum;
+}
+
+/* Draw the weekly view inside calendar panel. */
+static void
+draw_weekly_view(struct window *cwin, struct date *current_day,
+                 unsigned sunday_first)
+{
+#define DAYSLICESNO  6
+  const int WCALWIDTH = 30;
+  const int OFFY = CALHEIGHT / 2 - (conf.compact_panels ? 3 : 1);
+  struct tm t;
+  int OFFX, j, c_wday, days_to_remove, weeknum;
+
+  OFFX = (wins_sbar_width() - WCALWIDTH) / 2 + 1;
+
+  /* Fill in a tm structure with the first day of the selected week. */
+  c_wday = ui_calendar_get_wday(&slctd_day);
+  if (sunday_first)
+    days_to_remove = c_wday;
+  else
+    days_to_remove = c_wday == 0 ? WEEKINDAYS - 1 : c_wday - 1;
+
+  memset(&t, 0, sizeof(struct tm));
+  t.tm_mday = slctd_day.dd;
+  t.tm_mon = slctd_day.mm - 1;
+  t.tm_year = slctd_day.yyyy - 1900;
+  mktime(&t);
+  date_change(&t, 0, -days_to_remove);
+
+  /* Print the week number. */
+  weeknum = ISO8601weeknum(&t);
+  WINS_CALENDAR_LOCK;
+  custom_apply_attr(cwin->p, ATTR_HIGHEST);
+  mvwprintw(cwin->p, conf.compact_panels ? 0 : 2, cwin->w - 9, "(# %02d)",
+            weeknum);
+  custom_remove_attr(cwin->p, ATTR_HIGHEST);
+  WINS_CALENDAR_UNLOCK;
+
+  /* Now draw calendar view. */
+  for (j = 0; j < WEEKINDAYS; j++) {
+    struct date date;
+    unsigned attr, item_this_day;
+    int i, slices[DAYSLICESNO];
+
+    /* print the day names, with regards to the first day of the week */
+    custom_apply_attr(cwin->p, ATTR_HIGHEST);
+    mvwaddstr(cwin->p, OFFY, OFFX + 4 * j, _(daynames[1 + j - sunday_first]));
+    custom_remove_attr(cwin->p, ATTR_HIGHEST);
+
+    /* Check if the day to be printed has an item or not. */
+    date.dd = t.tm_mday;
+    date.mm = t.tm_mon + 1;
+    date.yyyy = t.tm_year + 1900;
+    item_this_day = day_check_if_item(date);
+
+    /* Print the day numbers with appropriate decoration. */
+    if (t.tm_mday == current_day->dd
+        && current_day->mm == slctd_day.mm
+        && current_day->yyyy == slctd_day.yyyy
+        && current_day->dd != slctd_day.dd)
+      attr = ATTR_LOWEST;       /* today, but not selected */
+    else if (t.tm_mday == slctd_day.dd)
+      attr = ATTR_HIGHEST;      /* selected day */
+    else if (item_this_day)
+      attr = ATTR_LOW;
+    else
+      attr = 0;
+
+    WINS_CALENDAR_LOCK;
+    if (attr)
+      custom_apply_attr(cwin->p, attr);
+    mvwprintw(cwin->p, OFFY + 1, OFFX + 1 + 4 * j, "%02d", t.tm_mday);
+    if (attr)
+      custom_remove_attr(cwin->p, attr);
+    WINS_CALENDAR_UNLOCK;
+
+    /* Draw slices indicating appointment times. */
+    memset(slices, 0, DAYSLICESNO * sizeof *slices);
+    if (day_chk_busy_slices(date, DAYSLICESNO, slices)) {
+      for (i = 0; i < DAYSLICESNO; i++) {
+        if (j != WEEKINDAYS - 1 && i != DAYSLICESNO - 1) {
+          WINS_CALENDAR_LOCK;
+          mvwhline(cwin->p, OFFY + 2 + i, OFFX + 3 + 4 * j, ACS_S9, 2);
+          WINS_CALENDAR_UNLOCK;
+        }
+        if (slices[i]) {
+          int highlight;
+
+          highlight = (t.tm_mday == slctd_day.dd) ? 1 : 0;
+          WINS_CALENDAR_LOCK;
+          if (highlight)
+            custom_apply_attr(cwin->p, attr);
+          wattron(cwin->p, A_REVERSE);
+          mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 1 + 4 * j, " ");
+          mvwaddstr(cwin->p, OFFY + 2 + i, OFFX + 2 + 4 * j, " ");
+          wattroff(cwin->p, A_REVERSE);
+          if (highlight)
+            custom_remove_attr(cwin->p, attr);
+          WINS_CALENDAR_UNLOCK;
+        }
+      }
+    }
+
+    /* get next day */
+    date_change(&t, 0, 1);
+  }
+
+  /* Draw marks to indicate midday on the sides of the calendar. */
+  WINS_CALENDAR_LOCK;
+  custom_apply_attr(cwin->p, ATTR_HIGHEST);
+  mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2, OFFX, ACS_S9, 1);
+  mvwhline(cwin->p, OFFY + 1 + DAYSLICESNO / 2,
+           OFFX + WCALWIDTH - 3, ACS_S9, 1);
+  custom_remove_attr(cwin->p, ATTR_HIGHEST);
+  WINS_CALENDAR_UNLOCK;
+
+#undef DAYSLICESNO
+}
+
+/* Function used to display the calendar panel. */
+void ui_calendar_update_panel(struct window *cwin)
+{
+  struct date current_day;
+  unsigned sunday_first;
+
+  ui_calendar_store_current_date(&current_day);
+
+  WINS_CALENDAR_LOCK;
+  erase_window_part(cwin->p, 1, conf.compact_panels ? 1 : 3, cwin->w - 2,
+                    cwin->h - 2);
+  if (!conf.compact_panels)
+    mvwhline(cwin->p, 2, 1, ACS_HLINE, cwin->w - 2);
+  WINS_CALENDAR_UNLOCK;
+
+  sunday_first = ui_calendar_week_begins_on_monday()? 0 : 1;
+
+  draw_calendar[ui_calendar_view] (cwin, &current_day, sunday_first);
+
+  wnoutrefresh(cwin->p);
+}
+
+/* Set the selected day in calendar to current day. */
+void ui_calendar_goto_today(void)
+{
+  struct date today;
+
+  ui_calendar_store_current_date(&today);
+  slctd_day.dd = today.dd;
+  slctd_day.mm = today.mm;
+  slctd_day.yyyy = today.yyyy;
+}
+
+/*
+ * Ask for a date to jump to, then check the correctness of that date
+ * and jump to it.
+ * If the entered date is empty, automatically jump to the current date.
+ * slctd_day is updated with the newly selected date.
+ */
+void ui_calendar_change_day(int datefmt)
+{
+#define LDAY 11
+  char selected_day[LDAY] = "";
+  char outstr[BUFSIZ];
+  int dday, dmonth, dyear;
+  int wrong_day = 1;
+  const char *mesg_line1 =
+      _("The day you entered is not valid "
+        "(should be between 01/01/1902 and 12/31/2037)");
+  const char *mesg_line2 = _("Press [ENTER] to continue");
+  const char *request_date = _("Enter the day to go to [ENTER for today] : %s");
+
+  while (wrong_day) {
+    snprintf(outstr, BUFSIZ, request_date, DATEFMT_DESC(datefmt));
+    status_mesg(outstr, "");
+    if (getstring(win[STA].p, selected_day, LDAY, 0, 1) == GETSTRING_ESC)
+      return;
+    else {
+      if (strlen(selected_day) == 0) {
+        wrong_day = 0;
+        ui_calendar_goto_today();
+      } else if (parse_date(selected_day, datefmt, &dyear, &dmonth, &dday,
+                            ui_calendar_get_slctd_day())) {
+        wrong_day = 0;
+        /* go to chosen day */
+        slctd_day.dd = dday;
+        slctd_day.mm = dmonth;
+        slctd_day.yyyy = dyear;
+      }
+      if (wrong_day) {
+        status_mesg(mesg_line1, mesg_line2);
+        wgetch(win[KEY].p);
+      }
+    }
+  }
+
+  return;
+}
+
+void ui_calendar_move(enum move move, int count)
+{
+  int ret, days_to_remove, days_to_add;
+  struct tm t;
+
+  memset(&t, 0, sizeof(struct tm));
+  t.tm_mday = slctd_day.dd;
+  t.tm_mon = slctd_day.mm - 1;
+  t.tm_year = slctd_day.yyyy - 1900;
+
+  switch (move) {
+  case DAY_PREV:
+    ret = date_change(&t, 0, -count);
+    break;
+  case DAY_NEXT:
+    ret = date_change(&t, 0, count);
+    break;
+  case WEEK_PREV:
+    ret = date_change(&t, 0, -count * WEEKINDAYS);
+    break;
+  case WEEK_NEXT:
+    ret = date_change(&t, 0, count * WEEKINDAYS);
+    break;
+  case MONTH_PREV:
+    ret = date_change(&t, -count, 0);
+    break;
+  case MONTH_NEXT:
+    ret = date_change(&t, count, 0);
+    break;
+  case YEAR_PREV:
+    ret = date_change(&t, -count * YEARINMONTHS, 0);
+    break;
+  case YEAR_NEXT:
+    ret = date_change(&t, count * YEARINMONTHS, 0);
+    break;
+  case WEEK_START:
+    /* Normalize struct tm to get week day number. */
+    mktime(&t);
+    if (ui_calendar_week_begins_on_monday())
+      days_to_remove = ((t.tm_wday == 0) ? WEEKINDAYS - 1 : t.tm_wday - 1);
+    else
+      days_to_remove = ((t.tm_wday == 0) ? 0 : t.tm_wday);
+    days_to_remove += (count - 1) * WEEKINDAYS;
+    ret = date_change(&t, 0, -days_to_remove);
+    break;
+  case WEEK_END:
+    mktime(&t);
+    if (ui_calendar_week_begins_on_monday())
+      days_to_add = ((t.tm_wday == 0) ? 0 : WEEKINDAYS - t.tm_wday);
+    else
+      days_to_add = ((t.tm_wday == 0) ?
+                     WEEKINDAYS - 1 : WEEKINDAYS - 1 - t.tm_wday);
+    days_to_add += (count - 1) * WEEKINDAYS;
+    ret = date_change(&t, 0, days_to_add);
+    break;
+  default:
+    ret = 1;
+    /* NOTREACHED */
+  }
+
+  if (ret == 0) {
+    if (t.tm_year < 2) {
+      t.tm_mday = 1;
+      t.tm_mon = 0;
+      t.tm_year = 2;
+    } else if (t.tm_year > 137) {
+      t.tm_mday = 31;
+      t.tm_mon = 11;
+      t.tm_year = 137;
+    }
+
+    slctd_day.dd = t.tm_mday;
+    slctd_day.mm = t.tm_mon + 1;
+    slctd_day.yyyy = t.tm_year + 1900;
+  }
+}
+
+/* Returns the beginning of current year as a long. */
+long ui_calendar_start_of_year(void)
+{
+  time_t timer;
+  struct tm tm;
+
+  timer = time(NULL);
+  localtime_r(&timer, &tm);
+  tm.tm_mon = 0;
+  tm.tm_mday = 1;
+  tm.tm_hour = 0;
+  tm.tm_min = 0;
+  tm.tm_sec = 0;
+  timer = mktime(&tm);
+
+  return (long)timer;
+}
+
+long ui_calendar_end_of_year(void)
+{
+  time_t timer;
+  struct tm tm;
+
+  timer = time(NULL);
+  localtime_r(&timer, &tm);
+  tm.tm_mon = 0;
+  tm.tm_mday = 1;
+  tm.tm_hour = 0;
+  tm.tm_min = 0;
+  tm.tm_sec = 0;
+  tm.tm_year++;
+  timer = mktime(&tm);
+
+  return (long)(timer - 1);
+}
+
+/*
+ * The pom, potm, dotr, adj360 are used to compute the current
+ * phase of the moon.
+ * The code is based on the OpenBSD version of pom(6).
+ * Below is reported the copyright notice.
+ */
+/*
+ * Copyright (c) 1989, 1993
+ *	The Regents of the University of California.  All rights reserved.
+ *
+ * This code is derived from software posted to USENET.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * dtor --
+ *	convert degrees to radians
+ */
+static double dtor(double deg)
+{
+  return deg * M_PI / 180;
+}
+
+/*
+ * adj360 --
+ *	adjust value so 0 <= deg <= 360
+ */
+static void adj360(double *deg)
+{
+  for (;;)
+    if (*deg < 0.0)
+      *deg += 360.0;
+    else if (*deg > 360.0)
+      *deg -= 360.0;
+    else
+      break;
+}
+
+/*
+ * potm --
+ *	return phase of the moon
+ */
+static double potm(double days)
+{
+  double N, Msol, Ec, LambdaSol, l, Mm, Ev, Ac, A3, Mmprime;
+  double A4, lprime, V, ldprime, D, Nm;
+
+  N = 360.0 * days / 365.242191;        /* sec 46 #3 */
+  adj360(&N);
+  Msol = N + EPSILONg - RHOg;   /* sec 46 #4 */
+  adj360(&Msol);
+  Ec = 360 / M_PI * ECCEN * sin(dtor(Msol));    /* sec 46 #5 */
+  LambdaSol = N + Ec + EPSILONg;        /* sec 46 #6 */
+  adj360(&LambdaSol);
+  l = 13.1763966 * days + lzero;        /* sec 65 #4 */
+  adj360(&l);
+  Mm = l - (0.1114041 * days) - Pzero;  /* sec 65 #5 */
+  adj360(&Mm);
+  Nm = Nzero - (0.0529539 * days);      /* sec 65 #6 */
+  adj360(&Nm);
+  Ev = 1.2739 * sin(dtor(2 * (l - LambdaSol) - Mm));    /* sec 65 #7 */
+  Ac = 0.1858 * sin(dtor(Msol));        /* sec 65 #8 */
+  A3 = 0.37 * sin(dtor(Msol));
+  Mmprime = Mm + Ev - Ac - A3;  /* sec 65 #9 */
+  Ec = 6.2886 * sin(dtor(Mmprime));     /* sec 65 #10 */
+  A4 = 0.214 * sin(dtor(2 * Mmprime));  /* sec 65 #11 */
+  lprime = l + Ev + Ec - Ac + A4;       /* sec 65 #12 */
+  V = 0.6583 * sin(dtor(2 * (lprime - LambdaSol)));     /* sec 65 #13 */
+  ldprime = lprime + V;         /* sec 65 #14 */
+  D = ldprime - LambdaSol;      /* sec 67 #2 */
+  return 50.0 * (1 - cos(dtor(D)));     /* sec 67 #3 */
+}
+
+/*
+ * Phase of the Moon.  Calculates the current phase of the moon.
+ * Based on routines from `Practical Astronomy with Your Calculator',
+ * by Duffett-Smith.  Comments give the section from the book that
+ * particular piece of code was adapted from.
+ *
+ * -- Keith E. Brandt  VIII 1984
+ *
+ * Updated to the Third Edition of Duffett-Smith's book, IX 1998
+ *
+ */
+static double pom(time_t tmpt)
+{
+  struct tm *GMT;
+  double days;
+  int cnt;
+
+  GMT = gmtime(&tmpt);
+  days = (GMT->tm_yday + 1) + ((GMT->tm_hour + (GMT->tm_min / 60.0) +
+                                (GMT->tm_sec / 3600.0)) / 24.0);
+  for (cnt = EPOCH; cnt < GMT->tm_year; ++cnt)
+    days += ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365;
+  /* Selected time could be before EPOCH */
+  for (cnt = GMT->tm_year; cnt < EPOCH; ++cnt)
+    days -= ISLEAP(cnt + TM_YEAR_BASE) ? 366 : 365;
+
+  return potm(days);
+}
+
+/*
+ * Return a pictogram representing the current phase of the moon.
+ * Careful: date is the selected day in calendar at 00:00, so it represents
+ * the phase of the moon for previous day.
+ */
+const char *ui_calendar_get_pom(time_t date)
+{
+  const char *pom_pict[MOON_PHASES] = { "   ", "|) ", "(|)", "(| ", " | " };
+  enum pom phase = NO_POM;
+  double pom_today, relative_pom, pom_yesterday, pom_tomorrow;
+  const double half = 50.0;
+
+  pom_yesterday = pom(date);
+  pom_today = pom(date + DAYINSEC);
+  relative_pom = abs(pom_today - half);
+  pom_tomorrow = pom(date + 2 * DAYINSEC);
+  if (pom_today > pom_yesterday && pom_today > pom_tomorrow)
+    phase = FULL_MOON;
+  else if (pom_today < pom_yesterday && pom_today < pom_tomorrow)
+    phase = NEW_MOON;
+  else if (relative_pom < abs(pom_yesterday - half)
+           && relative_pom < abs(pom_tomorrow - half))
+    phase = (pom_tomorrow > pom_today) ? FIRST_QUARTER : LAST_QUARTER;
+
+  return pom_pict[phase];
+}
diff --git a/src/ui-day.c b/src/ui-day.c
index c300699..75adb3b 100644
--- a/src/ui-day.c
+++ b/src/ui-day.c
@@ -242,7 +242,7 @@ static void update_rept(struct rpt **rpt, const long start)
       int newmonth, newday, newyear;
 
       if (parse_date(timstr, conf.input_datefmt, &newyear, &newmonth,
-                     &newday, calendar_get_slctd_day())) {
+                     &newday, ui_calendar_get_slctd_day())) {
         t = start;
         localtime_r(&t, &lt);
         new_date.dd = newday;
@@ -360,7 +360,7 @@ void ui_day_item_edit(void)
     break;
   }
 
-  calendar_monthly_view_cache_set_invalid();
+  ui_calendar_monthly_view_cache_set_invalid();
 
   if (need_check_notify)
     notify_check_next_app(1);
@@ -490,18 +490,18 @@ void ui_day_item_add(void)
   status_mesg(mesg_3, "");
   if (getstring(win[STA].p, item_mesg, BUFSIZ, 0, 1) == GETSTRING_VALID) {
     if (is_appointment) {
-      apoint_start = date2sec(*calendar_get_slctd_day(), heures, minutes);
+      apoint_start = date2sec(*ui_calendar_get_slctd_day(), heures, minutes);
       apoint_new(item_mesg, 0L, apoint_start, min2sec(apoint_duration), 0L);
       if (notify_bar())
         notify_check_added(item_mesg, apoint_start, 0L);
     } else
-      event_new(item_mesg, 0L, date2sec(*calendar_get_slctd_day(), 0, 0), Id);
+      event_new(item_mesg, 0L, date2sec(*ui_calendar_get_slctd_day(), 0, 0), Id);
 
     if (ui_day_hilt() == 0)
       ui_day_hilt_increase(1);
   }
 
-  calendar_monthly_view_cache_set_invalid();
+  ui_calendar_monthly_view_cache_set_invalid();
 
   wins_erase_status_bar();
 }
@@ -524,7 +524,7 @@ void ui_day_item_delete(unsigned *nb_events, unsigned *nb_apoints,
   const char *note_choices = _("[in]");
   const int nb_note_choices = 2;
 
-  long date = calendar_get_slctd_day_sec();
+  long date = ui_calendar_get_slctd_day_sec();
   int nb_items = *nb_apoints + *nb_events;
   int to_be_removed = 0;
 
@@ -585,7 +585,7 @@ void ui_day_item_delete(unsigned *nb_events, unsigned *nb_apoints,
     /* NOTREACHED */
   }
 
-  calendar_monthly_view_cache_set_invalid();
+  ui_calendar_monthly_view_cache_set_invalid();
 
   if (ui_day_hilt() > 1)
     ui_day_hilt_decrease(1);
@@ -687,7 +687,7 @@ void ui_day_item_repeat(void)
         date_entered = 1;
       } else {
         if (parse_date(user_input, conf.input_datefmt,
-                       &year, &month, &day, calendar_get_slctd_day())) {
+                       &year, &month, &day, ui_calendar_get_slctd_day())) {
           t = p->start;
           localtime_r(&t, &lt);
           until_date.dd = day;
@@ -713,7 +713,7 @@ void ui_day_item_repeat(void)
       return;
   }
 
-  date = calendar_get_slctd_day_sec();
+  date = ui_calendar_get_slctd_day_sec();
   if (p->type == EVNT) {
     struct event *ev = p->item.ev;
     recur_event_new(ev->mesg, ev->note, ev->day, ev->id, type, freq, until,
@@ -734,7 +734,7 @@ void ui_day_item_repeat(void)
   day_cut[REG_BLACK_HOLE].type = p->type;
   day_cut[REG_BLACK_HOLE].item = p->item;
 
-  calendar_monthly_view_cache_set_invalid();
+  ui_calendar_monthly_view_cache_set_invalid();
 }
 
 /* Free the current cut item, if any. */
@@ -783,9 +783,9 @@ void ui_day_item_paste(unsigned *nb_events, unsigned *nb_apoints,
     return;
 
   day_item_fork(&day_cut[reg], &day);
-  item_type = day_paste_item(&day, calendar_get_slctd_day_sec());
+  item_type = day_paste_item(&day, ui_calendar_get_slctd_day_sec());
 
-  calendar_monthly_view_cache_set_invalid();
+  ui_calendar_monthly_view_cache_set_invalid();
 
   if (item_type == EVNT || item_type == RECUR_EVNT)
     (*nb_events)++;
@@ -884,7 +884,7 @@ void ui_day_update_panel(int which_pan)
   struct date slctd_date;
 
   /* variable inits */
-  slctd_date = *calendar_get_slctd_day();
+  slctd_date = *ui_calendar_get_slctd_day();
   title_xpos = win[APP].w - (strlen(_(monthnames[slctd_date.mm - 1])) + 16);
   if (slctd_date.dd < 10)
     title_xpos++;
@@ -895,7 +895,7 @@ void ui_day_update_panel(int which_pan)
   erase_window_part(win[APP].p, 1, title_lines, win[APP].w - 2, win[APP].h - 2);
   custom_apply_attr(win[APP].p, ATTR_HIGHEST);
   mvwprintw(win[APP].p, title_lines, title_xpos, "%s  %s %d, %d",
-            calendar_get_pom(date), _(monthnames[slctd_date.mm - 1]),
+            ui_calendar_get_pom(date), _(monthnames[slctd_date.mm - 1]),
             slctd_date.dd, slctd_date.yyyy);
   custom_remove_attr(win[APP].p, ATTR_HIGHEST);
 
diff --git a/src/utils.c b/src/utils.c
index 1192ed8..7baa961 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -80,7 +80,7 @@ void exit_calcurse(int status)
   } else
     was_interactive = 0;
 
-  calendar_stop_date_thread();
+  ui_calendar_stop_date_thread();
   io_stop_psave_thread();
   free_user_data();
   keys_free();
diff --git a/src/vars.c b/src/vars.c
index a54b702..0235089 100644
--- a/src/vars.c
+++ b/src/vars.c
@@ -161,7 +161,7 @@ void vars_init(void)
 
   wins_set_layout(1);
 
-  calendar_set_first_day_of_week(MONDAY);
+  ui_calendar_set_first_day_of_week(MONDAY);
 
   /* Pad structure to scroll text inside the appointment panel */
   apad.length = 1;
@@ -171,5 +171,5 @@ void vars_init(void)
   custom_init_attr();
 
   /* Start at the current date */
-  calendar_init_slctd_day();
+  ui_calendar_init_slctd_day();
 }
diff --git a/src/wins.c b/src/wins.c
index 6274a19..d8f1f45 100644
--- a/src/wins.c
+++ b/src/wins.c
@@ -499,7 +499,7 @@ void wins_update_panels(int flags)
   if (flags & FLAG_TOD)
     ui_todo_update_panel(slctd_win);
   if (flags & FLAG_CAL)
-    calendar_update_panel(&win[CAL]);
+    ui_calendar_update_panel(&win[CAL]);
 }
 
 /*
-- 
cgit v1.2.3-70-g09d2