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