2002-03-17 Gaurav Vaish <gvaish@iitk.ac.in>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / Calendar.cs
1 /**\r
2  * Namespace: System.Web.UI.WebControls\r
3  * Class:     Calendar\r
4  *\r
5  * Author:  Gaurav Vaish\r
6  * Maintainer: gvaish@iitk.ac.in\r
7  * Contact: <my_scripts2001@yahoo.com>, <gvaish@iitk.ac.in>\r
8  * Implementation: yes\r
9  * Status:  98%\r
10  *\r
11  * (C) Gaurav Vaish (2001)\r
12  */\r
13 \r
14 using System;\r
15 using System.IO;\r
16 using System.Collections;\r
17 using System.Globalization;\r
18 using System.Text;\r
19 using System.Web;\r
20 using System.Web.UI;\r
21 using System.Drawing;\r
22 \r
23 namespace System.Web.UI.WebControls\r
24 {\r
25         public class Calendar : WebControl, IPostBackEventHandler\r
26         {\r
27                 //\r
28 \r
29                 private TableItemStyle          dayHeaderStyle;\r
30                 private TableItemStyle          dayStyle;\r
31                 private TableItemStyle          nextPrevStyle;\r
32                 private TableItemStyle          otherMonthDayStyle;\r
33                 private SelectedDatesCollection selectedDates;\r
34                 private ArrayList               selectedDatesList;\r
35                 private TableItemStyle          selectedDayStyle;\r
36                 private TableItemStyle          selectorStyle;\r
37                 private TableItemStyle          titleStyle;\r
38                 private TableItemStyle          todayDayStyle;\r
39                 private TableItemStyle          weekendDayStyle;\r
40 \r
41                 private static readonly object DayRenderEvent           = new object();\r
42                 private static readonly object SelectionChangedEvent    = new object();\r
43                 private static readonly object VisibleMonthChangedEvent = new object();\r
44 \r
45                 private Color defaultTextColor;\r
46                 private System.Globalization.Calendar globCal;\r
47 \r
48                 private static int MASK_WEEKEND  = (0x01 << 0);\r
49                 private static int MASK_OMONTH   = (0x01 << 1);\r
50                 private static int MASK_TODAY    = (0x01 << 2);\r
51                 private static int MASK_SELECTED = (0x01 << 3);\r
52                 private static int MASK_DAY      = (0x01 << 4);\r
53                 private static int MASK_UNIQUE = MASK_WEEKEND | MASK_OMONTH | MASK_TODAY | MASK_SELECTED;\r
54 \r
55                 public Calendar(): base()\r
56                 {\r
57                         //TODO: Initialization\r
58                 }\r
59 \r
60                 public int CellPadding\r
61                 {\r
62                         get\r
63                         {\r
64                                 object o = ViewState["CellPadding"];\r
65                                 if(o!=null)\r
66                                         return (int)o;\r
67                                 return 2;\r
68                         }\r
69                         set\r
70                         {\r
71                                 ViewState["CellPadding"] = value;\r
72                         }\r
73                 }\r
74 \r
75                 public int CellSpacing\r
76                 {\r
77                         get\r
78                         {\r
79                                 object o = ViewState["CellSpacing"];\r
80                                 if(o!=null)\r
81                                         return (int)o;\r
82                                 return 0;\r
83                         }\r
84                         set\r
85                         {\r
86                                 if(value<-1)\r
87                                         throw new ArgumentOutOfRangeException();\r
88                                 ViewState["CellSpacing"] = value;\r
89                         }\r
90                 }\r
91 \r
92                 public TableItemStyle DayHeaderStyle\r
93                 {\r
94                         get\r
95                         {\r
96                                 if(dayHeaderStyle==null)\r
97                                         dayHeaderStyle = new TableItemStyle();\r
98                                 if(IsTrackingViewState)\r
99                                         dayHeaderStyle.TrackViewState();\r
100                                 return dayHeaderStyle;\r
101                         }\r
102                 }\r
103 \r
104                 public DayNameFormat DayNameFormat\r
105                 {\r
106                         get\r
107                         {\r
108                                 object o = ViewState["DayNameFormat"];\r
109                                 if(o!=null)\r
110                                         return (DayNameFormat)o;\r
111                                 return DayNameFormat.Short;\r
112                         }\r
113                         set\r
114                         {\r
115                                 if(!System.Enum.IsDefined(typeof(DayNameFormat),value))\r
116                                         throw new ArgumentException();\r
117                                 ViewState["DayNameFormat"] = value;\r
118                         }\r
119                 }\r
120 \r
121                 public TableItemStyle DayStyle\r
122                 {\r
123                         get\r
124                         {\r
125                                 if(dayStyle==null)\r
126                                         dayStyle = new TableItemStyle();\r
127                                 if(IsTrackingViewState)\r
128                                         dayStyle.TrackViewState();\r
129                                 return dayStyle;\r
130                         }\r
131                 }\r
132 \r
133                 public FirstDayOfWeek FirstDayOfWeek\r
134                 {\r
135                         get\r
136                         {\r
137                                 object o = ViewState["FirstDayOfWeek"];\r
138                                 if(o!=null)\r
139                                         return (FirstDayOfWeek)o;\r
140                                 return FirstDayOfWeek.Default;\r
141                         }\r
142                         set\r
143                         {\r
144                                 if(!System.Enum.IsDefined(typeof(FirstDayOfWeek), value))\r
145                                         throw new ArgumentException();\r
146                                 ViewState["FirstDayOfWeek"] = value;\r
147                         }\r
148                 }\r
149 \r
150                 public string NextMonthText\r
151                 {\r
152                         get\r
153                         {\r
154                                 object o = ViewState["NextMonthText"];\r
155                                 if(o!=null)\r
156                                         return (string)o;\r
157                                 return "&gt;";\r
158                         }\r
159                         set\r
160                         {\r
161                                 ViewState["NextMonthText"] = value;\r
162                         }\r
163                 }\r
164 \r
165                 public NextPrevFormat NextPrevFormat\r
166                 {\r
167                         get\r
168                         {\r
169                                 object o = ViewState["NextPrevFormat"];\r
170                                 if(o!=null)\r
171                                         return (NextPrevFormat)o;\r
172                                 return NextPrevFormat.CustomText;\r
173                         }\r
174                         set\r
175                         {\r
176                                 if(!System.Enum.IsDefined(typeof(NextPrevFormat), value))\r
177                                         throw new ArgumentException();\r
178                                 ViewState["NextPrevFormat"] = value;\r
179                         }\r
180                 }\r
181 \r
182                 public TableItemStyle NextPrevStyle\r
183                 {\r
184                         get\r
185                         {\r
186                                 if(nextPrevStyle == null)\r
187                                         nextPrevStyle = new TableItemStyle();\r
188                                 if(IsTrackingViewState)\r
189                                         nextPrevStyle.TrackViewState();\r
190                                 return nextPrevStyle;\r
191                         }\r
192                 }\r
193 \r
194                 public TableItemStyle OtherMonthDayStyle\r
195                 {\r
196                         get\r
197                         {\r
198                                 if(otherMonthDayStyle == null)\r
199                                         otherMonthDayStyle = new TableItemStyle();\r
200                                 if(IsTrackingViewState)\r
201                                         otherMonthDayStyle.TrackViewState();\r
202                                 return otherMonthDayStyle;\r
203                         }\r
204                 }\r
205 \r
206                 public string PrevMonthText\r
207                 {\r
208                         get\r
209                         {\r
210                                 object o = ViewState["PrevMonthText"];\r
211                                 if(o!=null)\r
212                                         return (string)o;\r
213                                 return "&lt;";\r
214                         }\r
215                         set\r
216                         {\r
217                                 ViewState["PrevMonthText"] = value;\r
218                         }\r
219                 }\r
220 \r
221                 public DateTime SelectedDate\r
222                 {\r
223                         get\r
224                         {\r
225                                 if(SelectedDates.Count > 0)\r
226                                 {\r
227                                         return SelectedDates[0];\r
228                                 }\r
229                                 return DateTime.MinValue;\r
230                         }\r
231                         set\r
232                         {\r
233                                 if(value == DateTime.MinValue)\r
234                                 {\r
235                                         SelectedDates.Clear();\r
236                                 } else\r
237                                 {\r
238                                         SelectedDates.SelectRange(value, value);\r
239                                 }\r
240                         }\r
241                 }\r
242 \r
243                 public SelectedDatesCollection SelectedDates\r
244                 {\r
245                         get\r
246                         {\r
247                                 if(selectedDates==null)\r
248                                 {\r
249                                         if(selectedDatesList == null)\r
250                                                 selectedDatesList = new ArrayList();\r
251                                         selectedDates = new SelectedDatesCollection(selectedDatesList);\r
252                                 }\r
253                                 return selectedDates;\r
254                         }\r
255                 }\r
256 \r
257                 public TableItemStyle SelectedDayStyle\r
258                 {\r
259                         get\r
260                         {\r
261                                 if(selectedDayStyle==null)\r
262                                         selectedDayStyle = new TableItemStyle();\r
263                                 if(IsTrackingViewState)\r
264                                         selectedDayStyle.TrackViewState();\r
265                                 return selectedDayStyle;\r
266                         }\r
267                 }\r
268 \r
269                 public CalendarSelectionMode SelectionMode\r
270                 {\r
271                         get\r
272                         {\r
273                                 object o = ViewState["SelectionMode"];\r
274                                 if(o!=null)\r
275                                         return (CalendarSelectionMode)o;\r
276                                 return CalendarSelectionMode.Day;\r
277                         }\r
278                         set\r
279                         {\r
280                                 if(!System.Enum.IsDefined(typeof(CalendarSelectionMode), value))\r
281                                         throw new ArgumentException();\r
282                                 ViewState["SelectionMode"] = value;\r
283                         }\r
284                 }\r
285 \r
286                 public string SelectedMonthText\r
287                 {\r
288                         get\r
289                         {\r
290                                 object o = ViewState["SelectedMonthText"];\r
291                                 if(o!=null)\r
292                                         return (string)o;\r
293                                 return "&gt;&gt;";\r
294                         }\r
295                         set\r
296                         {\r
297                                 ViewState["SelectedMonthText"] = value;\r
298                         }\r
299                 }\r
300 \r
301                 public TableItemStyle SelectorStyle\r
302                 {\r
303                         get\r
304                         {\r
305                                 if(selectorStyle==null)\r
306                                         selectorStyle = new TableItemStyle();\r
307                                 return selectorStyle;\r
308                         }\r
309                 }\r
310 \r
311                 public string SelectWeekText\r
312                 {\r
313                         get\r
314                         {\r
315                                 object o = ViewState["SelectWeekText"];\r
316                                 if(o!=null)\r
317                                         return (string)o;\r
318                                 return "&gt;";\r
319                         }\r
320                         set\r
321                         {\r
322                                 ViewState["SelectWeekText"] = value;\r
323                         }\r
324                 }\r
325 \r
326                 public bool ShowDayHeader\r
327                 {\r
328                         get\r
329                         {\r
330                                 object o = ViewState["ShowDayHeader"];\r
331                                 if(o!=null)\r
332                                         return (bool)o;\r
333                                 return true;\r
334                         }\r
335                         set\r
336                         {\r
337                                 ViewState["ShowDayHeader"] = value;\r
338                         }\r
339                 }\r
340 \r
341                 public bool ShowGridLines\r
342                 {\r
343                         get\r
344                         {\r
345                                 object o = ViewState["ShowGridLines"];\r
346                                 if(o!=null)\r
347                                         return (bool)o;\r
348                                 return false;\r
349                         }\r
350                         set\r
351                         {\r
352                                 ViewState["ShowGridLines"] = value;\r
353                         }\r
354                 }\r
355 \r
356                 public bool ShowNextPrevMonth\r
357                 {\r
358                         get\r
359                         {\r
360                                 object o = ViewState["ShowNextPrevMonth"];\r
361                                 if(o!=null)\r
362                                         return (bool)o;\r
363                                 return true;\r
364                         }\r
365                         set\r
366                         {\r
367                                 ViewState["ShowNextPrevMonth"] = value;\r
368                         }\r
369                 }\r
370 \r
371                 public bool ShowTitle\r
372                 {\r
373                         get\r
374                         {\r
375                                 object o = ViewState["ShowTitle"];\r
376                                 if(o!=null)\r
377                                         return (bool)o;\r
378                                 return true;\r
379                         }\r
380                         set\r
381                         {\r
382                                 ViewState["ShowTitle"] = value;\r
383                         }\r
384                 }\r
385 \r
386                 public TitleFormat TitleFormat\r
387                 {\r
388                         get\r
389                         {\r
390                                 object o = ViewState["TitleFormat"];\r
391                                 if(o!=null)\r
392                                         return (TitleFormat)o;\r
393                                 return TitleFormat.MonthYear;\r
394                         }\r
395                         set\r
396                         {\r
397                                 if(!System.Enum.IsDefined(typeof(TitleFormat), value))\r
398                                         throw new ArgumentException();\r
399                                 ViewState["TitleFormat"] = value;\r
400                         }\r
401                 }\r
402 \r
403                 public TableItemStyle TitleStyle\r
404                 {\r
405                         get\r
406                         {\r
407                                 if(titleStyle==null)\r
408                                         titleStyle = new TableItemStyle();\r
409                                 if(IsTrackingViewState)\r
410                                         titleStyle.TrackViewState();\r
411                                 return titleStyle;\r
412                         }\r
413                 }\r
414 \r
415                 public TableItemStyle TodayDayStyle\r
416                 {\r
417                         get\r
418                         {\r
419                                 if(todayDayStyle==null)\r
420                                         todayDayStyle = new TableItemStyle();\r
421                                 if(IsTrackingViewState)\r
422                                         todayDayStyle.TrackViewState();\r
423                                 return todayDayStyle;\r
424                         }\r
425                 }\r
426 \r
427                 public DateTime TodaysDate\r
428                 {\r
429                         get\r
430                         {\r
431                                 object o = ViewState["TodaysDate"];\r
432                                 if(o!=null)\r
433                                         return (DateTime)o;\r
434                                 return DateTime.Today;\r
435                         }\r
436                         set\r
437                         {\r
438                                 ViewState["TodaysDate"] = value;\r
439                         }\r
440                 }\r
441 \r
442                 public DateTime VisibleDate\r
443                 {\r
444                         get\r
445                         {\r
446                                 object o = ViewState["VisibleDate"];\r
447                                 if(o!=null)\r
448                                         return (DateTime)o;\r
449                                 return DateTime.MinValue;\r
450                         }\r
451                         set\r
452                         {\r
453                                 ViewState["VisibleDate"] = value;\r
454                         }\r
455                 }\r
456 \r
457                 public TableItemStyle WeekendDayStyle\r
458                 {\r
459                         get\r
460                         {\r
461                                 if(weekendDayStyle == null)\r
462                                         weekendDayStyle = new TableItemStyle();\r
463                                 if(IsTrackingViewState)\r
464                                 {\r
465                                         weekendDayStyle.TrackViewState();\r
466                                 }\r
467                                 return weekendDayStyle;\r
468                         }\r
469                 }\r
470 \r
471                 public event DayRenderEventHandler DayRender\r
472                 {\r
473                         add\r
474                         {\r
475                                 Events.AddHandler(DayRenderEvent, value);\r
476                         }\r
477                         remove\r
478                         {\r
479                                 Events.RemoveHandler(DayRenderEvent, value);\r
480                         }\r
481                 }\r
482 \r
483                 public event EventHandler SelectionChanged\r
484                 {\r
485                         add\r
486                         {\r
487                                 Events.AddHandler(SelectionChangedEvent, value);\r
488                         }\r
489                         remove\r
490                         {\r
491                                 Events.RemoveHandler(SelectionChangedEvent, value);\r
492                         }\r
493                 }\r
494 \r
495                 public event MonthChangedEventHandler VisibleMonthChanged\r
496                 {\r
497                         add\r
498                         {\r
499                                 Events.AddHandler(VisibleMonthChangedEvent, value);\r
500                         }\r
501                         remove\r
502                         {\r
503                                 Events.RemoveHandler(VisibleMonthChangedEvent, value);\r
504                         }\r
505                 }\r
506 \r
507                 protected virtual void OnDayRender(TableCell cell, CalendarDay day)\r
508                 {\r
509                         if(Events!=null)\r
510                         {\r
511                                 DayRenderEventHandler dreh = (DayRenderEventHandler)(Events[DayRenderEvent]);\r
512                                 if(dreh!=null)\r
513                                         dreh(this, new DayRenderEventArgs(cell, day));\r
514                         }\r
515                 }\r
516 \r
517                 protected virtual void OnSelectionChanged()\r
518                 {\r
519                         if(Events!=null)\r
520                         {\r
521                                 EventHandler eh = (EventHandler)(Events[SelectionChangedEvent]);\r
522                                 if(eh!=null)\r
523                                         eh(this, new EventArgs());\r
524                         }\r
525                 }\r
526 \r
527                 protected virtual void OnVisibleMonthChanged(DateTime newDate, DateTime prevDate)\r
528                 {\r
529                         if(Events!=null)\r
530                         {\r
531                                 MonthChangedEventHandler mceh = (MonthChangedEventHandler)(Events[VisibleMonthChangedEvent]);\r
532                                 if(mceh!=null)\r
533                                         mceh(this, new MonthChangedEventArgs(newDate, prevDate));\r
534                         }\r
535                 }\r
536 \r
537                 /// <remarks>\r
538                 /// See test6.aspx in Tests directory for verification\r
539                 /// </remarks>\r
540                 void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)\r
541                 {\r
542                         globCal = DateTimeFormatInfo.CurrentInfo.Calendar;\r
543                         DateTime visDate = GetEffectiveVisibleDate();\r
544                         //FIXME: Should it be String.Compare(eventArgument, "nextMonth", false);\r
545                         if(eventArgument == "nextMonth")\r
546                         {\r
547                                 VisibleDate = globCal.AddMonths(visDate, 1);\r
548                                 OnVisibleMonthChanged(VisibleDate, visDate);\r
549                                 return;\r
550                         }\r
551                         if(eventArgument == "prevMonth")\r
552                         {\r
553                                 VisibleDate = globCal.AddMonths(visDate, -1);\r
554                                 OnVisibleMonthChanged(VisibleDate, visDate);\r
555                                 return;\r
556                         }\r
557                         if(eventArgument == "selectMonth")\r
558                         {\r
559                                 DateTime oldDate = new DateTime(globCal.GetYear(visDate), globCal.GetMonth(visDate), 1, globCal);\r
560                                 SelectRangeInternal(oldDate, globCal.AddDays(globCal.AddMonths(oldDate, 1), -1), visDate);\r
561                                 return;\r
562                         }\r
563                         if(String.Compare(eventArgument, 0, "selectWeek", 0, "selectWeek".Length)==0)\r
564                         {\r
565                                 int week = -1;\r
566                                 try\r
567                                 {\r
568                                         week = Int32.Parse(eventArgument.Substring("selectWeek".Length));\r
569                                 } catch(Exception e)\r
570                                 {\r
571                                 }\r
572                                 if(week >= 0 && week <= 5)\r
573                                 {\r
574                                         DateTime weekStart = globCal.AddDays(GetFirstCalendarDay(visDate), week * 7);\r
575                                         SelectRangeInternal(weekStart, globCal.AddDays(weekStart, 6), visDate);\r
576                                 }\r
577                                 return;\r
578                         }\r
579                         if(String.Compare(eventArgument, 0, "selectDay", 0, "selectDay".Length)==0)\r
580                         {\r
581                                 int day = -1;\r
582                                 try\r
583                                 {\r
584                                         day = Int32.Parse(eventArgument.Substring("selectDay".Length));\r
585                                 } catch(Exception e)\r
586                                 {\r
587                                 }\r
588                                 if(day >= 0 && day <= 42)\r
589                                 {\r
590                                         DateTime dayStart = globCal.AddDays(GetFirstCalendarDay(visDate), day);\r
591                                         SelectRangeInternal(dayStart, dayStart, visDate);\r
592                                 }\r
593                         }\r
594                 }\r
595 \r
596                 protected override void Render(HtmlTextWriter writer)\r
597                 {\r
598                         //TODO: Implement me\r
599                         globCal = DateTimeFormatInfo.CurrentInfo.Calendar;\r
600                         DateTime visDate   = GetEffectiveVisibleDate();\r
601                         DateTime firstDate = GetFirstCalendarDay(visDate);\r
602 \r
603                         bool isEnabled = false;\r
604                         bool isHtmlTextWriter = false;\r
605                         if(Page == null || Site == null)\r
606                         {\r
607                                 isEnabled = false;\r
608                                 isHtmlTextWriter = false;\r
609                         } else\r
610                         {\r
611                                 isEnabled = Enabled;\r
612                                 isHtmlTextWriter = (writer.GetType() != typeof(HtmlTextWriter));\r
613                         }\r
614                         defaultTextColor = ForeColor;\r
615                         if(defaultTextColor == Color.Empty)\r
616                                 defaultTextColor = Color.Black;\r
617 \r
618                         Table calTable = new Table();\r
619                         calTable.ID = ID;\r
620                         calTable.CopyBaseAttributes(this);\r
621                         if(ControlStyleCreated)\r
622                                 ApplyStyle(ControlStyle);\r
623                         calTable.Width = Width;\r
624                         calTable.Height = Height;\r
625                         calTable.CellSpacing = CellSpacing;\r
626                         calTable.CellPadding = CellPadding;\r
627 \r
628                         if(ControlStyleCreated && ControlStyle.IsSet(WebControls.Style.BORDERWIDTH) && BorderWidth != Unit.Empty)\r
629                         {\r
630                                 calTable.BorderWidth = BorderWidth;\r
631                         } else\r
632                         {\r
633                                 calTable.BorderWidth = Unit.Pixel(1);\r
634                         }\r
635 \r
636                         if(ShowGridLines)\r
637                                 calTable.GridLines = GridLines.Both;\r
638                         else\r
639                                 calTable.GridLines = GridLines.None;\r
640 \r
641                         calTable.RenderBeginTag(writer);\r
642                         if(ShowTitle)\r
643                                 RenderTitle(writer, visDate, SelectionMode, isEnabled);\r
644                         if(ShowDayHeader)\r
645                                 RenderHeader(writer, firstDate, SelectionMode, isEnabled, isHtmlTextWriter);\r
646                         RenderAllDays(writer, firstDate, visDate, SelectionMode, isEnabled, isHtmlTextWriter);\r
647 \r
648                         calTable.RenderEndTag(writer);\r
649                 }\r
650 \r
651                 protected override ControlCollection CreateControlCollection()\r
652                 {\r
653                         return new EmptyControlCollection(this);\r
654                 }\r
655 \r
656                 protected override void LoadViewState(object savedState)\r
657                 {\r
658                         if(savedState!=null)\r
659                         {\r
660                                 if(ViewState["_CalendarSelectedDates"] != null)\r
661                                         selectedDates = (SelectedDatesCollection)ViewState["_CalendarSelectedDates"];\r
662 \r
663                                 object[] states = (object[]) savedState;\r
664                                 if(states[0] != null)\r
665                                         base.LoadViewState(states[0]);\r
666                                 if(states[1] != null)\r
667                                         DayHeaderStyle.LoadViewState(states[1]);\r
668                                 if(states[2] != null)\r
669                                         DayStyle.LoadViewState(states[2]);\r
670                                 if(states[3] != null)\r
671                                         NextPrevStyle.LoadViewState(states[3]);\r
672                                 if(states[4] != null)\r
673                                         OtherMonthDayStyle.LoadViewState(states[4]);\r
674                                 if(states[5] != null)\r
675                                         SelectedDayStyle.LoadViewState(states[5]);\r
676                                 if(states[6] != null)\r
677                                         SelectorStyle.LoadViewState(states[6]);\r
678                                 if(states[7] != null)\r
679                                         TitleStyle.LoadViewState(states[7]);\r
680                                 if(states[8] != null)\r
681                                         TodayDayStyle.LoadViewState(states[8]);\r
682                                 if(states[9] != null)\r
683                                         WeekendDayStyle.LoadViewState(states[9]);\r
684                         }\r
685                 }\r
686 \r
687                 protected override object SaveViewState()\r
688                 {\r
689                         ViewState["_CalendarSelectedDates"] = (SelectedDates.Count > 0 ? selectedDates : null);\r
690                         object[] states = new object[11];\r
691                         states[0] = base.SaveViewState();\r
692                         states[1] = (dayHeaderStyle == null ? null : dayHeaderStyle.SaveViewState());\r
693                         states[2] = (dayStyle == null ? null : dayStyle.SaveViewState());\r
694                         states[3] = (nextPrevStyle == null ? null : nextPrevStyle.SaveViewState());\r
695                         states[4] = (otherMonthDayStyle == null ? null : otherMonthDayStyle.SaveViewState());\r
696                         states[5] = (selectedDayStyle == null ? null : selectedDayStyle.SaveViewState());\r
697                         states[6] = (selectorStyle == null ? null : selectorStyle.SaveViewState());\r
698                         states[7] = (titleStyle == null ? null : titleStyle.SaveViewState());\r
699                         states[8] = (todayDayStyle == null ? null : todayDayStyle.SaveViewState());\r
700                         states[9] = (weekendDayStyle == null ? null : weekendDayStyle.SaveViewState());\r
701                         for(int i=0; i < states.Length; i++)\r
702                         {\r
703                                 if(states[i]!=null)\r
704                                         return states;\r
705                         }\r
706                         return null;\r
707                 }\r
708 \r
709                 protected override void TrackViewState()\r
710                 {\r
711                         TrackViewState();\r
712                         if(titleStyle!=null)\r
713                         {\r
714                                 titleStyle.TrackViewState();\r
715                         }\r
716                         if(nextPrevStyle!=null)\r
717                         {\r
718                                 nextPrevStyle.TrackViewState();\r
719                         }\r
720                         if(dayStyle!=null)\r
721                         {\r
722                                 dayStyle.TrackViewState();\r
723                         }\r
724                         if(dayHeaderStyle!=null)\r
725                         {\r
726                                 dayHeaderStyle.TrackViewState();\r
727                         }\r
728                         if(todayDayStyle!=null)\r
729                         {\r
730                                 todayDayStyle.TrackViewState();\r
731                         }\r
732                         if(weekendDayStyle!=null)\r
733                         {\r
734                                 weekendDayStyle.TrackViewState();\r
735                         }\r
736                         if(otherMonthDayStyle!=null)\r
737                         {\r
738                                 otherMonthDayStyle.TrackViewState();\r
739                         }\r
740                         if(selectedDayStyle!=null)\r
741                         {\r
742                                 selectedDayStyle.TrackViewState();\r
743                         }\r
744                         if(selectorStyle!=null)\r
745                         {\r
746                                 selectorStyle.TrackViewState();\r
747                         }\r
748                 }\r
749 \r
750                 [MonoTODO("RenderAllDays")]\r
751                 private void RenderAllDays(HtmlTextWriter writer, DateTime firstDay, DateTime activeDate, CalendarSelectionMode mode, bool isActive, bool isDownLevel)\r
752                 {\r
753                         /*\r
754                         TableItemStyle weeksStyle;\r
755                         Unit size;\r
756                         string weeksCellData;\r
757                         bool isWeekMode = (mode == CalendarSelectionMode.DayWeek || mode == CalendarSelectionMode.DayWeekMonth);\r
758                         if(isWeekMode)\r
759                         {\r
760                                 weeksStyle = new TableItemStyle();\r
761                                 weeksStyle.Width = Unit.Percentage(12);\r
762                                 weeksStyle.HorizontalAlign = HorizontalAlign.Center;\r
763                                 weeksStyle.CopyFrom(SelectorStyle);\r
764                                 size = Unit.Percentage(14);\r
765                                 if(!isDownLevel)\r
766                                         weeksCellData = GetHtmlForCell(weeksCell, isActive);\r
767                         }\r
768                         bool dayRenderBool = false;\r
769                         if(GetType() != typeof(Calendar) || Events[DayRenderEvent] != null || !isDownLevel)\r
770                                 dayRenderBool = true;\r
771 \r
772                         string[] content = new string[0x01 << 4];\r
773                         int definedStyles = MASK_SELECTED;\r
774                         if(weekendStyle != null && !weekendStyle.IsEmpty)\r
775                                 definedStyles |= MASK_WEEKEND;\r
776                         if(otherMonthStyle != null && !otherMonthStyle.IsEmpty)\r
777                                 definedStyles |= MASK_OMONTH;\r
778                         if(todayDayStyle != null && todayDayStyle.IsEmpty)\r
779                                 definedStyles |= MASK_TODAY;\r
780                         if(dayStyle != null && !dayStyle.IsEmpty)\r
781                                 definedStyles |= MASK_DAY;\r
782 \r
783                         bool selectDayBool = false;\r
784                         if(isActive && mode != CalendarSelectionMode.None)\r
785                         {\r
786                                 selectDayBool = true;\r
787                         }\r
788 \r
789                         for(int crr = 0; crr < 6; crr++)\r
790                         {\r
791                                 writer.Write("<tr>");\r
792                                 if(isWeekMode)\r
793                                 {\r
794                                         if(isDownLevel)\r
795                                         {\r
796                                                 string cellText = GetCalendarLinkText("selectWeek" + crr.ToString(), SelectWeekText, isActive, weeksCell.ForeColor);\r
797                                                 weeksCell.Text = cellText;\r
798                                                 RenderCalendarCell(writer, weeksCell, cellText);\r
799                                         } else\r
800                                         {\r
801                                                 if(isActive)\r
802                                                 {\r
803                                                         writer.Write(String.Format(weeksCellData, "selectWeek" + crr.ToString(), SelectWeekText));\r
804                                                 } else\r
805                                                 {\r
806                                                         writer.Write(String.Format(weeksCellData, "selectWeek" + crr.ToString()));\r
807                                                 }\r
808                                         }\r
809                                 }\r
810                                 for(int crc = 0; crc < 7; crc++)\r
811                                 {\r
812                                         // have to display for each day in the week.\r
813                                         throw new NotImplementedException();\r
814                                 }\r
815                         }\r
816                         */\r
817                         throw new NotImplementedException();\r
818                 }\r
819 \r
820                 private int GetMask(CalendarDay day)\r
821                 {\r
822                         int retVal = MASK_DAY;\r
823                         if(day.IsSelected)\r
824                                 retVal |= MASK_SELECTED;\r
825                         if(day.IsToday)\r
826                                 retVal |= MASK_TODAY;\r
827                         if(day.IsOtherMonth)\r
828                                 retVal |= MASK_OMONTH;\r
829                         if(day.IsWeekend)\r
830                                 retVal |= MASK_WEEKEND;\r
831                         return retVal;\r
832                 }\r
833 \r
834                 /// <remarks>\r
835                 /// Refers to the second line of the calendar, that contains a link\r
836                 /// to select whole month, and weekdays as defined by DayNameFormat\r
837                 /// </remarks>\r
838                 private void RenderHeader(HtmlTextWriter writer, DateTime firstDay, CalendarSelectionMode mode, bool isActive, bool isDownLevel)\r
839                 {\r
840                         writer.Write("<tr>");\r
841                         bool isWeekMode = (mode == CalendarSelectionMode.DayWeek || mode == CalendarSelectionMode.DayWeekMonth);\r
842                         TableCell headerCell = new TableCell();\r
843                         headerCell.HorizontalAlign = HorizontalAlign.Center;\r
844                         string selMthText = String.Empty;\r
845                         if(isWeekMode)\r
846                         {\r
847                                 headerCell.ApplyStyle(SelectorStyle);\r
848                                 selMthText = GetCalendarLinkText("selectMonth", SelectedMonthText, SelectorStyle.ForeColor, isActive);\r
849                         } else\r
850                         {\r
851                                 headerCell.ApplyStyle(DayHeaderStyle);\r
852                         }\r
853                         RenderCalendarCell(writer, headerCell, selMthText);\r
854 \r
855                         TableCell dayHeaderCell = new TableCell();\r
856                         dayHeaderCell.HorizontalAlign = HorizontalAlign.Center;\r
857                         string content = null;\r
858                         if(!isDownLevel)\r
859                         {\r
860                                 content = GetHtmlForCell(dayHeaderCell, isActive);\r
861                         }\r
862                         int dayOfWeek = (int)globCal.GetDayOfWeek(firstDay);\r
863                         DateTimeFormatInfo currDTInfo = DateTimeFormatInfo.CurrentInfo;\r
864                         for(int currDay = dayOfWeek; currDay < dayOfWeek + 7; currDay++)\r
865                         {\r
866                                 DayOfWeek effDay = (DayOfWeek) Enum.ToObject(typeof(DayOfWeek),currDay % 7);\r
867                                 string currDayContent = String.Empty;\r
868                                 switch(DayNameFormat)\r
869                                 {\r
870                                         case DayNameFormat.Full:            currDayContent = currDTInfo.GetDayName(effDay);\r
871                                                                             break;\r
872                                         case DayNameFormat.FirstLetter:     currDayContent = currDTInfo.GetDayName(effDay).Substring(0,1);\r
873                                                                             break;\r
874                                         case DayNameFormat.FirstTwoLetters: currDayContent = currDTInfo.GetDayName(effDay).Substring(0,2);\r
875                                                                             break;\r
876                                         case DayNameFormat.Short:           goto default;\r
877                                         default:                            currDayContent = currDTInfo.GetAbbreviatedDayName(effDay);\r
878                                                                             break;\r
879                                 }\r
880                                 if(isDownLevel)\r
881                                 {\r
882                                         RenderCalendarCell(writer, dayHeaderCell, currDayContent);\r
883                                 } else\r
884                                 {\r
885                                         writer.Write(String.Format(content, currDayContent));\r
886                                 }\r
887                         }\r
888                         writer.Write("</tr>");\r
889                 }\r
890 \r
891                 private void RenderTitle(HtmlTextWriter writer, DateTime visibleDate, CalendarSelectionMode mode, bool isActive)\r
892                 {\r
893                         writer.Write("<tr>");\r
894                         Table innerTable = new Table();\r
895                         TableCell titleCell = new TableCell();\r
896                         bool isWeekMode = (mode == CalendarSelectionMode.DayWeek || mode == CalendarSelectionMode.DayWeekMonth);\r
897                         titleCell.ColumnSpan = (isWeekMode ? 8 : 7);\r
898                         titleCell.BackColor = Color.Silver;\r
899 \r
900                         innerTable.GridLines = GridLines.None;\r
901                         innerTable.Width = Unit.Percentage(100);\r
902                         innerTable.CellSpacing = 0;\r
903                         ApplyTitleStyle(innerTable, titleCell, TitleStyle);\r
904 \r
905                         innerTable.RenderBeginTag(writer);\r
906                         titleCell.RenderBeginTag(writer);\r
907 \r
908                         writer.Write("<tr>");\r
909                         string prevContent = String.Empty;\r
910                         if(ShowNextPrevMonth)\r
911                         {\r
912                                 TableCell prevCell = new TableCell();\r
913                                 prevCell.Width = Unit.Percentage(15);\r
914                                 prevCell.HorizontalAlign = HorizontalAlign.Left;\r
915                                 if(NextPrevFormat == NextPrevFormat.CustomText)\r
916                                 {\r
917                                         prevContent = PrevMonthText;\r
918                                 } else\r
919                                 {\r
920                                         int pMthInt = globCal.GetMonth(globCal.AddMonths(visibleDate, -1));\r
921                                         if(NextPrevFormat == NextPrevFormat.FullMonth)\r
922                                                 prevContent = DateTimeFormatInfo.CurrentInfo.GetMonthName(pMthInt);\r
923                                         else\r
924                                                 prevContent = DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName(pMthInt);\r
925                                 }\r
926                                 prevCell.ApplyStyle(NextPrevStyle);\r
927                                 RenderCalendarCell(writer, prevCell, GetCalendarLinkText("prevMonth", prevContent, NextPrevStyle.ForeColor, isActive));\r
928                         }\r
929                         TableCell currCell = new TableCell();\r
930                         currCell.Width = Unit.Percentage(70);\r
931                         if(TitleStyle.HorizontalAlign == HorizontalAlign.NotSet)\r
932                                 currCell.HorizontalAlign = HorizontalAlign.Center;\r
933                         else\r
934                                 currCell.HorizontalAlign = TitleStyle.HorizontalAlign;\r
935                         currCell.Wrap = TitleStyle.Wrap;\r
936                         string currMonthContent = String.Empty;\r
937                         if(TitleFormat == TitleFormat.Month)\r
938                         {\r
939                                 currMonthContent = visibleDate.ToString("MMMM");\r
940                         } else\r
941                         {\r
942                                 string cmcFmt = DateTimeFormatInfo.CurrentInfo.YearMonthPattern;\r
943                                 if(cmcFmt.IndexOf(',') >= 0)\r
944                                 {\r
945                                         cmcFmt = "MMMM yyyy";\r
946                                 }\r
947                                 currMonthContent = visibleDate.ToString(cmcFmt);\r
948                         }\r
949                         string nextContent = String.Empty;\r
950                         if(ShowNextPrevMonth)\r
951                         {\r
952                                 TableCell nextCell = new TableCell();\r
953                                 nextCell.Width = Unit.Percentage(15);\r
954                                 nextCell.HorizontalAlign = HorizontalAlign.Left;\r
955                                 if(NextPrevFormat == NextPrevFormat.CustomText)\r
956                                 {\r
957                                         nextContent = PrevMonthText;\r
958                                 } else\r
959                                 {\r
960                                         int nMthInt = globCal.GetMonth(globCal.AddMonths(visibleDate, 1));\r
961                                         if(NextPrevFormat == NextPrevFormat.FullMonth)\r
962                                                 nextContent = DateTimeFormatInfo.CurrentInfo.GetMonthName(nMthInt);\r
963                                         else\r
964                                                 nextContent = DateTimeFormatInfo.CurrentInfo.GetAbbreviatedMonthName(nMthInt);\r
965                                 }\r
966                                 nextCell.ApplyStyle(NextPrevStyle);\r
967                                 RenderCalendarCell(writer, nextCell, GetCalendarLinkText("nextMonth", nextContent, NextPrevStyle.ForeColor, isActive));\r
968                         }\r
969 \r
970                         writer.Write("</tr>");\r
971                         titleCell.RenderEndTag(writer);\r
972                         innerTable.RenderEndTag(writer);\r
973 \r
974                         writer.Write("</tr>");\r
975                 }\r
976 \r
977                 private void ApplyTitleStyle(Table table, TableCell cell, TableItemStyle style)\r
978                 {\r
979                         if(style.BackColor != Color.Empty)\r
980                         {\r
981                                 cell.BackColor = style.BackColor;\r
982                         }\r
983                         if(style.BorderStyle != BorderStyle.NotSet)\r
984                         {\r
985                                 cell.BorderStyle = style.BorderStyle;\r
986                         }\r
987                         if(style.BorderColor != Color.Empty)\r
988                         {\r
989                                 cell.BorderColor = style.BorderColor;\r
990                         }\r
991                         if(style.BorderWidth != Unit.Empty)\r
992                         {\r
993                                 cell.BorderWidth = style.BorderWidth;\r
994                         }\r
995                         if(style.Height != Unit.Empty)\r
996                         {\r
997                                 cell.Height = style.Height;\r
998                         }\r
999                         if(style.VerticalAlign != VerticalAlign.NotSet)\r
1000                         {\r
1001                                 cell.VerticalAlign = style.VerticalAlign;\r
1002                         }\r
1003 \r
1004                         if(style.ForeColor != Color.Empty)\r
1005                         {\r
1006                                 table.ForeColor = style.ForeColor;\r
1007                         } else if(ForeColor != Color.Empty)\r
1008                         {\r
1009                                 table.ForeColor = ForeColor;\r
1010                         }\r
1011 \r
1012                         table.Font.CopyFrom(style.Font);\r
1013                         table.Font.MergeWith(Font);\r
1014                 }\r
1015 \r
1016                 private void RenderCalendarCell(HtmlTextWriter writer, TableCell cell, string text)\r
1017                 {\r
1018                         cell.RenderBeginTag(writer);\r
1019                         writer.Write(text);\r
1020                         cell.RenderEndTag(writer);\r
1021                 }\r
1022 \r
1023                 private DateTime GetFirstCalendarDay(DateTime visibleDate)\r
1024                 {\r
1025                         DayOfWeek firstDay = DateTimeFormatInfo.CurrentInfo.FirstDayOfWeek;\r
1026                         if(FirstDayOfWeek != FirstDayOfWeek.Default)\r
1027                         {\r
1028                                 firstDay = (DayOfWeek) Enum.ToObject(typeof(DayOfWeek), (int)FirstDayOfWeek);\r
1029                         }\r
1030                         //FIXME: is (int)(Enum) correct?\r
1031                         int days = (int)globCal.GetDayOfWeek(visibleDate) - (int)firstDay;\r
1032                         if(days < 0)\r
1033                         {\r
1034                                 days += 7;\r
1035                         }\r
1036                         return globCal.AddDays(visibleDate, -days);\r
1037                 }\r
1038 \r
1039                 private DateTime GetEffectiveVisibleDate()\r
1040                 {\r
1041                         DateTime dt = VisibleDate;\r
1042                         if(dt.Equals(DateTime.MinValue))\r
1043                         {\r
1044                                 dt = TodaysDate;\r
1045                         }\r
1046                         return new DateTime(globCal.GetYear(dt), globCal.GetMonth(dt), globCal.GetDayOfMonth(dt), globCal);\r
1047                 }\r
1048 \r
1049                 /// <summary>\r
1050                 /// Creates text to be displayed, with all attributes if to be\r
1051                 /// shown as a hyperlink\r
1052                 /// </summary>\r
1053                 private string GetCalendarLinkText(string eventArg, string text, Color foreground, bool isLink)\r
1054                 {\r
1055                         if(isLink)\r
1056                         {\r
1057                                 StringBuilder dispVal = new StringBuilder();\r
1058                                 dispVal.Append("<a href=\"");\r
1059                                 dispVal.Append(Page.GetPostBackClientHyperlink(this, eventArg));\r
1060                                 dispVal.Append("\" style=\"color: ");\r
1061                                 if(foreground.IsEmpty)\r
1062                                 {\r
1063                                         dispVal.Append(ColorTranslator.ToHtml(defaultTextColor));\r
1064                                 } else\r
1065                                 {\r
1066                                         dispVal.Append(ColorTranslator.ToHtml(foreground));\r
1067                                 }\r
1068                                 dispVal.Append("\">");\r
1069                                 dispVal.Append(text);\r
1070                                 dispVal.Append("</a>");\r
1071                                 return dispVal.ToString();\r
1072                         }\r
1073                         return text;\r
1074                 }\r
1075 \r
1076                 private string GetHtmlForCell(TableCell cell, bool showLinks)\r
1077                 {\r
1078                         StringWriter sw = new StringWriter();\r
1079                         HtmlTextWriter htw = new HtmlTextWriter(sw);\r
1080                         cell.RenderBeginTag(htw);\r
1081                         if(showLinks)\r
1082                         {\r
1083                                 htw.Write(GetCalendarLinkText("{0}", "{1}", cell.ForeColor, showLinks));\r
1084                         } else\r
1085                         {\r
1086                                 htw.Write("{0}");\r
1087                         }\r
1088                         cell.RenderEndTag(htw);\r
1089                         return sw.ToString();\r
1090                 }\r
1091 \r
1092                 internal void SelectRangeInternal(DateTime fromDate, DateTime toDate, DateTime visibleDate)\r
1093                 {\r
1094                         TimeSpan span = fromDate - toDate;\r
1095                         if(SelectedDates.Count != span.Days || SelectedDates[SelectedDates.Count - 1]!= toDate)\r
1096                         {\r
1097                                 SelectedDates.SelectRange(fromDate, toDate);\r
1098                                 OnSelectionChanged();\r
1099                         }\r
1100                         if(globCal.GetMonth(fromDate) == globCal.GetMonth(fromDate) && globCal.GetMonth(fromDate) != globCal.GetMonth(visibleDate))\r
1101                         {\r
1102                                 VisibleDate = new DateTime(globCal.GetYear(fromDate), globCal.GetMonth(fromDate), 1, globCal);\r
1103                                 OnVisibleMonthChanged(VisibleDate, visibleDate);\r
1104                         }\r
1105                 }\r
1106         }\r
1107 }\r