+ time_t previous_month;
+ time_t next_month;
+ time_t colheader_time;
+ struct tm colheader_tm;
+ char colheader_label[32];
+ long weekstart = 0;
+ char url[256];
+ char div_id[256];
+
+ snprintf(div_id, sizeof div_id, "mini_calendar_%d", rand() );
+
+ // Determine what day to start. If an impossible value is found, start on Sunday.
+ get_pref_long("weekstart", &weekstart, 17);
+ if (weekstart > 6) weekstart = 0;
+
+ // Now back up to the 1st of the month...
+ memset(&starting_tm, 0, sizeof(struct tm));
+
+ starting_tm.tm_year = year - 1900;
+ starting_tm.tm_mon = month - 1;
+ starting_tm.tm_mday = 1;
+ thetime = mktime(&starting_tm);
+
+ memcpy(&tm, &starting_tm, sizeof(struct tm));
+ while (tm.tm_mday != 1) {
+ thetime = thetime - (time_t)86400; // go back 24 hours
+ localtime_r(&thetime, &tm);
+ }
+
+ // Determine previous and next months ... for links
+ previous_month = thetime - (time_t)864000; // back 10 days
+ next_month = thetime + (time_t)(31L * 86400); // ahead 31 days
+
+ // Now back up until we're on the user's preferred start day
+ localtime_r(&thetime, &tm);
+ while (tm.tm_wday != weekstart) {
+ thetime = thetime - (time_t)86400; // go back 24 hours
+ localtime_r(&thetime, &tm);
+ }
+
+ wc_printf("<div class=\"mini_calendar\" id=\"%s\">\n", div_id);
+
+ // Previous month link
+ localtime_r(&previous_month, &tm);
+ wc_printf("<a href=\"javascript:minical_change_month(%d,%d);\">«</a>", (int)(tm.tm_year)+1900, tm.tm_mon + 1);
+
+ wc_strftime(colheader_label, sizeof colheader_label, "%B", &starting_tm);
+ wc_printf(" "
+ "<span class=\"mini_calendar_month_label\">"
+ "%s %d"
+ "</span>"
+ " ", colheader_label, year);
+
+ // Next month link
+ localtime_r(&next_month, &tm);
+ wc_printf("<a href=\"javascript:minical_change_month(%d,%d);\">»</a>", (int)(tm.tm_year)+1900, tm.tm_mon + 1);
+
+ wc_printf("<table border=\"0\" cellpadding=\"1\" cellspacing=\"1\" class=\"mini_calendar_days\"><tr>");
+ colheader_time = thetime;
+ for (i=0; i<7; ++i) {
+ colheader_time = thetime + (i * 86400) ;
+ localtime_r(&colheader_time, &colheader_tm);
+ wc_strftime(colheader_label, sizeof colheader_label, "%A", &colheader_tm);
+ wc_printf("<th>%c</th>", colheader_label[0]);
+
+ }
+ wc_printf("</tr>\n");
+
+ // Now do 35 or 42 days
+ for (i = 0; i < 42; ++i) {
+ localtime_r(&thetime, &tm);
+
+ if (i < 35) {
+
+ // Before displaying Sunday, start a new row
+ if ((i % 7) == 0) {
+ wc_printf("<tr>");
+ }
+
+ if (tm.tm_mon == month-1) {
+ snprintf(url, sizeof url, "readfwd?calview=day?year=%d?month=%d?day=%d",
+ tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday);
+ wc_printf("<td><a href=\"%s\">%d</a></td>", url, tm.tm_mday);
+ }
+ else {
+ wc_printf("<td> </td>");
+ }
+
+ // After displaying one week, end the row
+ if ((i % 7) == 6) {
+ wc_printf("</tr>\n");
+ }
+
+ }
+
+ thetime += (time_t)86400; // ahead 24 hours
+ }
+
+ wc_printf("</table>" // end of inner table
+ "</div>\n");
+
+ StrBufAppendPrintf(WC->trailing_javascript,
+ " function minical_change_month(year, month) { \n"
+ " p = 'year=' + year + '&month=' + month \n"
+ " + '&r=' + ctdlRandomString(); \n"
+ " new Ajax.Updater('%s', 'mini_calendar', \n"
+ " { method: 'get', parameters: p, evalScripts: true } ); \n"
+ " } \n"
+ "",
+ div_id
+ );
+
+}
+
+
+// ajax embedder for the above mini calendar
+void ajax_mini_calendar(void) {
+ embeddable_mini_calendar( ibstr("year"), ibstr("month"));
+}
+
+
+// Display one day of a whole month view of a calendar
+void calendar_month_view_display_events(int year, int month, int day) {
+ long hklen;
+ const char *HashKey;
+ void *vCal;
+ HashPos *Pos;
+ disp_cal *Cal;