summaryrefslogtreecommitdiffstats
path: root/src/calendar.c
diff options
context:
space:
mode:
authorLukas Fleischer <calcurse@cryptocrack.de>2013-02-14 10:52:44 +0100
committerLukas Fleischer <calcurse@cryptocrack.de>2013-02-14 11:08:03 +0100
commit806673dd9b256e879d1483255886a8881d1d8115 (patch)
tree53dfc46a1575233ad95dfdc2767a695504d26eac /src/calendar.c
parent971df8d215a0e10c87f67f3505345e15efcffb8e (diff)
downloadcalcurse-806673dd9b256e879d1483255886a8881d1d8115.tar.gz
calcurse-806673dd9b256e879d1483255886a8881d1d8115.zip
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>
Diffstat (limited to 'src/calendar.c')
-rw-r--r--src/calendar.c915
1 files changed, 0 insertions, 915 deletions
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];
-}