2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / Calendar.cs
1 //
2 // System.Web.UI.WebControls.Calendar.cs
3 //
4 // Authors:
5 //   Gaurav Vaish (gvaish@iitk.ac.in)
6 //   Gonzalo Paniagua Javier (gonzalo@ximian.com)
7 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 //
9 // (c) Copyright 2002 Ximian, Inc. (http://www.ximian.com)
10 // (C) Gaurav Vaish (2002)
11 // (C) 2003 Andreas Nahr
12 //\r
13
14 //
15 // Permission is hereby granted, free of charge, to any person obtaining
16 // a copy of this software and associated documentation files (the
17 // "Software"), to deal in the Software without restriction, including
18 // without limitation the rights to use, copy, modify, merge, publish,
19 // distribute, sublicense, and/or sell copies of the Software, and to
20 // permit persons to whom the Software is furnished to do so, subject to
21 // the following conditions:
22 // 
23 // The above copyright notice and this permission notice shall be
24 // included in all copies or substantial portions of the Software.
25 // 
26 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
27 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
28 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
29 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
30 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
31 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
32 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
33 //
34 \r
35 using System;\r
36 using System.IO;\r
37 using System.Collections;\r
38 using System.Globalization;\r
39 using System.Text;\r
40 using System.Web;\r
41 using System.Web.UI;\r
42 using System.Drawing;\r
43 using System.ComponentModel;
44 using System.ComponentModel.Design;\r
45 \r
46 namespace System.Web.UI.WebControls\r
47 {\r
48         [DefaultEvent("SelectionChanged")]\r
49         [DefaultProperty("SelectedDate")]\r
50         [Designer("System.Web.UI.Design.WebControls.CalendarDesigner, " + Consts.AssemblySystem_Design, typeof (IDesigner))]\r
51         [DataBindingHandler("System.Web.UI.Design.WebControls.CalendarDataBindingHandler, " + Consts.AssemblySystem_Design)]
52         public class Calendar : WebControl, IPostBackEventHandler\r
53         {\r
54                 //\r
55                 private TableItemStyle          dayHeaderStyle;\r
56                 private TableItemStyle          dayStyle;\r
57                 private TableItemStyle          nextPrevStyle;\r
58                 private TableItemStyle          otherMonthDayStyle;\r
59                 private SelectedDatesCollection selectedDates;\r
60                 private ArrayList               selectedDatesList;\r
61                 private TableItemStyle          selectedDayStyle;\r
62                 private TableItemStyle          selectorStyle;\r
63                 private TableItemStyle          titleStyle;\r
64                 private TableItemStyle          todayDayStyle;\r
65                 private TableItemStyle          weekendDayStyle;\r
66 \r
67                 private static readonly object DayRenderEvent           = new object();\r
68                 private static readonly object SelectionChangedEvent    = new object();\r
69                 private static readonly object VisibleMonthChangedEvent = new object();\r
70 \r
71                 private Color defaultTextColor;\r
72                 private System.Globalization.Calendar globCal;\r
73                 private DateTimeFormatInfo infoCal = DateTimeFormatInfo.CurrentInfo;
74
75                 private static readonly DateTime begin_date = new DateTime (2000,01,01,0,0,0,0);
76                                 
77 \r
78                 private static int MASK_WEEKEND  = (0x01 << 0);\r
79                 private static int MASK_OMONTH   = (0x01 << 1);\r
80                 private static int MASK_TODAY    = (0x01 << 2);\r
81                 private static int MASK_SELECTED = (0x01 << 3);\r
82                 private static int MASK_DAY      = (0x01 << 4);\r
83                 private static int MASK_UNIQUE = MASK_WEEKEND | MASK_OMONTH | MASK_TODAY | MASK_SELECTED;\r
84 \r
85                 public Calendar(): base()\r
86                 {\r
87                 }\r
88
89
90                 [DefaultValue (2), Bindable (true), WebCategory ("Layout")]
91                 [WebSysDescription ("The border left within the calendar days.")]\r
92                 public int CellPadding\r
93                 {\r
94                         get\r
95                         {\r
96                                 object o = ViewState["CellPadding"];\r
97                                 if(o!=null)\r
98                                         return (int)o;\r
99                                 return 2;\r
100                         }\r
101                         set\r
102                         {
103                                 if (value < -1)
104                                         throw new ArgumentOutOfRangeException ("value", "CellPadding value has to be -1 for 'not set' or > -1.");\r
105                                 ViewState["CellPadding"] = value;\r
106                         }\r
107                 }\r
108
109                 [DefaultValue (0), Bindable (true), WebCategory ("Layout")]
110                 [WebSysDescription ("The border left between calendar days.")]\r
111                 public int CellSpacing\r
112                 {\r
113                         get\r
114                         {\r
115                                 object o = ViewState["CellSpacing"];\r
116                                 if(o!=null)\r
117                                         return (int)o;\r
118                                 return 0;\r
119                         }\r
120                         set\r
121                         {\r
122                                 if (value < -1)
123                                         throw new ArgumentOutOfRangeException ("value", "CellSpacing value has to be -1 for 'not set' or > -1.");\r
124                                 ViewState["CellSpacing"] = value;\r
125                         }\r
126                 }\r
127
128                 [NotifyParentProperty (true), WebCategory ("Style")]
129                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
130                 [PersistenceMode (PersistenceMode.InnerProperty)]
131                 [WebSysDescription ("The style applied to the day header.")]\r
132                 public TableItemStyle DayHeaderStyle\r
133                 {\r
134                         get\r
135                         {\r
136                                 if(dayHeaderStyle==null)\r
137                                         dayHeaderStyle = new TableItemStyle();\r
138                                 if(IsTrackingViewState)\r
139                                         dayHeaderStyle.TrackViewState();\r
140                                 return dayHeaderStyle;\r
141                         }\r
142                 }\r
143
144                 [DefaultValue (typeof (DayNameFormat), "Short"), Bindable (true), WebCategory ("Appearance")]
145                 [WebSysDescription ("The format for the day name display.")]\r
146                 public DayNameFormat DayNameFormat\r
147                 {\r
148                         get\r
149                         {\r
150                                 object o = ViewState["DayNameFormat"];\r
151                                 if(o!=null)\r
152                                         return (DayNameFormat)o;\r
153                                 return DayNameFormat.Short;\r
154                         }\r
155                         set\r
156                         {\r
157                                 if(!System.Enum.IsDefined(typeof(DayNameFormat),value))\r
158                                         throw new ArgumentOutOfRangeException ("value", "Only valid enumeration members are allowed");\r
159                                 ViewState["DayNameFormat"] = value;\r
160                         }\r
161                 }\r
162
163                 [DefaultValue (null)]
164                 [NotifyParentProperty (true), WebCategory ("Style")]
165                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
166                 [PersistenceMode (PersistenceMode.InnerProperty)]
167                 [WebSysDescription ("The style applied to the day entry.")]\r
168                 public TableItemStyle DayStyle\r
169                 {\r
170                         get\r
171                         {\r
172                                 if(dayStyle==null)\r
173                                         dayStyle = new TableItemStyle();\r
174                                 if(IsTrackingViewState)\r
175                                         dayStyle.TrackViewState();\r
176                                 return dayStyle;\r
177                         }\r
178                 }\r
179
180                 [DefaultValue (typeof (FirstDayOfWeek), "Default"), Bindable (true), WebCategory ("Appearance")]
181                 [WebSysDescription ("The day that a week begins with.")]\r
182                 public FirstDayOfWeek FirstDayOfWeek\r
183                 {\r
184                         get\r
185                         {\r
186                                 object o = ViewState["FirstDayOfWeek"];\r
187                                 if(o!=null)\r
188                                         return (FirstDayOfWeek)o;\r
189                                 return FirstDayOfWeek.Default;\r
190                         }\r
191                         set\r
192                         {\r
193                                 if(!System.Enum.IsDefined(typeof(FirstDayOfWeek), value))\r
194                                         throw new ArgumentOutOfRangeException ("value", "Only valid enumeration members are allowed");\r
195                                 ViewState["FirstDayOfWeek"] = value;\r
196                         }\r
197                 }\r
198
199                 [DefaultValue (">"), Bindable (true), WebCategory ("Appearance")]
200                 [WebSysDescription ("The text for selecting the next month.")]\r
201                 public string NextMonthText\r
202                 {\r
203                         get\r
204                         {\r
205                                 object o = ViewState["NextMonthText"];\r
206                                 if(o!=null)\r
207                                         return (string)o;\r
208                                 return "&gt;";\r
209                         }\r
210                         set\r
211                         {\r
212                                 ViewState["NextMonthText"] = value;\r
213                         }\r
214                 }\r
215
216                 [DefaultValue (typeof (NextPrevFormat), "CustomText"), Bindable (true), WebCategory ("Appearance")]
217                 [WebSysDescription ("The format for the month navigation.")]\r
218                 public NextPrevFormat NextPrevFormat\r
219                 {\r
220                         get\r
221                         {\r
222                                 object o = ViewState["NextPrevFormat"];\r
223                                 if(o!=null)\r
224                                         return (NextPrevFormat)o;\r
225                                 return NextPrevFormat.CustomText;\r
226                         }\r
227                         set\r
228                         {\r
229                                 if(!System.Enum.IsDefined(typeof(NextPrevFormat), value))\r
230                                         throw new ArgumentOutOfRangeException ("value", "Only valid enumeration members are allowed");\r
231                                 ViewState["NextPrevFormat"] = value;\r
232                         }\r
233                 }\r
234
235                 [NotifyParentProperty (true), WebCategory ("Style")]
236                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
237                 [PersistenceMode (PersistenceMode.InnerProperty)]
238                 [WebSysDescription ("The style applied to the month navigation.")]\r
239                 public TableItemStyle NextPrevStyle\r
240                 {\r
241                         get\r
242                         {\r
243                                 if(nextPrevStyle == null)\r
244                                         nextPrevStyle = new TableItemStyle();\r
245                                 if(IsTrackingViewState)\r
246                                         nextPrevStyle.TrackViewState();\r
247                                 return nextPrevStyle;\r
248                         }\r
249                 }\r
250
251                 [DefaultValue (null)]
252                 [NotifyParentProperty (true), WebCategory ("Style")]
253                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
254                 [PersistenceMode (PersistenceMode.InnerProperty)]
255                 [WebSysDescription ("The style applied to day entries belonging to another month.")]\r
256                 public TableItemStyle OtherMonthDayStyle\r
257                 {\r
258                         get\r
259                         {\r
260                                 if(otherMonthDayStyle == null)\r
261                                         otherMonthDayStyle = new TableItemStyle();\r
262                                 if(IsTrackingViewState)\r
263                                         otherMonthDayStyle.TrackViewState();\r
264                                 return otherMonthDayStyle;\r
265                         }\r
266                 }\r
267
268                 [DefaultValue ("<"), Bindable (true), WebCategory ("Appearance")]
269                 [WebSysDescription ("The text for selecting the previous month.")]\r
270                 public string PrevMonthText\r
271                 {\r
272                         get\r
273                         {\r
274                                 object o = ViewState["PrevMonthText"];\r
275                                 if(o!=null)\r
276                                         return (string)o;\r
277                                 return "&lt;";\r
278                         }\r
279                         set\r
280                         {\r
281                                 ViewState["PrevMonthText"] = value;\r
282                         }\r
283                 }\r
284
285                 [DefaultValue (null), Bindable (true)]
286                 [WebSysDescription ("The currently selected date.")]\r
287                 public DateTime SelectedDate\r
288                 {\r
289                         get\r
290                         {\r
291                                 if(SelectedDates.Count > 0)\r
292                                 {\r
293                                         return SelectedDates[0];\r
294                                 }\r
295                                 return DateTime.MinValue;\r
296                         }\r
297                         set\r
298                         {\r
299                                 if(value == DateTime.MinValue)\r
300                                 {\r
301                                         SelectedDates.Clear();\r
302                                 } else\r
303                                 {\r
304                                         SelectedDates.SelectRange(value, value);\r
305                                 }\r
306                         }\r
307                 }\r
308
309                 [Browsable (false), DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
310                 [WebSysDescription ("All currently selected dates.")]\r
311                 public SelectedDatesCollection SelectedDates\r
312                 {\r
313                         get\r
314                         {\r
315                                 if(selectedDates==null)\r
316                                 {\r
317                                         if(selectedDatesList == null)\r
318                                                 selectedDatesList = new ArrayList();\r
319                                         selectedDates = new SelectedDatesCollection(selectedDatesList);\r
320                                 }\r
321                                 return selectedDates;\r
322                         }\r
323                 }\r
324
325                 [DefaultValue (null)]
326                 [NotifyParentProperty (true), WebCategory ("Style")]
327                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
328                 [PersistenceMode (PersistenceMode.InnerProperty)]
329                 [WebSysDescription ("The style applied to the selected day.")]\r
330                 public TableItemStyle SelectedDayStyle\r
331                 {\r
332                         get\r
333                         {\r
334                                 if(selectedDayStyle==null)\r
335                                         selectedDayStyle = new TableItemStyle();\r
336                                 if(IsTrackingViewState)\r
337                                         selectedDayStyle.TrackViewState();\r
338                                 return selectedDayStyle;\r
339                         }\r
340                 }\r
341
342                 [DefaultValue (typeof (CalendarSelectionMode), "Day"), Bindable (true), WebCategory ("Behavior")]
343                 [WebSysDescription ("The mode in which days or other entries are selected.")]\r
344                 public CalendarSelectionMode SelectionMode\r
345                 {\r
346                         get\r
347                         {\r
348                                 object o = ViewState["SelectionMode"];\r
349                                 if(o!=null)\r
350                                         return (CalendarSelectionMode)o;\r
351                                 return CalendarSelectionMode.Day;\r
352                         }\r
353                         set\r
354                         {\r
355                                 if(!System.Enum.IsDefined(typeof(CalendarSelectionMode), value))\r
356                                         throw new ArgumentOutOfRangeException ("value", "Only valid enumeration members are allowed");\r
357                                 ViewState["SelectionMode"] = value;\r
358                         }\r
359                 }\r
360
361                 [DefaultValue (">>"), Bindable (true), WebCategory ("Appearance")]
362                 [WebSysDescription ("The text that is used for selection of months.")]\r
363                 public string SelectMonthText\r
364                 {\r
365                         get\r
366                         {\r
367                                 object o = ViewState["SelectMonthText"];\r
368                                 if(o!=null)\r
369                                         return (string)o;\r
370                                 return "&gt;&gt;";\r
371                         }\r
372                         set\r
373                         {\r
374                                 ViewState["SelectMonthText"] = value;\r
375                         }\r
376                 }\r
377
378                 [NotifyParentProperty (true), WebCategory ("Style")]
379                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
380                 [PersistenceMode (PersistenceMode.InnerProperty)]
381                 [WebSysDescription ("The style applied to the selector.")]\r
382                 public TableItemStyle SelectorStyle\r
383                 {\r
384                         get\r
385                         {\r
386                                 if(selectorStyle==null)\r
387                                         selectorStyle = new TableItemStyle();\r
388                                 return selectorStyle;\r
389                         }\r
390                 }\r
391
392                 [DefaultValue (">"), Bindable (true), WebCategory ("Appearance")]
393                 [WebSysDescription ("The text that is used for selection of weeks.")]\r
394                 public string SelectWeekText\r
395                 {\r
396                         get\r
397                         {\r
398                                 object o = ViewState["SelectWeekText"];\r
399                                 if(o!=null)\r
400                                         return (string)o;\r
401                                 return "&gt;";\r
402                         }\r
403                         set\r
404                         {\r
405                                 ViewState["SelectWeekText"] = value;\r
406                         }\r
407                 }\r
408
409                 [DefaultValue (true), Bindable (true), WebCategory ("Appearance")]
410                 [WebSysDescription ("Determines if the header for days is shown.")]\r
411                 public bool ShowDayHeader\r
412                 {\r
413                         get\r
414                         {\r
415                                 object o = ViewState["ShowDayHeader"];\r
416                                 if(o!=null)\r
417                                         return (bool)o;\r
418                                 return true;\r
419                         }\r
420                         set\r
421                         {\r
422                                 ViewState["ShowDayHeader"] = value;\r
423                         }\r
424                 }\r
425
426                 [DefaultValue (false), Bindable (true), WebCategory ("Appearance")]
427                 [WebSysDescription ("Determines if gridlines are shown.")]\r
428                 public bool ShowGridLines\r
429                 {\r
430                         get\r
431                         {\r
432                                 object o = ViewState["ShowGridLines"];\r
433                                 if(o!=null)\r
434                                         return (bool)o;\r
435                                 return false;\r
436                         }\r
437                         set\r
438                         {\r
439                                 ViewState["ShowGridLines"] = value;\r
440                         }\r
441                 }\r
442
443                 [DefaultValue (true), Bindable (true), WebCategory ("Appearance")]
444                 [WebSysDescription ("Determines if month navigation is shown.")]\r
445                 public bool ShowNextPrevMonth\r
446                 {\r
447                         get\r
448                         {\r
449                                 object o = ViewState["ShowNextPrevMonth"];\r
450                                 if(o!=null)\r
451                                         return (bool)o;\r
452                                 return true;\r
453                         }\r
454                         set\r
455                         {\r
456                                 ViewState["ShowNextPrevMonth"] = value;\r
457                         }\r
458                 }\r
459
460                 [DefaultValue (true), Bindable (true), WebCategory ("Appearance")]
461                 [WebSysDescription ("Determines if the title is shown.")]\r
462                 public bool ShowTitle\r
463                 {\r
464                         get\r
465                         {\r
466                                 object o = ViewState["ShowTitle"];\r
467                                 if(o!=null)\r
468                                         return (bool)o;\r
469                                 return true;\r
470                         }\r
471                         set\r
472                         {\r
473                                 ViewState["ShowTitle"] = value;\r
474                         }\r
475                 }\r
476
477                 [DefaultValue (typeof (TitleFormat), "MonthYear"), Bindable (true), WebCategory ("Appearance")]
478                 [WebSysDescription ("The format in which the title is rendered.")]\r
479                 public TitleFormat TitleFormat\r
480                 {\r
481                         get\r
482                         {\r
483                                 object o = ViewState["TitleFormat"];\r
484                                 if(o!=null)\r
485                                         return (TitleFormat)o;\r
486                                 return TitleFormat.MonthYear;\r
487                         }\r
488                         set\r
489                         {\r
490                                 if(!System.Enum.IsDefined(typeof(TitleFormat), value))\r
491                                         throw new ArgumentOutOfRangeException ("value", "Only valid enumeration members are allowed");\r
492                                 ViewState["TitleFormat"] = value;\r
493                         }\r
494                 }\r
495
496                 [NotifyParentProperty (true), WebCategory ("Style")]
497                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
498                 [PersistenceMode (PersistenceMode.InnerProperty)]
499                 [WebSysDescription ("The style applied to the title.")]\r
500                 public TableItemStyle TitleStyle\r
501                 {\r
502                         get\r
503                         {\r
504                                 if(titleStyle==null)\r
505                                         titleStyle = new TableItemStyle();\r
506                                 if(IsTrackingViewState)\r
507                                         titleStyle.TrackViewState();\r
508                                 return titleStyle;\r
509                         }\r
510                 }\r
511
512                 [DefaultValue (null)]
513                 [NotifyParentProperty (true), WebCategory ("Style")]
514                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
515                 [PersistenceMode (PersistenceMode.InnerProperty)]
516                 [WebSysDescription ("The style applied to the today's date display.")]\r
517                 public TableItemStyle TodayDayStyle\r
518                 {\r
519                         get\r
520                         {\r
521                                 if(todayDayStyle==null)\r
522                                         todayDayStyle = new TableItemStyle();\r
523                                 if(IsTrackingViewState)\r
524                                         todayDayStyle.TrackViewState();\r
525                                 return todayDayStyle;\r
526                         }\r
527                 }\r
528
529                 [Bindable (true), Browsable (false)]
530                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
531                 [WebSysDescription ("The current date.")]\r
532                 public DateTime TodaysDate\r
533                 {\r
534                         get\r
535                         {\r
536                                 object o = ViewState["TodaysDate"];\r
537                                 if(o!=null)\r
538                                         return (DateTime)o;\r
539                                 return DateTime.Today;\r
540                         }\r
541                         set\r
542                         {\r
543                                 ViewState["TodaysDate"] = value.Date;\r
544                         }\r
545                 }\r
546
547                 [DefaultValue (null), Bindable (true)]
548                 [WebSysDescription ("The month that is displayed.")]\r
549                 public DateTime VisibleDate\r
550                 {\r
551                         get\r
552                         {\r
553                                 object o = ViewState["VisibleDate"];\r
554                                 if(o!=null)\r
555                                         return (DateTime)o;\r
556                                 return DateTime.MinValue;\r
557                         }\r
558                         set\r
559                         {\r
560                                 ViewState["VisibleDate"] = value.Date;\r
561                         }\r
562                 }\r
563
564                 [NotifyParentProperty (true), WebCategory ("Style")]
565                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Content)]
566                 [PersistenceMode (PersistenceMode.InnerProperty)]
567                 [WebSysDescription ("The style applied to weekend days.")]\r
568                 public TableItemStyle WeekendDayStyle\r
569                 {\r
570                         get\r
571                         {\r
572                                 if(weekendDayStyle == null)\r
573                                         weekendDayStyle = new TableItemStyle();\r
574                                 if(IsTrackingViewState)\r
575                                 {\r
576                                         weekendDayStyle.TrackViewState();\r
577                                 }\r
578                                 return weekendDayStyle;\r
579                         }\r
580                 }\r
581
582                 [WebCategory ("Action")]
583                 [WebSysDescription ("Raised when a day entry is rendered.")]\r
584                 public event DayRenderEventHandler DayRender\r
585                 {\r
586                         add\r
587                         {\r
588                                 Events.AddHandler(DayRenderEvent, value);\r
589                         }\r
590                         remove\r
591                         {\r
592                                 Events.RemoveHandler(DayRenderEvent, value);\r
593                         }\r
594                 }\r
595
596                 [WebCategory ("Action")]
597                 [WebSysDescription ("Raised when another entry is selected.")]\r
598                 public event EventHandler SelectionChanged\r
599                 {\r
600                         add\r
601                         {\r
602                                 Events.AddHandler(SelectionChangedEvent, value);\r
603                         }\r
604                         remove\r
605                         {\r
606                                 Events.RemoveHandler(SelectionChangedEvent, value);\r
607                         }\r
608                 }\r
609
610                 [WebCategory ("Action")]
611                 [WebSysDescription ("Raised when a the currently visible month has changed.")]\r
612                 public event MonthChangedEventHandler VisibleMonthChanged\r
613                 {\r
614                         add\r
615                         {\r
616                                 Events.AddHandler(VisibleMonthChangedEvent, value);\r
617                         }\r
618                         remove\r
619                         {\r
620                                 Events.RemoveHandler(VisibleMonthChangedEvent, value);\r
621                         }\r
622                 }\r
623 \r
624                 protected virtual void OnDayRender(TableCell cell, CalendarDay day)\r
625                 {\r
626                         if(Events!=null)\r
627                         {\r
628                                 DayRenderEventHandler dreh = (DayRenderEventHandler)(Events[DayRenderEvent]);\r
629                                 if(dreh!=null)\r
630                                         dreh(this, new DayRenderEventArgs(cell, day));\r
631                         }\r
632                 }\r
633 \r
634                 protected virtual void OnSelectionChanged()\r
635                 {\r
636                         if(Events!=null)\r
637                         {\r
638                                 EventHandler eh = (EventHandler)(Events[SelectionChangedEvent]);\r
639                                 if(eh!=null)\r
640                                         eh(this, new EventArgs());\r
641                         }\r
642                 }\r
643 \r
644                 protected virtual void OnVisibleMonthChanged(DateTime newDate, DateTime prevDate)\r
645                 {\r
646                         if(Events!=null)\r
647                         {\r
648                                 MonthChangedEventHandler mceh = (MonthChangedEventHandler)(Events[VisibleMonthChangedEvent]);\r
649                                 if(mceh!=null)\r
650                                         mceh(this, new MonthChangedEventArgs(newDate, prevDate));\r
651                         }\r
652                 }\r
653 \r
654                 /// <remarks>\r
655                 /// See test6.aspx in Tests directory for verification\r
656                 /// </remarks>\r
657                 void IPostBackEventHandler.RaisePostBackEvent(string eventArgument)\r
658                 {\r
659                         // initialize the calendar...TODO: find out why this isn't done in the constructor
660                         // if the culture is changed between rendering and postback this will be broken
661                         globCal = DateTimeFormatInfo.CurrentInfo.Calendar;\r
662
663                         // TODO: Find out what kind of exceptions to throw when we get bad data
664                         if (eventArgument.StartsWith ("V")) {
665                                 TimeSpan mod = new TimeSpan (Int32.Parse (eventArgument.Substring (1)), 0, 0, 0);
666                                 DateTime new_date = begin_date + mod;
667                                 VisibleDate = new_date;
668                                 OnVisibleMonthChanged (VisibleDate, new_date);
669                         } else if (eventArgument.StartsWith ("R")) {
670                                 TimeSpan mod = new TimeSpan (Int32.Parse (eventArgument.Substring (1,
671                                                                                           eventArgument.Length - 3)), 0, 0, 0);
672                                 DateTime range_begin = begin_date + mod;
673                                 int sel_days = Int32.Parse (eventArgument.Substring (eventArgument.Length - 2));
674                                 SelectRangeInternal (range_begin, range_begin.AddDays (sel_days - 1), GetEffectiveVisibleDate ());
675                         } else {
676                                 TimeSpan mod = new TimeSpan (Int32.Parse (eventArgument), 0, 0, 0);
677                                 DateTime day = begin_date + mod;
678                                 SelectRangeInternal (day, day, GetEffectiveVisibleDate ());
679                         }\r
680                 }\r
681 \r
682                 protected override void OnPreRender (EventArgs e)
683                 {
684                         base.OnPreRender (e);
685                 }
686
687                 protected override void Render(HtmlTextWriter writer)\r
688                 {\r
689                         globCal = DateTimeFormatInfo.CurrentInfo.Calendar;\r
690                         DateTime visDate   = GetEffectiveVisibleDate();\r
691                         DateTime firstDate = GetFirstCalendarDay(visDate);\r
692 \r
693                         bool isEnabled;\r
694                         bool isHtmlTextWriter;\r
695                         //FIXME: when Control.Site works, reactivate this\r
696                         //if (Page == null || Site == null) {\r
697                         //      isEnabled = false;\r
698                         //      isHtmlTextWriter = false;\r
699                         //} else {\r
700                                 isEnabled = Enabled;\r
701                                 isHtmlTextWriter = (writer.GetType() != typeof(HtmlTextWriter));\r
702                         //}\r
703                         defaultTextColor = ForeColor;\r
704                         if(defaultTextColor == Color.Empty)\r
705                                 defaultTextColor = Color.Black;\r
706 \r
707                         Table calTable = new Table ();\r
708                         calTable.ID = ID;\r
709                         calTable.CopyBaseAttributes(this);\r
710                         if(ControlStyleCreated)\r
711                                 calTable.ApplyStyle(ControlStyle);\r
712                         calTable.Width = Width;\r
713                         calTable.Height = Height;\r
714                         calTable.CellSpacing = CellSpacing;\r
715                         calTable.CellPadding = CellPadding;\r
716 \r
717                         if (ControlStyleCreated &&\r
718                             ControlStyle.IsSet (WebControls.Style.BORDERWIDTH) &&\r
719                             BorderWidth != Unit.Empty)\r
720                                 calTable.BorderWidth = BorderWidth;\r
721                         else\r
722                                 calTable.BorderWidth = Unit.Pixel(1);\r
723 \r
724                         if (ShowGridLines)\r
725                                 calTable.GridLines = GridLines.Both;\r
726                         else\r
727                                 calTable.GridLines = GridLines.None;\r
728 \r
729                         calTable.RenderBeginTag (writer);\r
730 \r
731                         if (ShowTitle)\r
732                                 RenderTitle (writer, visDate, SelectionMode, isEnabled);\r
733 \r
734                         if (ShowDayHeader)\r
735                                 RenderHeader (writer, firstDate, SelectionMode, isEnabled, isHtmlTextWriter);\r
736 \r
737                         RenderAllDays (writer, firstDate, visDate, SelectionMode, isEnabled, isHtmlTextWriter);\r
738 \r
739                         calTable.RenderEndTag(writer);\r
740                 }\r
741 \r
742                 protected override ControlCollection CreateControlCollection()\r
743                 {\r
744                         return new EmptyControlCollection(this);\r
745                 }\r
746 \r
747                 protected override void LoadViewState(object savedState)\r
748                 {\r
749                         if (savedState!=null) {\r
750                                 object[] states = (object[]) savedState;\r
751                                 if(states[0] != null)\r
752                                         base.LoadViewState(states[0]);\r
753                                 if(states[1] != null)\r
754                                         DayHeaderStyle.LoadViewState(states[1]);\r
755                                 if(states[2] != null)\r
756                                         DayStyle.LoadViewState(states[2]);\r
757                                 if(states[3] != null)\r
758                                         NextPrevStyle.LoadViewState(states[3]);\r
759                                 if(states[4] != null)\r
760                                         OtherMonthDayStyle.LoadViewState(states[4]);\r
761                                 if(states[5] != null)\r
762                                         SelectedDayStyle.LoadViewState(states[5]);\r
763                                 if(states[6] != null)\r
764                                         SelectorStyle.LoadViewState(states[6]);\r
765                                 if(states[7] != null)\r
766                                         TitleStyle.LoadViewState(states[7]);\r
767                                 if(states[8] != null)\r
768                                         TodayDayStyle.LoadViewState(states[8]);\r
769                                 if(states[9] != null)\r
770                                         WeekendDayStyle.LoadViewState(states[9]);\r
771 \r
772                                 ArrayList dateList = ViewState ["_CalendarSelectedDates"] as ArrayList;\r
773                                 if (dateList != null)\r
774                                         selectedDates = new SelectedDatesCollection (dateList);\r
775                         }\r
776                 }\r
777 \r
778                 protected override object SaveViewState()\r
779                 {
780                         if (SelectedDates.Count > 0)\r
781                                 ViewState["_CalendarSelectedDates"] = selectedDates.GetDateList ();
782                         \r
783                         object[] states = new object [10];\r
784                         states[0] = base.SaveViewState();\r
785                         states[1] = (dayHeaderStyle == null ? null : dayHeaderStyle.SaveViewState());\r
786                         states[2] = (dayStyle == null ? null : dayStyle.SaveViewState());\r
787                         states[3] = (nextPrevStyle == null ? null : nextPrevStyle.SaveViewState());\r
788                         states[4] = (otherMonthDayStyle == null ? null : otherMonthDayStyle.SaveViewState());\r
789                         states[5] = (selectedDayStyle == null ? null : selectedDayStyle.SaveViewState());\r
790                         states[6] = (selectorStyle == null ? null : selectorStyle.SaveViewState());\r
791                         states[7] = (titleStyle == null ? null : titleStyle.SaveViewState());\r
792                         states[8] = (todayDayStyle == null ? null : todayDayStyle.SaveViewState());\r
793                         states[9] = (weekendDayStyle == null ? null : weekendDayStyle.SaveViewState());\r
794                         for(int i=0; i < states.Length; i++)\r
795                         {\r
796                                 if(states[i]!=null)\r
797                                         return states;\r
798                         }\r
799                         return null;\r
800                 }\r
801 \r
802                 protected override void TrackViewState()\r
803                 {\r
804                         base.TrackViewState();\r
805                         if(titleStyle!=null)\r
806                         {\r
807                                 titleStyle.TrackViewState();\r
808                         }\r
809                         if(nextPrevStyle!=null)\r
810                         {\r
811                                 nextPrevStyle.TrackViewState();\r
812                         }\r
813                         if(dayStyle!=null)\r
814                         {\r
815                                 dayStyle.TrackViewState();\r
816                         }\r
817                         if(dayHeaderStyle!=null)\r
818                         {\r
819                                 dayHeaderStyle.TrackViewState();\r
820                         }\r
821                         if(todayDayStyle!=null)\r
822                         {\r
823                                 todayDayStyle.TrackViewState();\r
824                         }\r
825                         if(weekendDayStyle!=null)\r
826                         {\r
827                                 weekendDayStyle.TrackViewState();\r
828                         }\r
829                         if(otherMonthDayStyle!=null)\r
830                         {\r
831                                 otherMonthDayStyle.TrackViewState();\r
832                         }\r
833                         if(selectedDayStyle!=null)\r
834                         {\r
835                                 selectedDayStyle.TrackViewState();\r
836                         }\r
837                         if(selectorStyle!=null)\r
838                         {\r
839                                 selectorStyle.TrackViewState();\r
840                         }\r
841                 }\r
842 \r
843                 private void RenderAllDays (HtmlTextWriter writer,\r
844                                             DateTime firstDay,\r
845                                             DateTime activeDate,\r
846                                             CalendarSelectionMode mode,\r
847                                             bool isActive,\r
848                                             bool isDownLevel)\r
849                 {\r
850                         TableItemStyle weeksStyle = null;
851                         TableCell weeksCell = new TableCell ();\r
852                         TableItemStyle weekendStyle = WeekendDayStyle;\r
853                         TableItemStyle otherMonthStyle = OtherMonthDayStyle;\r
854                         Unit size;\r
855                         bool isWeekMode = (mode == CalendarSelectionMode.DayWeek ||\r
856                                            mode == CalendarSelectionMode.DayWeekMonth);\r
857 \r
858                         if (isWeekMode) {\r
859                                 weeksStyle = new TableItemStyle ();\r
860                                 weeksStyle.Width = Unit.Percentage (12);\r
861                                 weeksStyle.HorizontalAlign = HorizontalAlign.Center;\r
862                                 weeksStyle.CopyFrom (SelectorStyle);\r
863                                 size = Unit.Percentage (12);\r
864                         } else {\r
865                                 size = Unit.Percentage (14);\r
866                         }\r
867 \r
868                         TableItemStyle [] styles = new TableItemStyle [32];\r
869                         int definedStyles = MASK_SELECTED;\r
870                         if (weekendStyle != null && !weekendStyle.IsEmpty)\r
871                                 definedStyles |= MASK_WEEKEND;\r
872                         if (otherMonthStyle != null && !otherMonthStyle.IsEmpty)\r
873                                 definedStyles |= MASK_OMONTH;\r
874                         if (todayDayStyle != null && !todayDayStyle.IsEmpty)\r
875                                 definedStyles |= MASK_TODAY;\r
876                         if (dayStyle != null && !dayStyle.IsEmpty)\r
877                                 definedStyles |= MASK_DAY;\r
878 \r
879                         int month = globCal.GetMonth (activeDate);\r
880                         DateTime currentDay = firstDay;\r
881                         int begin = (int) (firstDay - begin_date).TotalDays;
882                         for (int crr = 0; crr < 6; crr++) {\r
883                                 writer.Write ("<tr>");\r
884                                 if (isWeekMode) {\r
885                                         int week_offset = begin + crr * 7;
886                                         string cellText = GetCalendarLinkText (\r
887                                                                 "R" + week_offset + "07",\r
888                                                                 SelectWeekText, \r
889                                                                 weeksCell.ForeColor,\r
890                                                                 isActive);\r
891 \r
892                                         weeksCell.Text = cellText;\r
893                                         weeksCell.ApplyStyle (weeksStyle);
894                                         RenderCalendarCell (writer, weeksCell, cellText);\r
895                                 }\r
896 \r
897                                 for (int weekDay = 0; weekDay < 7; weekDay++) {\r
898                                         string dayString = currentDay.Day.ToString ();\r
899                                         DayOfWeek dow = currentDay.DayOfWeek;
900                                         CalendarDay calDay =\r
901                                                 new CalendarDay (\r
902                                                                 currentDay,\r
903                                                                 dow == DayOfWeek.Sunday ||
904                                                                 dow == DayOfWeek.Saturday,
905                                                                 currentDay == TodaysDate, \r
906                                                                 SelectedDates.Contains (currentDay),\r
907                                                                 globCal.GetMonth (currentDay) != month,\r
908                                                                 dayString\r
909                                                                 );\r
910 \r
911 \r
912                                         int dayStyles = GetMask (calDay) & definedStyles;\r
913                                         TableItemStyle currentDayStyle = styles [dayStyles];\r
914                                         if (currentDayStyle == null) {\r
915                                                 currentDayStyle = new TableItemStyle ();\r
916                                                 if ((dayStyles & MASK_DAY) != 0)\r
917                                                         currentDayStyle.CopyFrom (DayStyle);\r
918 \r
919                                                 if ((dayStyles & MASK_WEEKEND) != 0)\r
920                                                         currentDayStyle.CopyFrom (WeekendDayStyle);\r
921 \r
922                                                 if ((dayStyles & MASK_TODAY) != 0)\r
923                                                         currentDayStyle.CopyFrom (TodayDayStyle);\r
924 \r
925                                                 if ((dayStyles & MASK_OMONTH) != 0)\r
926                                                         currentDayStyle.CopyFrom (OtherMonthDayStyle);\r
927 \r
928                                                 if ((dayStyles & MASK_SELECTED) != 0) {\r
929                                                         currentDayStyle.ForeColor = Color.White;\r
930                                                         currentDayStyle.BackColor = Color.Silver;\r
931                                                         currentDayStyle.CopyFrom (SelectedDayStyle);\r
932                                                 }\r
933 \r
934                                                 currentDayStyle.Width = size;\r
935                                                 currentDayStyle.HorizontalAlign = HorizontalAlign.Center;\r
936                                         }\r
937 \r
938                                         TableCell dayCell = new TableCell ();
939                                         dayCell.ApplyStyle (currentDayStyle);
940                                         dayCell.Controls.Add (new LiteralControl (dayString));
941                                         calDay.IsSelectable = isActive;
942                                         if (calDay.IsSelectable)
943                                                 dayCell.Text = GetCalendarLinkText (
944                                                                         (begin + (crr * 7 + weekDay)).ToString (),
945                                                                         dayString,
946                                                                         dayCell.ForeColor,
947                                                                         isActive);
948
949                                         OnDayRender (dayCell, calDay);
950                                         dayCell.RenderControl (writer);
951
952                                         currentDay = globCal.AddDays (currentDay, 1);\r
953                                 }\r
954                                 writer.Write("</tr>");\r
955                         }\r
956                 }\r
957 \r
958                 private int GetMask (CalendarDay day)\r
959                 {\r
960                         int retVal = MASK_DAY;\r
961                         if(day.IsSelected)\r
962                                 retVal |= MASK_SELECTED;\r
963                         if(day.IsToday)\r
964                                 retVal |= MASK_TODAY;\r
965                         if(day.IsOtherMonth)\r
966                                 retVal |= MASK_OMONTH;\r
967                         if(day.IsWeekend)\r
968                                 retVal |= MASK_WEEKEND;\r
969                         return retVal;\r
970                 }\r
971 \r
972                 /// <remarks>\r
973                 /// Refers to the second line of the calendar, that contains a link\r
974                 /// to select whole month, and weekdays as defined by DayNameFormat\r
975                 /// </remarks>\r
976                 private void RenderHeader (HtmlTextWriter writer,\r
977                                            DateTime firstDay,\r
978                                            CalendarSelectionMode mode,\r
979                                            bool isActive,\r
980                                            bool isDownLevel)\r
981                 {\r
982                         writer.Write("<tr>");\r
983                         bool isWeekMode = (mode == CalendarSelectionMode.DayWeek ||\r
984                                            mode == CalendarSelectionMode.DayWeekMonth);\r
985 \r
986                         TableCell headerCell = new TableCell ();\r
987                         headerCell.HorizontalAlign = HorizontalAlign.Center;\r
988                         string selMthText = String.Empty;\r
989                         if (isWeekMode) {\r
990                                 if (mode == CalendarSelectionMode.DayWeekMonth) {\r
991                                         DateTime visDate = GetEffectiveVisibleDate ();
992                                         DateTime sel_month = new DateTime (visDate.Year, visDate.Month, 1);
993                                         int month_offset = (int) (sel_month - begin_date).TotalDays;
994                                         headerCell.ApplyStyle (SelectorStyle);\r
995                                         selMthText = GetCalendarLinkText ("R" + month_offset +
996                                                         globCal.GetDaysInMonth (sel_month.Year,
997                                                                         sel_month.Month).ToString ("d2"), // maybe there are calendars with less then 10 days in a month
998                                                                           SelectMonthText,\r
999                                                                           SelectorStyle.ForeColor,\r
1000                                                                           isActive);\r
1001                                 } else {\r
1002                                         headerCell.ApplyStyle (DayHeaderStyle);\r
1003                                         selMthText = String.Empty;\r
1004                                 }\r
1005                                 RenderCalendarCell (writer, headerCell, selMthText);\r
1006                         }\r
1007 \r
1008                         TableCell dayHeaderCell = new TableCell ();\r
1009                         dayHeaderCell.HorizontalAlign = HorizontalAlign.Center;\r
1010                         dayHeaderCell.ApplyStyle (dayHeaderStyle);
1011 \r
1012                         int dayOfWeek = (int) globCal.GetDayOfWeek (firstDay);\r
1013                         DateTimeFormatInfo currDTInfo = DateTimeFormatInfo.CurrentInfo;\r
1014                         for(int currDay = dayOfWeek; currDay < dayOfWeek + 7; currDay++) {\r
1015                                 DayOfWeek effDay = (DayOfWeek) Enum.ToObject (typeof (DayOfWeek), currDay % 7);\r
1016                                 string currDayContent;\r
1017                                 switch(DayNameFormat) {\r
1018                                 case DayNameFormat.Full:\r
1019                                         currDayContent = currDTInfo.GetDayName (effDay);\r
1020                                         break;\r
1021                                 case DayNameFormat.FirstLetter:\r
1022                                         currDayContent = currDTInfo.GetDayName (effDay).Substring (0,1);\r
1023                                         break;\r
1024                                 case DayNameFormat.FirstTwoLetters:\r
1025                                         currDayContent = currDTInfo.GetDayName (effDay).Substring (0,2);\r
1026                                         break;\r
1027                                 case DayNameFormat.Short:\r
1028                                         goto default;\r
1029                                 default:\r
1030                                         currDayContent = currDTInfo.GetAbbreviatedDayName (effDay);\r
1031                                         break;\r
1032                                 }\r
1033 \r
1034                                 RenderCalendarCell(writer, dayHeaderCell, currDayContent);\r
1035                         }\r
1036                         writer.Write ("</tr>");\r
1037                 }\r
1038 \r
1039                 private void RenderTitle (HtmlTextWriter writer,\r
1040                                           DateTime visibleDate,\r
1041                                           CalendarSelectionMode mode,\r
1042                                           bool isActive)\r
1043                 {\r
1044                         writer.Write("<tr>");\r
1045                         Table innerTable = new Table ();\r
1046                         TableCell titleCell = new TableCell();\r
1047                         bool isWeekMode = (mode == CalendarSelectionMode.DayWeek ||\r
1048                                            mode == CalendarSelectionMode.DayWeekMonth);\r
1049 \r
1050                         titleCell.ColumnSpan = (isWeekMode ? 8 : 7);\r
1051                         titleCell.BackColor = Color.Silver;\r
1052 \r
1053                         innerTable.GridLines = GridLines.None;\r
1054                         innerTable.Width = Unit.Percentage (100);\r
1055                         innerTable.CellSpacing = 0;\r
1056                         ApplyTitleStyle (innerTable, titleCell, TitleStyle);\r
1057 \r
1058                         titleCell.RenderBeginTag (writer);\r
1059                         innerTable.RenderBeginTag (writer);\r
1060 \r
1061                         writer.Write ("<tr>");\r
1062                         string prevContent = String.Empty;\r
1063                         if (ShowNextPrevMonth) {\r
1064                                 TableCell prevCell = new TableCell ();\r
1065                                 prevCell.Width = Unit.Percentage (15);\r
1066                                 prevCell.HorizontalAlign = HorizontalAlign.Left;\r
1067                                 if (NextPrevFormat == NextPrevFormat.CustomText) {\r
1068                                         prevContent = PrevMonthText;\r
1069                                 } else {\r
1070                                         int pMthInt = globCal.GetMonth(globCal.AddMonths (visibleDate, -1));\r
1071                                         if (NextPrevFormat == NextPrevFormat.FullMonth)\r
1072                                                 prevContent = infoCal.GetMonthName (pMthInt);\r
1073                                         else\r
1074                                                 prevContent = infoCal.GetAbbreviatedMonthName (pMthInt);\r
1075                                 }\r
1076                                 DateTime prev_month = visibleDate.AddMonths (-1);
1077                                 int prev_offset = (int) (new DateTime (prev_month.Year,
1078                                                                           prev_month.Month, 1) - begin_date).TotalDays;
1079                                 prevCell.ApplyStyle (NextPrevStyle);\r
1080                                 RenderCalendarCell (writer,\r
1081                                                     prevCell,\r
1082                                                     GetCalendarLinkText ("V" + prev_offset,\r
1083                                                                          prevContent,\r
1084                                                                          NextPrevStyle.ForeColor,\r
1085                                                                          isActive)\r
1086                                                     );\r
1087                         }\r
1088 \r
1089                         TableCell currCell = new TableCell ();\r
1090                         currCell.Width = Unit.Percentage (70);\r
1091                         if (TitleStyle.HorizontalAlign == HorizontalAlign.NotSet)\r
1092                                 currCell.HorizontalAlign = HorizontalAlign.Center;\r
1093                         else\r
1094                                 currCell.HorizontalAlign = TitleStyle.HorizontalAlign;\r
1095 \r
1096                         currCell.Wrap = TitleStyle.Wrap;\r
1097                         string currMonthContent = String.Empty;\r
1098                         if (TitleFormat == TitleFormat.Month) {\r
1099                                 currMonthContent = visibleDate.ToString ("MMMM");\r
1100                         } else {\r
1101                                 string cmcFmt = infoCal.YearMonthPattern;\r
1102                                 if (cmcFmt.IndexOf (',') >= 0)\r
1103                                         cmcFmt = "MMMM yyyy";\r
1104 \r
1105                                 currMonthContent = visibleDate.ToString (cmcFmt);\r
1106                         }\r
1107 \r
1108                         RenderCalendarCell (writer, currCell, currMonthContent);\r
1109                                                                  \r
1110                         string nextContent = String.Empty;\r
1111                         if (ShowNextPrevMonth) {\r
1112                                 TableCell nextCell = new TableCell ();\r
1113                                 nextCell.Width = Unit.Percentage(15);\r
1114                                 nextCell.HorizontalAlign = HorizontalAlign.Right;\r
1115                                 if (NextPrevFormat == NextPrevFormat.CustomText) {\r
1116                                         nextContent = NextMonthText;\r
1117                                 } else {\r
1118                                         int nMthInt = globCal.GetMonth (globCal.AddMonths (visibleDate, 1));\r
1119                                         if(NextPrevFormat == NextPrevFormat.FullMonth)\r
1120                                                 nextContent = infoCal.GetMonthName(nMthInt);\r
1121                                         else\r
1122                                                 nextContent = infoCal.GetAbbreviatedMonthName(nMthInt);\r
1123                                 }\r
1124                                 DateTime next_month = visibleDate.AddMonths (1);
1125                                 int next_offset = (int) (new DateTime (next_month.Year,
1126                                                                           next_month.Month, 1) - begin_date).TotalDays;
1127                                 nextCell.ApplyStyle(NextPrevStyle);\r
1128                                 RenderCalendarCell (writer,\r
1129                                                     nextCell,\r
1130                                                     GetCalendarLinkText ("V" + next_offset,\r
1131                                                                          nextContent,\r
1132                                                                          NextPrevStyle.ForeColor,\r
1133                                                                          isActive)\r
1134                                                     );\r
1135                         }\r
1136 \r
1137                         writer.Write("</tr>");\r
1138                         innerTable.RenderEndTag(writer);\r
1139                         titleCell.RenderEndTag(writer);\r
1140 \r
1141                         writer.Write("</tr>");\r
1142                 }\r
1143 \r
1144                 private void ApplyTitleStyle(Table table, TableCell cell, TableItemStyle style)\r
1145                 {\r
1146                         if(style.BackColor != Color.Empty)\r
1147                         {\r
1148                                 cell.BackColor = style.BackColor;\r
1149                         }\r
1150                         if(style.BorderStyle != BorderStyle.NotSet)\r
1151                         {\r
1152                                 cell.BorderStyle = style.BorderStyle;\r
1153                         }\r
1154                         if(style.BorderColor != Color.Empty)\r
1155                         {\r
1156                                 cell.BorderColor = style.BorderColor;\r
1157                         }\r
1158                         if(style.BorderWidth != Unit.Empty)\r
1159                         {\r
1160                                 cell.BorderWidth = style.BorderWidth;\r
1161                         }\r
1162                         if(style.Height != Unit.Empty)\r
1163                         {\r
1164                                 cell.Height = style.Height;\r
1165                         }\r
1166                         if(style.VerticalAlign != VerticalAlign.NotSet)\r
1167                         {\r
1168                                 cell.VerticalAlign = style.VerticalAlign;\r
1169                         }\r
1170 \r
1171                         if(style.ForeColor != Color.Empty)\r
1172                         {\r
1173                                 table.ForeColor = style.ForeColor;\r
1174                         } else if(ForeColor != Color.Empty)\r
1175                         {\r
1176                                 table.ForeColor = ForeColor;\r
1177                         }\r
1178
1179                         if (style.CssClass != "") {
1180                                 cell.CssClass = style.CssClass;
1181                         }
1182 \r
1183                         table.Font.CopyFrom(style.Font);\r
1184                         table.Font.MergeWith(Font);\r
1185                 }\r
1186 \r
1187                 private void RenderCalendarCell (HtmlTextWriter writer, TableCell cell, string text)\r
1188                 {\r
1189                         cell.RenderBeginTag(writer);\r
1190                         writer.Write(text);\r
1191                         cell.RenderEndTag(writer);\r
1192                 }\r
1193 \r
1194                 private DateTime GetFirstCalendarDay(DateTime visibleDate)\r
1195                 {\r
1196                         int fow = (int) FirstDayOfWeek;\r
1197                         if (fow == 7)\r
1198                                 fow = (int) infoCal.FirstDayOfWeek;\r
1199 \r
1200                         int days = (int) globCal.GetDayOfWeek (visibleDate) - fow;\r
1201                         if (days <= 0)\r
1202                                 days += 7;\r
1203                         return globCal.AddDays (visibleDate, -days);\r
1204                 }\r
1205 \r
1206                 private DateTime GetEffectiveVisibleDate()\r
1207                 {\r
1208                         DateTime dt = VisibleDate;\r
1209                         if (VisibleDate == DateTime.MinValue)\r
1210                                  dt = TodaysDate;\r
1211 \r
1212                         return globCal.AddDays (dt, 1 - globCal.GetDayOfMonth (dt));\r
1213                 }\r
1214 \r
1215                 /// <summary>\r
1216                 /// Creates text to be displayed, with all attributes if to be\r
1217                 /// shown as a hyperlink\r
1218                 /// </summary>\r
1219                 private string GetCalendarLinkText (string eventArg,\r
1220                                                     string text,\r
1221                                                     Color foreground,\r
1222                                                     bool isLink)\r
1223                 {\r
1224                         if (isLink) {\r
1225                                 StringBuilder dispVal = new StringBuilder ();\r
1226                                 dispVal.Append ("<a href=\"");\r
1227                                 dispVal.Append (Page.GetPostBackClientHyperlink (this, eventArg));\r
1228                                 dispVal.Append ("\" style=\"color: ");\r
1229                                 if (foreground.IsEmpty) {\r
1230                                         dispVal.Append (ColorTranslator.ToHtml (defaultTextColor));\r
1231                                 } else {\r
1232                                         dispVal.Append (ColorTranslator.ToHtml (foreground));\r
1233                                 }\r
1234                                 dispVal.Append ("\">");\r
1235                                 dispVal.Append (text);\r
1236                                 dispVal.Append ("</a>");\r
1237                                 return dispVal.ToString ();\r
1238                         }\r
1239                         return text;\r
1240                 }\r
1241 \r
1242                 private string GetHtmlForCell (TableCell cell, bool showLinks)\r
1243                 {\r
1244                         StringWriter sw = new StringWriter ();\r
1245                         HtmlTextWriter htw = new HtmlTextWriter (sw);\r
1246                         cell.RenderBeginTag (htw);\r
1247                         if(showLinks) {\r
1248                                 htw.Write (GetCalendarLinkText ("{0}", "{1}", cell.ForeColor, showLinks));\r
1249                         } else {\r
1250                                 htw.Write ("{0}");\r
1251                         }\r
1252                         cell.RenderEndTag (htw);\r
1253                         return sw.ToString();\r
1254                 }\r
1255 \r
1256                 internal void SelectRangeInternal (DateTime fromDate, DateTime toDate, DateTime visibleDate)\r
1257                 {\r
1258                         TimeSpan span = toDate - fromDate;\r
1259                         if (SelectedDates.Count != span.Days + 1 || \r
1260                             SelectedDates [0] != fromDate || \r
1261                             SelectedDates [SelectedDates.Count - 1] != toDate) {\r
1262                                 SelectedDates.SelectRange (fromDate, toDate);\r
1263                                 OnSelectionChanged ();\r
1264                         }\r
1265                 }\r
1266
1267                 protected bool HasWeekSelectors (CalendarSelectionMode selectionMode)
1268                 {
1269                         return selectionMode == CalendarSelectionMode.DayWeek ||
1270                                 selectionMode == CalendarSelectionMode.DayWeekMonth;
1271                 }
1272         }\r
1273 }\r