added brief view calendar, and renamed the original view to 'pretty view' in the...
[citadel.git] / webcit / calendar_view.c
1 /*
2  * $Id$
3  */
4 /**
5  * \defgroup CalHtmlHandles Handles the HTML display of calendar items.
6  * \ingroup Calendaring
7  */
8 /*@{*/
9 #include "webcit.h"
10 #include "webserver.h"
11
12 #ifndef WEBCIT_WITH_CALENDAR_SERVICE
13
14 /**\brief stub for non-libical builds */
15 void do_calendar_view(void) {
16         wprintf("<CENTER><I>");
17         wprintf(_("The calendar view is not available."));
18         wprintf("</I></CENTER><br />\n");
19 }
20
21 /**\brief stub for non-libical builds */
22 void do_tasks_view(void) {      
23         wprintf("<CENTER><I>");
24         wprintf(_("The tasks view is not available."));
25         wprintf("</I></CENTER><br />\n");
26 }
27
28 #else   /* WEBCIT_WITH_CALENDAR_SERVICE */
29
30 /****************************************************************************/
31
32 /**
33  * \brief Display one day of a whole month view of a calendar
34  * \param thetime the month we want to see 
35  */
36 void calendar_month_view_display_events(time_t thetime) {
37         int i;
38         time_t event_tt;
39         struct tm event_tm;
40         struct tm today_tm;
41         icalproperty *p;
42         struct icaltimetype t;
43         int month, day, year;
44         int all_day_event = 0;
45
46         if (WC->num_cal == 0) {
47                 wprintf("<br /><br /><br />\n");
48                 return;
49         }
50
51         localtime_r(&thetime, &today_tm);
52         month = today_tm.tm_mon + 1;
53         day = today_tm.tm_mday;
54         year = today_tm.tm_year + 1900;
55
56         for (i=0; i<(WC->num_cal); ++i) {
57                 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
58                                                 ICAL_DTSTART_PROPERTY);
59                 if (p != NULL) {
60                         t = icalproperty_get_dtstart(p);
61                         event_tt = icaltime_as_timet(t);
62
63                         if (t.is_date) all_day_event = 1;
64                         else all_day_event = 0;
65
66                         if (all_day_event) {
67                                 gmtime_r(&event_tt, &event_tm);
68                         }
69                         else {
70                                 localtime_r(&event_tt, &event_tm);
71                         }
72
73                         if ((event_tm.tm_year == today_tm.tm_year)
74                            && (event_tm.tm_mon == today_tm.tm_mon)
75                            && (event_tm.tm_mday == today_tm.tm_mday)) {
76
77                                 p = icalcomponent_get_first_property(
78                                                         WC->disp_cal[i].cal,
79                                                         ICAL_SUMMARY_PROPERTY);
80                                 if (p != NULL) {
81
82                                         if (all_day_event) {
83                                                 wprintf("<TABLE border=0 cellpadding=2><TR>"
84                                                         "<TD BGCOLOR=\"#CCCCDD\">"
85                                                 );
86                                         }
87
88                                         wprintf("<FONT SIZE=-1>"
89                                                 "<a href=\"display_edit_event?msgnum=%ld&calview=%s&year=%s&month=%s&day=%s\">",
90                                                 WC->disp_cal[i].cal_msgnum,
91                                                 bstr("calview"),
92                                                 bstr("year"),
93                                                 bstr("month"),
94                                                 bstr("day")
95                                         );
96                                         escputs((char *)
97                                                 icalproperty_get_comment(p));
98                                         wprintf("</A></FONT><br />\n");
99
100                                         if (all_day_event) {
101                                                 wprintf("</TD></TR></TABLE>");
102                                         }
103
104                                 }
105
106                         }
107
108
109                 }
110         }
111 }
112
113
114 /**
115  * \brief Display one day of a whole month view of a calendar
116  * \param thetime the month we want to see 
117  */
118 void calendar_month_view_brief_events(time_t thetime, const char *daycolor) {
119         int i;
120         time_t event_tt;
121         time_t event_tts;
122         time_t event_tte;
123         struct tm event_tms;
124         struct tm event_tme;
125         struct tm today_tm;
126         icalproperty *p;
127         icalproperty *e;
128         struct icaltimetype t;
129         int month, day, year;
130         int all_day_event = 0;
131         char calhourformat[16];
132         char *timeformat;
133
134         get_preference("calhourformat", calhourformat, sizeof calhourformat);
135         if (!strcasecmp(calhourformat, "24"))   timeformat="%k:%M";
136         else timeformat="%I:%M %p";
137
138         localtime_r(&thetime, &today_tm);
139         month = today_tm.tm_mon + 1;
140         day = today_tm.tm_mday;
141         year = today_tm.tm_year + 1900;
142
143         for (i=0; i<(WC->num_cal); ++i) {
144                 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
145                                                 ICAL_DTSTART_PROPERTY);
146                 if (p != NULL) {
147                         t = icalproperty_get_dtstart(p);
148                         event_tt = icaltime_as_timet(t);
149                         event_tts=event_tt;
150                         if (t.is_date) all_day_event = 1;
151                         else all_day_event = 0;
152
153                         if (all_day_event) {
154                                 gmtime_r(&event_tts, &event_tms);
155                         }
156                         else {
157                                 localtime_r(&event_tts, &event_tms);
158                         }
159                         /** \todo epoch &! daymask */
160                         if ((event_tms.tm_year == today_tm.tm_year)
161                            && (event_tms.tm_mon == today_tm.tm_mon)
162                            && (event_tms.tm_mday == today_tm.tm_mday)) {
163                                 
164                                 
165                                 char sbuf[255];
166                                 char ebuf[255];
167
168                                 p = icalcomponent_get_first_property(
169                                                         WC->disp_cal[i].cal,
170                                                         ICAL_SUMMARY_PROPERTY);
171                                 e = icalcomponent_get_first_property(
172                                                         WC->disp_cal[i].cal, 
173                                                         ICAL_DTEND_PROPERTY);
174                                 if ((p != NULL) && (e != NULL)) {
175                                         time_t difftime;
176                                         int hours, minutes;
177                                         t = icalproperty_get_dtend(e);
178                                         event_tte = icaltime_as_timet(t);
179                                         localtime_r(&event_tte, &event_tme);
180                                         difftime=(event_tte-event_tts)/60;
181                                         hours=(int)(difftime / 60);
182                                         minutes=difftime % 60;
183                                         wprintf("<tr><td bgcolor='%s'>%i:%i</td><td bgcolor='%s'>"
184                                                         "<font size=-1>"
185                                                         "<a href=\"display_edit_event?msgnum=%ld&calview=%s&year=%s&month=%s&day=%s\">",
186                                                         daycolor,
187                                                         hours, minutes,
188                                                         daycolor,
189                                                         WC->disp_cal[i].cal_msgnum,
190                                                         bstr("calview"),
191                                                         bstr("year"),
192                                                         bstr("month"),
193                                                         bstr("day")
194                                                         );
195
196                                         escputs((char *)
197                                                         icalproperty_get_comment(p));
198                                         /** \todo: allso ammitime format */
199                                         strftime(&sbuf[0],sizeof(sbuf),timeformat,&event_tms);
200                                         strftime(&ebuf[0],sizeof(sbuf),timeformat,&event_tme);
201
202                                         wprintf("</a></font></td>"
203                                                         "<td bgcolor='%s'>%s</td><td bgcolor='%s'>%s</td></tr>",
204                                                         daycolor,
205                                                         sbuf,
206                                                         daycolor,
207                                                         ebuf);
208                                         
209                                 }
210                                 
211                         }
212                         
213                         
214                 }
215         }
216 }
217
218
219 /**
220  * \brief view one month. pretty view
221  * \param year the year
222  * \param month the month
223  * \param day the actual day we want to see
224  */
225 void calendar_month_view(int year, int month, int day) {
226         struct tm starting_tm;
227         struct tm tm;
228         time_t thetime;
229         int i;
230         time_t previous_month;
231         time_t next_month;
232
233         /** Determine what day to start.
234          * First, back up to the 1st of the month...
235          */
236         memset(&starting_tm, 0, sizeof(struct tm));
237         starting_tm.tm_year = year - 1900;
238         starting_tm.tm_mon = month - 1;
239         starting_tm.tm_mday = day;
240         thetime = mktime(&starting_tm);
241
242         memcpy(&tm, &starting_tm, sizeof(struct tm));
243         while (tm.tm_mday != 1) {
244                 thetime = thetime - (time_t)86400;      /* go back 24 hours */
245                 localtime_r(&thetime, &tm);
246         }
247
248         /** Determine previous and next months ... for links */
249         previous_month = thetime - (time_t)864000L;     /* back 10 days */
250         next_month = thetime + (time_t)(31L * 86400L);  /* ahead 31 days */
251
252         /** Now back up until we're on a Sunday */
253         localtime_r(&thetime, &tm);
254         while (tm.tm_wday != 0) {
255                 thetime = thetime - (time_t)86400;      /* go back 24 hours */
256                 localtime_r(&thetime, &tm);
257         }
258
259         /** Outer table (to get the background color) */
260         wprintf("<div class=\"fix_scrollbar_bug\">"
261                 "<TABLE width=100%% border=0 cellpadding=0 cellspacing=0 "
262                 "bgcolor=#204B78><TR><TD>\n");
263
264         wprintf("<TABLE width=100%% border=0 cellpadding=0 cellspacing=0><tr>\n");
265
266         wprintf("<TD ALIGN=CENTER>");
267
268         localtime_r(&previous_month, &tm);
269         wprintf("<a href=\"readfwd?calview=month&year=%d&month=%d&day=1\">",
270                 (int)(tm.tm_year)+1900, tm.tm_mon + 1);
271         wprintf("<IMG ALIGN=MIDDLE src=\"static/prevdate_32x.gif\" BORDER=0></A>\n");
272
273         wprintf("&nbsp;&nbsp;"
274                 "<FONT SIZE=+1 COLOR=\"#FFFFFF\">"
275                 "%s %d"
276                 "</FONT>"
277                 "&nbsp;&nbsp;", months[month-1], year);
278
279         localtime_r(&next_month, &tm);
280         wprintf("<a href=\"readfwd?calview=month&year=%d&month=%d&day=1\">",
281                 (int)(tm.tm_year)+1900, tm.tm_mon + 1);
282         wprintf("<IMG ALIGN=MIDDLE src=\"static/nextdate_32x.gif\" BORDER=0></A>\n");
283
284         wprintf("</TD></TR></TABLE>\n");
285
286         /** Inner table (the real one) */
287         wprintf("<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
288                 "bgcolor=#204B78><TR>");
289         for (i=0; i<7; ++i) {
290                 wprintf("<TD ALIGN=CENTER WIDTH=14%%>"
291                         "<FONT COLOR=\"#FFFFFF\">%s</FONT></TH>", wdays[i]);
292         }
293         wprintf("</TR>\n");
294
295         /** Now do 35 days */
296         for (i = 0; i < 35; ++i) {
297                 localtime_r(&thetime, &tm);
298
299                 /** Before displaying Sunday, start a new row */
300                 if ((i % 7) == 0) {
301                         wprintf("<TR>");
302                 }
303
304                 wprintf("<TD BGCOLOR=\"#%s\" WIDTH=14%% HEIGHT=60 align=left VALIGN=TOP><B>",
305                         ((tm.tm_mon != month-1) ? "DDDDDD" :
306                         ((tm.tm_wday==0 || tm.tm_wday==6) ? "EEEECC" :
307                         "FFFFFF"))
308                 );
309                 if ((i==0) || (tm.tm_mday == 1)) {
310                         wprintf("%s ", months[tm.tm_mon]);
311                 }
312                 wprintf("<a href=\"readfwd?calview=day&year=%d&month=%d&day=%d\">"
313                         "%d</A></B><br />",
314                         tm.tm_year + 1900,
315                         tm.tm_mon + 1,
316                         tm.tm_mday,
317                         tm.tm_mday);
318
319                 /** put the data here, stupid */
320                 calendar_month_view_display_events(thetime);
321
322                 wprintf("</TD>");
323
324                 /** After displaying Saturday, end the row */
325                 if ((i % 7) == 6) {
326                         wprintf("</TR>\n");
327                 }
328
329                 thetime += (time_t)86400;               /** ahead 24 hours */
330         }
331
332         wprintf("</TABLE>"                      /** end of inner table */
333                 "</TD></TR></TABLE>"            /** end of outer table */
334                 "</div>\n");
335 }
336
337 /**
338  * \brief view one month. brief view
339  * \param year the year
340  * \param month the month
341  * \param day the actual day we want to see
342  */
343 void calendar_brief_month_view(int year, int month, int day) {
344         struct tm starting_tm;
345         struct tm tm;
346         time_t thetime;
347         int i;
348         time_t previous_month;
349         time_t next_month;
350
351         /** Determine what day to start.
352          * First, back up to the 1st of the month...
353          */
354         memset(&starting_tm, 0, sizeof(struct tm));
355         starting_tm.tm_year = year - 1900;
356         starting_tm.tm_mon = month - 1;
357         starting_tm.tm_mday = day;
358         thetime = mktime(&starting_tm);
359
360         memcpy(&tm, &starting_tm, sizeof(struct tm));
361         while (tm.tm_mday != 1) {
362                 thetime = thetime - (time_t)86400;      /* go back 24 hours */
363                 localtime_r(&thetime, &tm);
364         }
365
366         /** Determine previous and next months ... for links */
367         previous_month = thetime - (time_t)864000L;     /* back 10 days */
368         next_month = thetime + (time_t)(31L * 86400L);  /* ahead 31 days */
369
370         /** Now back up until we're on a Sunday */
371         localtime_r(&thetime, &tm);
372         while (tm.tm_wday != 0) {
373                 thetime = thetime - (time_t)86400;      /* go back 24 hours */
374                 localtime_r(&thetime, &tm);
375         }
376
377         /** Outer table (to get the background color) */
378         wprintf("<div class=\"fix_scrollbar_bug\">"
379                 "<TABLE width=100%% border=0 cellpadding=0 cellspacing=0 "
380                 "bgcolor=#204B78><TR><TD>\n");
381
382         wprintf("<TABLE width=100%% border=0 cellpadding=0 cellspacing=0><tr>\n");
383
384         wprintf("<TD ALIGN=CENTER>");
385
386         localtime_r(&previous_month, &tm);
387         wprintf("<a href=\"readfwd?calview=month&year=%d&month=%d&day=1\">",
388                 (int)(tm.tm_year)+1900, tm.tm_mon + 1);
389         wprintf("<IMG ALIGN=MIDDLE src=\"static/prevdate_32x.gif\" BORDER=0></A>\n");
390
391         wprintf("&nbsp;&nbsp;"
392                 "<FONT SIZE=+1 COLOR=\"#FFFFFF\">"
393                 "%s %d"
394                 "</FONT>"
395                 "&nbsp;&nbsp;", months[month-1], year);
396
397         localtime_r(&next_month, &tm);
398         wprintf("<a href=\"readfwd?calview=month&year=%d&month=%d&day=1\">",
399                 (int)(tm.tm_year)+1900, tm.tm_mon + 1);
400         wprintf("<IMG ALIGN=MIDDLE src=\"static/nextdate_32x.gif\" BORDER=0></A>\n");
401
402         wprintf("</TD></TR></TABLE>\n");
403
404         /** Inner table (the real one) */
405         wprintf("<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
406                 "bgcolor=#EEEECC><TR>");
407         wprintf("</TR>\n");
408         wprintf("<TR><TD COLSPAN=\"100%\">\n");
409
410         /** Now do 35 days */
411         for (i = 0; i < 35; ++i) {
412                 char weeknumber[255];
413                 char *daycolor;
414                 localtime_r(&thetime, &tm);
415
416
417                 /** Before displaying Sunday, start a new CELL */
418                 if ((i % 7) == 0) {
419                         strftime(&weeknumber[0],sizeof(weeknumber),"%U",&tm);
420                         wprintf("<TABLE border='0' BGCOLOR=\"#EEEECC\" width='100%'> <tr><th colspan='4'>%s %s</th></tr>"
421                                         "   <tr><td>%s</td><td width='70%'>%s</td><td>%s</td><td>%s</td></tr>\n",
422                                         _("Week"), 
423                                         weeknumber,
424                                         _("Hours"),
425                                         _("Subject"),
426                                         _("Start"),
427                                         _("End")
428                                         );
429                 }
430                 
431                 daycolor=((tm.tm_mon != month-1) ? "DDDDDD" :
432                                   ((tm.tm_wday==0 || tm.tm_wday==6) ? "EEEECC" :
433                                    "FFFFFF"));
434                 
435                 /** Day Header */
436                 wprintf("<tr><td BGCOLOR='%s' colspan='1' align='left'> %s</td><td BGCOLOR='%s' colspan='3'><hr></td></tr>\n",
437                                 daycolor,
438                                 wdays[i%7],
439                                 daycolor);
440
441                 /** put the data of one day  here, stupid */
442                 calendar_month_view_brief_events(thetime, daycolor);
443
444
445                 /** After displaying Saturday, end the row */
446                 if ((i % 7) == 6) {
447                         wprintf("</td></tr></table>\n");
448                 }
449
450                 thetime += (time_t)86400;               /** ahead 24 hours */
451         }
452
453         wprintf("</TABLE>"                      /** end of inner table */
454                 "</TD></TR></TABLE>"            /** end of outer table */
455                 "</div>\n");
456 }
457
458 /** 
459  * \brief view one week
460  * this should view just one week, but it's not here yet.
461  * \todo ny implemented
462  * \param year the year
463  * \param month the month
464  * \param day the day which we want to see the week around
465  */
466 void calendar_week_view(int year, int month, int day) {
467         wprintf("<CENTER><I>week view FIXME</I></CENTER><br />\n");
468 }
469
470
471 /**
472  * \brief display one day
473  * Display events for a particular hour of a particular day.
474  * (Specify hour < 0 to show "all day" events)
475  * \param year the year
476  * \param month the month
477  * \param day the day
478  * \param hour the hour we want to start displaying?????
479  */
480 void calendar_day_view_display_events(int year, int month,
481                                         int day, int hour) {
482         int i;
483         icalproperty *p;
484         struct icaltimetype t;
485         time_t event_tt;
486         struct tm *event_tm;
487         int all_day_event = 0;
488
489         if (WC->num_cal == 0) {
490                 // \todo FIXME wprintf("<br /><br /><br />\n");
491                 return;
492         }
493
494         for (i=0; i<(WC->num_cal); ++i) {
495                 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
496                                                 ICAL_DTSTART_PROPERTY);
497                 if (p != NULL) {
498                         t = icalproperty_get_dtstart(p);
499                         event_tt = icaltime_as_timet(t);
500                         if (t.is_date) {
501                                 all_day_event = 1;
502                         }
503                         else {
504                                 all_day_event = 0;
505                         }
506
507                         if (all_day_event) {
508                                 event_tm = gmtime(&event_tt);
509                         }
510                         else {
511                                 event_tm = localtime(&event_tt);
512                         }
513
514                         if ((event_tm->tm_year == (year-1900))
515                            && (event_tm->tm_mon == (month-1))
516                            && (event_tm->tm_mday == day)
517                            && ( ((event_tm->tm_hour == hour)&&(!t.is_date)) || ((hour<0)&&(t.is_date)) )
518                            ) {
519
520
521                                 p = icalcomponent_get_first_property(
522                                                         WC->disp_cal[i].cal,
523                                                         ICAL_SUMMARY_PROPERTY);
524                                 if (p != NULL) {
525
526                                         if (all_day_event) {
527                                                 wprintf("<TABLE border=1 cellpadding=2><TR>"
528                                                         "<TD BGCOLOR=\"#CCCCCC\">"
529                                                 );
530                                         }
531
532                                         wprintf("<FONT SIZE=-1>"
533                                                 "<a href=\"display_edit_event?msgnum=%ld&calview=day&year=%d&month=%d&day=%d\">",
534                                                 WC->disp_cal[i].cal_msgnum,
535                                                 year, month, day
536                                         );
537                                         escputs((char *)
538                                                 icalproperty_get_comment(p));
539                                         wprintf("</A></FONT><br />\n");
540
541                                         if (all_day_event) {
542                                                 wprintf("</TD></TR></TABLE>");
543                                         }
544                                 }
545
546                         }
547
548
549                 }
550         }
551 }
552
553
554 /**
555  * \brief view one day
556  * \param year the year
557  * \param month the month 
558  * \param day the day we want to display
559  */
560 void calendar_day_view(int year, int month, int day) {
561         int hour;
562         struct icaltimetype today, yesterday, tomorrow;
563         char calhourformat[16];
564         int daystart = 8;
565         int dayend = 17;
566         char daystart_str[16], dayend_str[16];
567
568         get_preference("calhourformat", calhourformat, sizeof calhourformat);
569         get_preference("daystart", daystart_str, sizeof daystart_str);
570         if (strlen(daystart_str) > 0) daystart = atoi(daystart_str);
571         get_preference("dayend", dayend_str, sizeof dayend_str);
572         if (strlen(dayend_str) > 0) dayend = atoi(dayend_str);
573         
574
575         /** Figure out the dates for "yesterday" and "tomorrow" links */
576
577         memset(&today, 0, sizeof(struct icaltimetype));
578         today.year = year;
579         today.month = month;
580         today.day = day;
581         today.is_date = 1;
582
583         memcpy(&yesterday, &today, sizeof(struct icaltimetype));
584         --yesterday.day;
585         yesterday = icaltime_normalize(yesterday);
586
587         memcpy(&tomorrow, &today, sizeof(struct icaltimetype));
588         ++tomorrow.day;
589         tomorrow = icaltime_normalize(tomorrow);
590
591
592         /** Outer table (to get the background color) */
593         wprintf("<div class=\"fix_scrollbar_bug\">"
594                 "<TABLE width=100%% border=0 cellpadding=0 cellspacing=0 "
595                 "bgcolor=#204B78><TR><TD>\n");
596
597         /** Inner table (the real one) */
598         wprintf("<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
599                 "bgcolor=#204B78><TR>\n");
600
601         /** Innermost table (contains hours etc.) */
602         wprintf("<TD WIDTH=80%%>"
603                 "<TABLE width=100%% border=0 cellpadding=1 cellspacing=1 "
604                 "bgcolor=#204B78>\n");
605
606         /** Display events before 8:00 (hour=-1 is all-day events) */
607         wprintf("<TR>"
608                 "<TD BGCOLOR=\"#CCCCDD\" VALIGN=MIDDLE WIDTH=10%%></TD>"
609                 "<TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
610         for (hour = (-1); hour <= (daystart-1); ++hour) {
611                 calendar_day_view_display_events(year, month, day, hour);
612         }
613         wprintf("</TD></TR>\n");
614
615         /** Now the middle of the day... */     
616         for (hour = daystart; hour <= dayend; ++hour) { /* could do HEIGHT=xx */
617                 wprintf("<TR HEIGHT=30><TD BGCOLOR=\"#CCCCDD\" ALIGN=MIDDLE "
618                         "VALIGN=MIDDLE WIDTH=10%%>");
619                 wprintf("<a href=\"display_edit_event?msgnum=0"
620                         "&year=%d&month=%d&day=%d&hour=%d&minute=0\">",
621                         year, month, day, hour
622                 );
623
624                 if (!strcasecmp(calhourformat, "24")) {
625                         wprintf("%2d:00</A> ", hour);
626                 }
627                 else {
628                         wprintf("%d:00%s</A> ",
629                                 (hour <= 12 ? hour : hour-12),
630                                 (hour < 12 ? "am" : "pm")
631                         );
632                 }
633
634                 wprintf("</TD><TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
635
636                 /* put the data here, stupid */
637                 calendar_day_view_display_events(year, month, day, hour);
638
639                 wprintf("</TD></TR>\n");
640         }
641
642         /** Display events after 5:00... */
643         wprintf("<TR>"
644                 "<TD BGCOLOR=\"#CCCCDD\" VALIGN=MIDDLE WIDTH=10%%></TD>"
645                 "<TD BGCOLOR=\"#FFFFFF\" VALIGN=TOP>");
646         for (hour = (dayend+1); hour <= 23; ++hour) {
647                 calendar_day_view_display_events(year, month, day, hour);
648         }
649         wprintf("</TD></TR>\n");
650
651
652         wprintf("</TABLE>"                      /* end of innermost table */
653                 "</TD>"
654         );
655
656         wprintf("<TD WIDTH=20%% VALIGN=top>");  /* begin stuff-on-the-right */
657
658
659         /** Begin todays-date-with-left-and-right-arrows */
660         wprintf("<TABLE BORDER=0 WIDTH=100%% "
661                 "CELLSPACING=0 CELLPADDING=0 BGCOLOR=\"#FFFFFF\">\n");
662         wprintf("<TR>");
663
664         /** Left arrow */       
665         wprintf("<TD ALIGN=CENTER>");
666         wprintf("<a href=\"readfwd?calview=day&year=%d&month=%d&day=%d\">",
667                 yesterday.year, yesterday.month, yesterday.day);
668         wprintf("<IMG ALIGN=MIDDLE src=\"static/prevdate_32x.gif\" BORDER=0></A>");
669         wprintf("</TD>");
670
671         /** Today's date */
672         wprintf("<TD ALIGN=CENTER>");
673         wprintf("<FONT SIZE=+2>%s</FONT><br />"
674                 "<FONT SIZE=+3>%d</FONT><br />"
675                 "<FONT SIZE=+2>%d</FONT><br />",
676                 months[month-1], day, year);
677         wprintf("</TD>");
678
679         /** Right arrow */
680         wprintf("<TD ALIGN=CENTER>");
681         wprintf("<a href=\"readfwd?calview=day&year=%d&month=%d&day=%d\">",
682                 tomorrow.year, tomorrow.month, tomorrow.day);
683         wprintf("<IMG ALIGN=MIDDLE src=\"static/nextdate_32x.gif\""
684                 " BORDER=0></A>\n");
685         wprintf("</TD>");
686
687         wprintf("</TR></TABLE>\n");
688         /** End todays-date-with-left-and-right-arrows */
689
690         /** \todo In the future we might want to put a month-o-matic here */
691
692         wprintf("</FONT></CENTER>\n");
693
694         wprintf("</TD>");                       /** end stuff-on-the-right */
695
696
697
698         wprintf("</TR></TABLE>"                 /** end of inner table */
699                 "</TD></TR></TABLE></div>"      /** end of outer table */
700         );
701
702
703
704 }
705
706 /**
707  * \brief Display today's events.
708  */
709 void calendar_summary_view(void) {
710         int i;
711         icalproperty *p;
712         struct icaltimetype t;
713         time_t event_tt;
714         struct tm event_tm;
715         struct tm today_tm;
716         time_t now;
717         int all_day_event = 0;
718         char timestring[SIZ];
719
720         if (WC->num_cal == 0) {
721                 return;
722         }
723
724         now = time(NULL);
725         localtime_r(&now, &today_tm);
726
727         for (i=0; i<(WC->num_cal); ++i) {
728                 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
729                                                 ICAL_DTSTART_PROPERTY);
730                 if (p != NULL) {
731                         t = icalproperty_get_dtstart(p);
732                         event_tt = icaltime_as_timet(t);
733                         if (t.is_date) {
734                                 all_day_event = 1;
735                         }
736                         else {
737                                 all_day_event = 0;
738                         }
739                         fmt_time(timestring, event_tt);
740
741                         if (all_day_event) {
742                                 gmtime_r(&event_tt, &event_tm);
743                         }
744                         else {
745                                 localtime_r(&event_tt, &event_tm);
746                         }
747
748                         if ( (event_tm.tm_year == today_tm.tm_year)
749                            && (event_tm.tm_mon == today_tm.tm_mon)
750                            && (event_tm.tm_mday == today_tm.tm_mday)
751                            ) {
752
753
754                                 p = icalcomponent_get_first_property(
755                                                         WC->disp_cal[i].cal,
756                                                         ICAL_SUMMARY_PROPERTY);
757                                 if (p != NULL) {
758                                         escputs((char *)
759                                                 icalproperty_get_comment(p));
760                                         wprintf(" (%s)<br />\n", timestring);
761                                 }
762                         }
763                 }
764         }
765         free_calendar_buffer();
766 }
767
768
769 /**
770  * \brief clean up ical memory
771  * \todo this could get troubel with future ical versions
772  */
773 void free_calendar_buffer(void) {
774         int i;
775         if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) {
776                 icalcomponent_free(WC->disp_cal[i].cal);
777         }
778         WC->num_cal = 0;
779         free(WC->disp_cal);
780         WC->disp_cal = NULL;
781 }
782
783
784
785 /**
786  * \brief do the whole calendar page
787  * view any part of the calender. decide which way, etc.
788  */
789 void do_calendar_view(void) {
790         time_t now;
791         struct tm tm;
792         int year, month, day;
793         char calview[SIZ];
794
795         /** In case no date was specified, go with today */
796         now = time(NULL);
797         localtime_r(&now, &tm);
798         year = tm.tm_year + 1900;
799         month = tm.tm_mon + 1;
800         day = tm.tm_mday;
801
802         /** Now see if a date was specified */
803         if (strlen(bstr("year")) > 0) year = atoi(bstr("year"));
804         if (strlen(bstr("month")) > 0) month = atoi(bstr("month"));
805         if (strlen(bstr("day")) > 0) day = atoi(bstr("day"));
806
807         /** How would you like that cooked? */
808         if (strlen(bstr("calview")) > 0) {
809                 strcpy(calview, bstr("calview"));
810         }
811         else {
812                 strcpy(calview, "month");
813         }
814
815         /** Display the selected view */
816         if (!strcasecmp(calview, "day")) {
817                 calendar_day_view(year, month, day);
818         }
819         else if (!strcasecmp(calview, "week")) {
820                 calendar_week_view(year, month, day);
821         }
822         else {
823                 if (WC->wc_view == VIEW_CALBRIEF) {
824                         calendar_brief_month_view(year, month, day);
825                 }
826                 else {
827                         calendar_month_view(year, month, day);
828                 }
829         }
830
831         /** Free the calendar stuff */
832         free_calendar_buffer();
833
834 }
835
836
837 /**
838  * \brief get task due date
839  * Helper function for do_tasks_view().  
840  * \param vtodo a task to get the due date
841  * \return the date/time due.
842  */
843 time_t get_task_due_date(icalcomponent *vtodo) {
844         icalproperty *p;
845
846         if (vtodo == NULL) {
847                 return(0L);
848         }
849
850         /**
851          * If we're looking at a fully encapsulated VCALENDAR
852          * rather than a VTODO component, recurse into the data
853          * structure until we get a VTODO.
854          */
855         if (icalcomponent_isa(vtodo) == ICAL_VCALENDAR_COMPONENT) {
856                 return get_task_due_date(
857                         icalcomponent_get_first_component(
858                                 vtodo, ICAL_VTODO_COMPONENT
859                         )
860                 );
861         }
862
863         p = icalcomponent_get_first_property(vtodo, ICAL_DUE_PROPERTY);
864         if (p != NULL) {
865                 return(icaltime_as_timet(icalproperty_get_due(p)));
866         }
867         else {
868                 return(0L);
869         }
870 }
871
872
873 /**
874  * \brief Compare the due dates of two tasks (this is for sorting)
875  * \param task1 first task to compare
876  * \param task2 second task to compare
877  */
878 int task_due_cmp(const void *task1, const void *task2) {
879         time_t t1;
880         time_t t2;
881
882         t1 =  get_task_due_date(((struct disp_cal *)task1)->cal);
883         t2 =  get_task_due_date(((struct disp_cal *)task2)->cal);
884
885         if (t1 < t2) return(-1);
886         if (t1 > t2) return(1);
887         return(0);
888 }
889
890
891
892
893 /**
894  * \brief do the whole task view stuff
895  */
896 void do_tasks_view(void) {
897         int i;
898         time_t due;
899         int bg = 0;
900         char buf[SIZ];
901         icalproperty *p;
902
903         wprintf("<div class=\"fix_scrollbar_bug\">"
904                 "<table border=0 cellspacing=0 width=100%% bgcolor=\"#FFFFFF\">\n<tr>\n"
905                 "<TH>");
906         wprintf(_("Name of task"));
907         wprintf("</TH><TH>");
908         wprintf(_("Date due"));
909         wprintf("</TH></TR>\n"
910         );
911
912         /** Sort them if necessary */
913         if (WC->num_cal > 1) {
914                 qsort(WC->disp_cal,
915                         WC->num_cal,
916                         sizeof(struct disp_cal),
917                         task_due_cmp
918                 );
919         }
920
921         if (WC->num_cal) for (i=0; i<(WC->num_cal); ++i) {
922
923                 bg = 1 - bg;
924                 wprintf("<TR BGCOLOR=\"#%s\"><TD>",
925                         (bg ? "DDDDDD" : "FFFFFF")
926                 );
927
928                 p = icalcomponent_get_first_property(WC->disp_cal[i].cal,
929                                                         ICAL_SUMMARY_PROPERTY);
930                 wprintf("<a href=\"display_edit_task?msgnum=%ld&taskrm=",
931                         WC->disp_cal[i].cal_msgnum );
932                 urlescputs(WC->wc_roomname);
933                 wprintf("\">");
934                 wprintf("<IMG ALIGN=MIDDLE "
935                         "src=\"static/taskmanag_16x.gif\" BORDER=0>&nbsp;");
936                 if (p != NULL) {
937                         escputs((char *)icalproperty_get_comment(p));
938                 }
939                 wprintf("</A>\n");
940                 wprintf("</TD>\n");
941
942                 due = get_task_due_date(WC->disp_cal[i].cal);
943                 fmt_date(buf, due, 0);
944                 wprintf("<TD><FONT");
945                 if (due < time(NULL)) {
946                         wprintf(" COLOR=\"#FF0000\"");
947                 }
948                 wprintf(">%s</FONT></TD></TR>\n", buf);
949         }
950
951         wprintf("</table></div>\n");
952
953         /** Free the list */
954         free_calendar_buffer();
955
956 }
957
958 #endif  /* WEBCIT_WITH_CALENDAR_SERVICE */
959
960 /** @} */