calculate AppRelativeTemplateSourceDirectory from HttpContext when control is not...
[mono.git] / mcs / class / System.Web / System.Web.UI / Control.cs
1 //
2 // System.Web.UI.Control.cs
3 //
4 // Authors:
5 //   Bob Smith <bob@thestuff.net>
6 //   Gonzalo Paniagua Javier (gonzalo@ximian.com
7 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
8 //   Sanjay Gupta (gsanjay@novell.com)
9 //
10 // (C) Bob Smith
11 // (c) 2002,2003 Ximian, Inc. (http://www.ximian.com)
12 // (C) 2004 Novell, Inc. (http://www.novell.com)
13 //
14
15 //
16 // Permission is hereby granted, free of charge, to any person obtaining
17 // a copy of this software and associated documentation files (the
18 // "Software"), to deal in the Software without restriction, including
19 // without limitation the rights to use, copy, modify, merge, publish,
20 // distribute, sublicense, and/or sell copies of the Software, and to
21 // permit persons to whom the Software is furnished to do so, subject to
22 // the following conditions:
23 // 
24 // The above copyright notice and this permission notice shall be
25 // included in all copies or substantial portions of the Software.
26 // 
27 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
30 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
31 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
32 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
33 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 //
35
36 // This will provide extra information when trace is enabled. Might be too verbose.
37 #define MONO_TRACE
38
39 using System.Collections;
40 using System.ComponentModel;
41 using System.ComponentModel.Design;
42 using System.ComponentModel.Design.Serialization;
43 using System.Security.Permissions;
44 using System.Web;
45 using System.Web.Util;
46 using System.Globalization;
47 #if NET_2_0
48 using System.Web.UI.Adapters;
49 using System.IO;
50 #endif
51
52 namespace System.Web.UI
53 {
54         // CAS
55         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
56         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
57         // attributes
58         [DefaultProperty ("ID"), DesignerCategory ("Code"), ToolboxItemFilter ("System.Web.UI", ToolboxItemFilterType.Require)]
59         [ToolboxItem ("System.Web.UI.Design.WebControlToolboxItem, " + Consts.AssemblySystem_Design)]
60         [Designer ("System.Web.UI.Design.ControlDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
61 #if NET_2_0
62         [DesignerSerializer ("Microsoft.VisualStudio.Web.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VisualStudio_Web,
63                                 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
64         [Bindable (true)]
65         [Themeable (false)]
66 #else
67         [DesignerSerializer ("Microsoft.VSDesigner.WebForms.ControlCodeDomSerializer, " + Consts.AssemblyMicrosoft_VSDesigner,
68                                 "System.ComponentModel.Design.Serialization.CodeDomSerializer, " + Consts.AssemblySystem_Design)]
69 #endif          
70         public partial class Control : IComponent, IDisposable, IParserAccessor, IDataBindingsAccessor
71 #if NET_2_0
72         , IUrlResolutionService, IControlBuilderAccessor, IControlDesignerAccessor, IExpressionsAccessor
73 #endif
74         {
75                 static readonly object DataBindingEvent = new object();
76                 static readonly object DisposedEvent = new object();
77                 static readonly object InitEvent = new object();
78                 static readonly object LoadEvent = new object();
79                 static readonly object PreRenderEvent = new object();
80                 static readonly object UnloadEvent = new object();
81                 static string[] defaultNameArray;
82                 /* */
83                 int event_mask;
84                 const int databinding_mask = 1;
85                 const int disposed_mask = 1 << 1;
86                 const int init_mask = 1 << 2;
87                 const int load_mask = 1 << 3;
88                 const int prerender_mask = 1 << 4;
89                 const int unload_mask = 1 << 5;
90                 /* */
91
92                 string uniqueID;
93                 string _userId;
94                 ControlCollection _controls;
95                 Control _namingContainer;
96                 Page _page;
97                 Control _parent;
98                 ISite _site;
99                 HttpContext _context;
100                 StateBag _viewState;
101                 EventHandlerList _events;
102                 RenderMethod _renderMethodDelegate;
103                 int defaultNumberID;
104  
105                 DataBindingCollection dataBindings;
106                 Hashtable pendingVS; // may hold unused viewstate data from child controls
107                 
108
109 #if NET_2_0
110                 TemplateControl _templateControl;
111                 bool _isChildControlStateCleared;
112 #endif
113                 string _templateSourceDirectory;
114                 
115                 /*************/
116                 int stateMask;
117                 const int ENABLE_VIEWSTATE      = 1;
118                 const int VISIBLE               = 1 << 1;
119                 const int AUTOID                = 1 << 2;
120                 const int CREATING_CONTROLS     = 1 << 3;
121                 const int BINDING_CONTAINER     = 1 << 4;
122                 const int AUTO_EVENT_WIREUP     = 1 << 5;
123                 const int IS_NAMING_CONTAINER   = 1 << 6;
124                 const int VISIBLE_CHANGED       = 1 << 7;
125                 const int TRACK_VIEWSTATE       = 1 << 8;
126                 const int CHILD_CONTROLS_CREATED = 1 << 9;
127                 const int ID_SET                = 1 << 10;
128                 const int INITED                = 1 << 11;
129                 const int INITING               = 1 << 12;
130                 const int VIEWSTATE_LOADED      = 1 << 13;
131                 const int LOADED                = 1 << 14;
132                 const int PRERENDERED           = 1 << 15;
133 #if NET_2_0
134                 const int ENABLE_THEMING        = 1 << 16;
135 #endif
136                 /*************/
137                 
138                 static Control ()
139                 {
140                         defaultNameArray = new string [100];
141                         for (int i = 0 ; i < 100 ; i++)
142 #if NET_2_0
143                                 defaultNameArray [i] = String.Format("ctl{0:D2}", i);
144 #else
145                                 defaultNameArray [i] = "_ctl" + i;
146 #endif
147                 }
148
149                 public Control()
150                 {
151                         stateMask = ENABLE_VIEWSTATE | VISIBLE | AUTOID | BINDING_CONTAINER | AUTO_EVENT_WIREUP;
152                         if (this is INamingContainer)
153                                 stateMask |= IS_NAMING_CONTAINER;
154                 }
155
156 #if NET_2_0
157                 [MonoTODO("Not implemented, always returns null")]
158                 protected ControlAdapter Adapter 
159                 {
160                         get {
161                                 // for the time being, fool the
162                                 // Control machinery into thinking we
163                                 // don't have an Adapter.  This will
164                                 // allow us to write all the rest of
165                                 // the Adapter handling code without
166                                 // having to worry about *having*
167                                 // adapters.
168                                 return null;
169                         }
170                 }
171
172                 string _appRelativeTemplateSourceDirectory = null;
173
174                 [EditorBrowsable (EditorBrowsableState.Advanced)]
175                 [Browsable (false)]
176                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
177                 public string AppRelativeTemplateSourceDirectory 
178                 {
179                         get {
180                                 if (_appRelativeTemplateSourceDirectory != null)
181                                         return _appRelativeTemplateSourceDirectory;
182
183                                 Control tc = TemplateControl;
184                                 if (tc != null)
185                                         return tc.AppRelativeTemplateSourceDirectory;
186
187                                 Control parent = Parent;
188                                 if (parent != null)
189                                         return parent.AppRelativeTemplateSourceDirectory;
190
191                                 HttpContext context = Context;
192                                 if (context != null)
193                                         return VirtualPathUtility.ToAppRelative (
194                                                 VirtualPathUtility.GetDirectory (context.Request.FilePath));
195
196                                 return "~/";
197                         }
198                         [EditorBrowsable (EditorBrowsableState.Never)]
199                         set     { _appRelativeTemplateSourceDirectory = value; }
200                 }
201                 
202 #endif          
203
204                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
205                 [EditorBrowsable (EditorBrowsableState.Never), Browsable (false)]
206                 public Control BindingContainer {
207                         get {
208                                 Control container = NamingContainer;
209                                 if (container != null && (container.stateMask & BINDING_CONTAINER) == 0)
210                                         container = container.BindingContainer;
211                                 return container;
212                         }
213                 }
214
215                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
216                 [Browsable (false)]
217                 [WebSysDescription ("An Identification of the control that is rendered.")]
218                 public virtual string ClientID {
219                         get {
220                                 string client = UniqueID;
221
222                                 if (client != null)
223 #if NET_2_0
224                                         client = UniqueID2ClientID (client);
225 #else
226                                         client = client.Replace (':', ClientIDSeparator);
227 #endif
228                                 
229                                 stateMask |= ID_SET;
230                                 return client;
231                         }
232                 }
233
234 #if NET_2_0
235                 internal string UniqueID2ClientID (string uniqueId)
236                 {
237                         return uniqueId.Replace (IdSeparator, ClientIDSeparator);
238                 }
239
240                 protected char ClientIDSeparator
241 #else
242                 char ClientIDSeparator
243 #endif          
244                 {
245                         get {
246                                 return '_';
247                         }
248                 }
249
250
251                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
252                 [Browsable (false)]
253                 [WebSysDescription ("The child controls of this control.")]
254                 public virtual ControlCollection Controls //DIT
255                 {
256                         get
257                         {
258                                 if (_controls == null) _controls = CreateControlCollection();
259                                 return _controls;
260                         }
261                 }
262
263 #if NET_2_0
264                 [MonoTODO ("revisit once we have a real design strategy")]
265                 protected internal bool DesignMode 
266                 {
267                         get { return false; }
268                 }
269 #endif          
270
271                 [DefaultValue (true), WebCategory ("Behavior")]
272                 [WebSysDescription ("An Identification of the control that is rendered.")]
273 #if NET_2_0
274                 [Themeable (false)]
275 #endif                
276                 public virtual bool EnableViewState {
277                         get { return ((stateMask & ENABLE_VIEWSTATE) != 0); }
278                         set { SetMask (ENABLE_VIEWSTATE, value); }
279                 }
280                 
281                 [MergableProperty (false), ParenthesizePropertyName (true)]
282                 [WebSysDescription ("The name of the control that is rendered.")]
283 #if NET_2_0
284                 [Filterable (false), Themeable (false)]
285 #endif                
286
287                 public virtual string ID {
288                         get {
289                                 return (((stateMask & ID_SET) != 0) ? _userId : null);
290                         }
291                         
292                         set {
293                                 if (value == "")
294                                         value = null;
295
296                                 stateMask |= ID_SET;
297                                 _userId = value;
298                                 NullifyUniqueID ();
299                         }
300                 }
301
302 #if NET_2_0
303                 protected char IdSeparator 
304                 {
305                         get {
306                                 return '$';
307                         }
308                 }
309
310                 protected internal bool IsChildControlStateCleared {
311                         get { return _isChildControlStateCleared; }
312                 }
313
314                 protected internal bool IsViewStateEnabled 
315                 {
316                         get {
317
318                                 for (Control control = this; control != null; control = control.Parent)
319                                         if (!control.EnableViewState)
320                                                 return false;
321
322                                 return true;
323                         }
324                 }
325
326                 protected bool LoadViewStateByID 
327                 {
328                         get {
329                                 return false;
330                         }
331                 }
332 #endif          
333                 
334                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
335                 [Browsable (false)]
336                 [WebSysDescription ("The container that this control is part of. The control's name has to be unique within the container.")]
337                 public virtual Control NamingContainer {
338                         get {
339                                 if (_namingContainer == null && _parent != null) {
340                                         if ((_parent.stateMask & IS_NAMING_CONTAINER) == 0)
341                                                 _namingContainer = _parent.NamingContainer;
342                                         else
343                                                 _namingContainer = _parent;
344                                 }
345
346                                 return _namingContainer;
347                         }
348                 }
349
350                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
351                 [Browsable (false)]
352                 [WebSysDescription ("The webpage that this control resides on.")]
353 #if NET_2_0
354                 [Bindable (false)]
355 #endif                
356                 public virtual Page Page //DIT
357                 {
358                         get
359                         {
360                                 if (_page == null && _parent != null) _page = _parent.Page;
361                                 return _page;
362                         }
363                         set
364                         {
365                                 _page = value;
366                         }
367                 }
368
369                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
370                 [Browsable (false)]
371                 [WebSysDescription ("The parent control of this control.")]
372                 public virtual Control Parent //DIT
373                 {
374                         get
375                         {
376                                 return _parent;
377                         }
378                 }
379
380                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
381                 [EditorBrowsable (EditorBrowsableState.Advanced), Browsable (false)]
382                 [WebSysDescription ("The site this control is part of.")]
383                 public ISite Site //DIT
384                 {
385                         get
386                         {
387                                 return _site;
388                         }
389                         set
390                         {
391                                 _site = value;
392                         }
393                 }
394
395 #if NET_2_0
396                 [Browsable (false)]
397                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
398                 public TemplateControl TemplateControl {
399                         get {
400                                 return TemplateControlInternal;
401                         }
402                         
403                         [EditorBrowsable (EditorBrowsableState.Never)]
404                         set { _templateControl = value; }
405                 }
406
407                         internal virtual TemplateControl TemplateControlInternal {
408                                 get {
409                                         if (_templateControl != null)
410                                                 return _templateControl;
411                                         if (_parent != null)
412                                                 return _parent.TemplateControl;
413                                         return null;
414                                 }
415                         }
416 #endif          
417
418 #if !TARGET_J2EE
419                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
420                 [Browsable (false)]
421                 [WebSysDescription ("A virtual directory containing the parent of the control.")]
422                 public virtual string TemplateSourceDirectory {
423                         get {
424 #if NET_2_0
425                                 if (_templateSourceDirectory == null) {
426                                         TemplateControl tc = TemplateControl;
427
428                                         if (tc == null) {
429                                                 HttpContext ctx = Context;
430                                                 if (ctx != null)
431                                                         _templateSourceDirectory = VirtualPathUtility.GetDirectory (ctx.Request.CurrentExecutionFilePath);
432                                         } else if (tc != this)
433                                                 _templateSourceDirectory = tc.TemplateSourceDirectory;
434                                         
435                                         if (_templateSourceDirectory == null && this is TemplateControl) {
436                                                 string path = ((TemplateControl)this).AppRelativeVirtualPath;
437                                                 
438                                                 if (path != null) {
439                                                         // Pretend our application virtual root is "/" even if it isn't - we just
440                                                         // want to get an absolute url out of relative one, without the real
441                                                         // application root prepended to it.
442                                                         string ret = VirtualPathUtility.GetDirectory (VirtualPathUtility.ToAbsolute (path, "/"));
443                                                         int len = ret.Length;
444                                                         if (len <= 1)
445                                                                 return ret;
446                                                         if (ret [--len] == '/')
447                                                                 _templateSourceDirectory = ret.Substring (0, len);
448                                                 } else
449                                                         _templateSourceDirectory = String.Empty;
450                                         }
451                                         if (_templateSourceDirectory == null)
452                                                 _templateSourceDirectory = String.Empty;
453                                 }
454                                 
455                                 return _templateSourceDirectory;
456 #else
457                                 if (_templateSourceDirectory == null) {
458                                         HttpContext ctx = HttpContext.Current;
459                                         HttpRequest req = ctx != null ? ctx.Request : null;
460                                         
461                                         _templateSourceDirectory = (_parent == null)
462                                                 ? req != null ? VirtualPathUtility.RemoveTrailingSlash (
463                                                         VirtualPathUtility.GetDirectory (
464                                                                 HttpContext.Current.Request.CurrentExecutionFilePath)) : String.Empty
465                                                 : _parent.TemplateSourceDirectory;
466                                 }
467                                 return _templateSourceDirectory;
468 #endif
469                         }
470                 }
471 #endif
472
473                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
474                 [Browsable (false)]
475                 [WebSysDescription ("The unique ID of the control.")]
476                 public virtual string UniqueID {
477                         get {
478                                 if (uniqueID != null)
479                                         return uniqueID;
480
481                                 if (_namingContainer == null) {
482                                         if ((stateMask & IS_NAMING_CONTAINER) == 0)
483                                                 _namingContainer = NamingContainer;
484                                         if (_namingContainer == null)
485                                                 return _userId;
486                                 }
487
488                                 if (_userId == null)
489                                         _userId = _namingContainer.GetDefaultName ();
490
491                                 string prefix = _namingContainer.UniqueID;
492 #if TARGET_J2EE
493                                 // For J2EE portlets we need to add the namespace to the ID.
494                                 if (_namingContainer == _page && _page.PortletNamespace != null)
495                                         prefix = _page.PortletNamespace;
496                                 else
497 #endif
498                                 if (_namingContainer == _page || prefix == null) {
499                                         uniqueID = _userId;
500                                         return uniqueID;
501                                 }
502
503 #if NET_2_0
504                                 uniqueID = prefix + IdSeparator + _userId;
505 #else
506                                 uniqueID = prefix + ":" + _userId;
507 #endif
508                                 return uniqueID;
509                         }
510                 }
511
512                 void SetMask (int m, bool val)
513                 {
514                         if (val)
515                                 stateMask |= m;
516                         else
517                                 stateMask &= ~m;
518                 }
519                 
520                 [DefaultValue (true), Bindable (true), WebCategory ("Behavior")]
521                 [WebSysDescription ("Visiblity state of the control.")]
522                 public virtual bool Visible {
523                         get {
524                                 if ((stateMask & VISIBLE) == 0)
525                                         return false;
526
527                                 if (_parent != null)
528                                         return _parent.Visible;
529
530                                 return true;
531                         }
532
533                         set {
534                                 if ((value && (stateMask & VISIBLE) == 0) ||
535                                     (!value && (stateMask & VISIBLE) != 0)) {
536                                         if (IsTrackingViewState)
537                                                 stateMask |= VISIBLE_CHANGED;
538                                 }
539
540                                 SetMask (VISIBLE, value);
541                         }
542                 }
543
544                 protected bool ChildControlsCreated {
545                         get { return ((stateMask & CHILD_CONTROLS_CREATED) != 0); }
546                         set {
547                                 if (value == false && (stateMask & CHILD_CONTROLS_CREATED) != 0) {
548                                         if (_controls != null)
549                                                 _controls.Clear();
550                                 }
551
552                                 SetMask (CHILD_CONTROLS_CREATED, value);
553                         }
554                 }
555
556                 [Browsable (false)]
557                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
558                 protected virtual HttpContext Context //DIT
559                 {
560                         get
561                         {
562                                 HttpContext context;
563                                 if (_context != null)
564                                         return _context;
565                                 if (_parent == null)
566                                         return HttpContext.Current;
567                                 context = _parent.Context;
568                                 if (context != null)
569                                         return context;
570                                 return HttpContext.Current;
571                         }
572                 }
573
574                 protected EventHandlerList Events {
575                         get {
576                                 if (_events == null)
577                                         _events = new EventHandlerList ();
578                                 return _events;
579                         }
580                 }
581
582                 protected bool HasChildViewState {
583                         get {
584                                 return (pendingVS != null && pendingVS.Count > 0);
585                         }
586                 }
587
588                 protected bool IsTrackingViewState {
589                         get { return ((stateMask & TRACK_VIEWSTATE) != 0); }
590                 }
591
592                 [Browsable (false)]
593                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
594                 [WebSysDescription ("ViewState")]
595                 protected virtual StateBag ViewState
596                 {
597                         get
598                         {
599                                 if(_viewState == null)
600                                         _viewState = new StateBag (ViewStateIgnoresCase);
601
602                                 if (IsTrackingViewState)
603                                         _viewState.TrackViewState ();
604
605                                 return _viewState;
606                         }
607                 }
608
609                 [Browsable (false)]
610                 [DesignerSerializationVisibility (DesignerSerializationVisibility.Hidden)]
611                 protected virtual bool ViewStateIgnoresCase
612                 {
613                         get {
614                                 return false;
615                         }
616                 }
617
618                 internal bool AutoEventWireup {
619                         get { return (stateMask & AUTO_EVENT_WIREUP) != 0; }
620                         set { SetMask (AUTO_EVENT_WIREUP, value); }
621                 }
622
623                 internal void SetBindingContainer (bool isBC)
624                 {
625                         SetMask (BINDING_CONTAINER, isBC);
626                 }
627
628                 internal void ResetChildNames ()
629                 {
630                         defaultNumberID = 0;
631                 }
632
633                 string GetDefaultName ()
634                 {
635                         string defaultName;
636                         if (defaultNumberID > 99) {
637 #if NET_2_0
638                                 defaultName = "ctl" + defaultNumberID++;
639 #else
640                                 defaultName = "_ctl" + defaultNumberID++;
641 #endif
642                         } else {
643                                 defaultName = defaultNameArray [defaultNumberID++];
644                         }
645                         return defaultName;
646                 }
647
648                 void NullifyUniqueID ()
649                 {
650                         uniqueID = null;
651                         if (!HasControls ())
652                                 return;
653
654                         foreach (Control c in _controls)
655                                 c.NullifyUniqueID ();
656                 }
657
658                 protected internal virtual void AddedControl (Control control, int index)
659                 {
660                         /* Ensure the control don't have more than 1 parent */
661                         if (control._parent != null)
662                                 control._parent.Controls.Remove (control);
663
664                         control._parent = this;
665                         control._page = _page;
666                         Control nc = ((stateMask & IS_NAMING_CONTAINER) != 0) ? this : NamingContainer;
667
668                         if (nc != null) {
669                                 control._namingContainer = nc;
670                                 if (control.AutoID == true && control._userId == null)
671                                         control._userId =  nc.GetDefaultName ();
672                         }
673
674                         if ((stateMask & (INITING | INITED)) != 0)
675                                 control.InitRecursive (nc);
676
677                         if ((stateMask & (VIEWSTATE_LOADED | LOADED)) != 0) {
678                                 if (pendingVS != null) {
679                                         object vs = pendingVS [index];
680                                         if (vs != null) {
681                                                 pendingVS.Remove (index);
682                                                 if (pendingVS.Count == 0)
683                                                         pendingVS = null;
684                                         
685                                                 control.LoadViewStateRecursive (vs);
686                                         }
687                                 }
688                         }
689
690                         if ((stateMask & LOADED) != 0)
691                                 control.LoadRecursive ();
692                         
693                         if ((stateMask & PRERENDERED) != 0)
694                                 control.PreRenderRecursiveInternal ();
695                 }
696
697                 protected virtual void AddParsedSubObject(object obj) //DIT
698                 {
699                         Control c = obj as Control;
700                         if (c != null) Controls.Add(c);
701                 }
702
703 #if NET_2_0
704                 [EditorBrowsable (EditorBrowsableState.Advanced)]
705                 public virtual void ApplyStyleSheetSkin (Page page)
706                 {
707                         if (!EnableTheming) /* this enough? */
708                                 return;
709
710                         /* apply the style sheet skin here */
711                         if (page.StyleSheetPageTheme != null) {
712                                 ControlSkin cs = page.StyleSheetPageTheme.GetControlSkin (GetType(), SkinID);
713                                 if (cs != null)
714                                         cs.ApplySkin (this);
715                         }
716                 }
717 #endif          
718
719                 protected void BuildProfileTree(string parentId, bool calcViewState)
720                 {
721                         //TODO
722                 }
723
724 #if NET_2_0
725                 protected void ClearChildControlState ()
726                 {
727                         _isChildControlStateCleared = true;
728                 }
729
730                 protected void ClearChildState ()
731                 {
732                         ClearChildViewState ();
733                         ClearChildControlState ();
734                 }
735 #endif          
736
737                 protected void ClearChildViewState ()
738                 {
739                         pendingVS = null;
740                 }
741
742 #if NET_2_0
743                 protected internal
744 #else
745                 protected
746 #endif          
747                 virtual void CreateChildControls() {} //DIT
748                 
749                 protected virtual ControlCollection CreateControlCollection() //DIT
750                 {
751                         return new ControlCollection(this);
752                 }
753
754                 protected virtual void EnsureChildControls ()
755                 {
756                         if (ChildControlsCreated == false && (stateMask & CREATING_CONTROLS) == 0) {
757                                 stateMask |= CREATING_CONTROLS;
758 #if NET_2_0
759                                 if (Adapter != null)
760                                         Adapter.CreateChildControls ();
761                                 else
762 #endif
763                                         CreateChildControls();
764                                 ChildControlsCreated = true;
765                                 stateMask &= ~CREATING_CONTROLS;
766                         }
767                 }
768
769 #if NET_2_0
770                 protected void EnsureID ()
771                 {
772                         if (Page == null)
773                                 return;
774                         if(String.IsNullOrEmpty(ID))
775                         ID = NamingContainer.GetDefaultName ();
776                 }
777
778                 protected bool HasEvents ()
779                 {
780                         return _events != null;
781                 }
782                 
783 #endif
784                 
785
786                 protected bool IsLiteralContent()
787                 {
788                         if (HasControls () && _controls.Count == 1 && (_controls [0] is LiteralControl))
789                                 return true;
790
791                         return false;
792                 }
793
794                 [WebSysDescription ("")]
795                 public virtual Control FindControl (string id)
796                 {
797                         return FindControl (id, 0);
798                 }
799
800                 Control LookForControlByName (string id)
801                 {
802 #if TARGET_J2EE
803                         if (this == Page && id != null && id == Page.PortletNamespace)
804                                 return this;
805 #endif
806                         if (!HasControls ())
807                                 return null;
808
809                         Control result = null;
810                         foreach (Control c in _controls) {
811                                 if (String.Compare (id, c._userId, true, CultureInfo.InvariantCulture) == 0) {
812                                         if (result != null && result != c) {
813                                                 throw new HttpException ("1 Found more than one control with ID '" + id + "'");
814                                         }
815
816                                         result = c;
817                                         continue;
818                                 }
819
820                                 if ((c.stateMask & IS_NAMING_CONTAINER) == 0 && c.HasControls ()) {
821                                         Control child = c.LookForControlByName (id);
822                                         if (child != null) {
823                                                 if (result != null && result != child)
824                                                         throw new HttpException ("2 Found more than one control with ID '" + id + "'");
825
826                                                 result = child;
827                                         }
828                                 }
829                         }
830
831                         return result;
832                 }
833
834                 protected virtual Control FindControl (string id, int pathOffset)
835                 {
836                         EnsureChildControls ();
837                         Control namingContainer = null;
838                         if ((stateMask & IS_NAMING_CONTAINER) == 0) {
839                                 namingContainer = NamingContainer;
840                                 if (namingContainer == null)
841                                         return null;
842
843                                 return namingContainer.FindControl (id, pathOffset);
844                         }
845
846                         if (!HasControls ())
847                                 return null;
848 #if NET_2_0
849                         int separatorIdx = id.IndexOf (IdSeparator, pathOffset);
850 #else
851                         int separatorIdx = id.IndexOf (':', pathOffset);
852 #endif
853                         if (separatorIdx == -1)
854                                 return LookForControlByName (id.Substring (pathOffset));
855                         
856                         string idfound = id.Substring (pathOffset, separatorIdx - pathOffset);
857                         namingContainer = LookForControlByName (idfound);
858                         if (namingContainer == null)
859                                 return null;
860
861                         return namingContainer.FindControl (id, separatorIdx + 1);
862                 }
863
864                 protected virtual void LoadViewState(object savedState)
865                 {
866                         if (savedState != null) {
867                                 ViewState.LoadViewState (savedState);
868                                 object o = ViewState ["Visible"];
869                                 if (o != null) {
870                                         SetMask (VISIBLE, (bool) o);
871                                         stateMask |= VISIBLE_CHANGED;
872                                 }
873                         }
874                 }
875
876                 // [MonoTODO("Secure?")]
877                 protected string MapPathSecure(string virtualPath)
878                 {
879                         string combined = UrlUtils.Combine (TemplateSourceDirectory, virtualPath);
880                         return Context.Request.MapPath (combined);
881                 }
882
883                 protected virtual bool OnBubbleEvent(object source, EventArgs args) //DIT
884                 {
885 #if MONO_TRACE
886                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
887                         string type_name = null;
888                         if (trace != null) {
889                                 type_name = GetType ().Name;
890                                 trace.Write ("control", String.Format ("OnBubbleEvent {0} {1}", _userId, type_name));
891                         }
892 #endif
893                         return false;
894                 }
895
896                 protected virtual void OnDataBinding (EventArgs e)
897                 {
898                         if ((event_mask & databinding_mask) != 0) {
899                                 EventHandler eh = (EventHandler)(_events [DataBindingEvent]);
900                                 if (eh != null) {
901 #if MONO_TRACE
902                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
903                                         string type_name = null;
904                                         if (trace != null) {
905                                                 type_name = GetType ().Name;
906                                                 trace.Write ("control", String.Format ("OnDataBinding {0} {1}", _userId, type_name));
907                                         }
908 #endif
909                                         eh (this, e);
910                                 }
911                         }
912                 }
913
914 #if NET_2_0
915                 protected internal
916 #else           
917                 protected
918 #endif          
919                 virtual void OnInit (EventArgs e)
920                 {
921                         if ((event_mask & init_mask) != 0) {
922                                 EventHandler eh = (EventHandler)(_events [InitEvent]);
923                                 if (eh != null) {
924 #if MONO_TRACE
925                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
926                                         string type_name = null;
927                                         if (trace != null) {
928                                                 type_name = GetType ().Name;
929                                                 trace.Write ("control", String.Format ("OnInit {0} {1}", _userId, type_name));
930                                         }
931 #endif
932                                         eh (this, e);
933                                 }
934                         }
935                 }
936
937 #if NET_2_0
938                 protected internal
939 #else
940                 protected
941 #endif          
942                 virtual void OnLoad (EventArgs e)
943                 {
944                         if ((event_mask & load_mask) != 0) {
945                                 EventHandler eh = (EventHandler)(_events [LoadEvent]);
946                                 if (eh != null) {
947 #if MONO_TRACE
948                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
949                                         string type_name = null;
950                                         if (trace != null) {
951                                                 type_name = GetType ().Name;
952                                                 trace.Write ("control", String.Format ("OnLoad {0} {1}", _userId, type_name));
953                                         }
954 #endif
955                                         eh (this, e);
956                                 }
957                         }
958                 }
959
960 #if NET_2_0
961                 protected internal
962 #else
963                 protected
964 #endif
965                 virtual void OnPreRender (EventArgs e)
966                 {
967                         if ((event_mask & prerender_mask) != 0) {
968                                 EventHandler eh = (EventHandler)(_events [PreRenderEvent]);
969                                 if (eh != null) {
970 #if MONO_TRACE
971                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
972                                         string type_name = null;
973                                         if (trace != null) {
974                                                 type_name = GetType ().Name;
975                                                 trace.Write ("control", String.Format ("OnPreRender {0} {1}", _userId, type_name));
976                                         }
977 #endif
978                                         eh (this, e);
979                                 }
980                         }
981                 }
982
983 #if NET_2_0
984                 protected internal
985 #else
986                 protected
987 #endif
988                 virtual void OnUnload(EventArgs e)
989                 {
990                         if ((event_mask & unload_mask) != 0) {
991                                 EventHandler eh = (EventHandler)(_events [UnloadEvent]);
992                                 if (eh != null) {
993 #if MONO_TRACE
994                                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
995                                         string type_name = null;
996                                         if (trace != null) {
997                                                 type_name = GetType ().Name;
998                                                 trace.Write ("control", String.Format ("OnUnload {0} {1}", _userId, type_name));
999                                         }
1000 #endif
1001                                         eh (this, e);
1002                                 }
1003                         }
1004                 }
1005
1006 #if NET_2_0
1007                 protected internal Stream OpenFile (string path)
1008                 {
1009                         try {
1010                                 string filePath = Context.Server.MapPath (path);
1011                                 return File.OpenRead (filePath);
1012                         }
1013                         catch (UnauthorizedAccessException) {
1014                                 throw new HttpException ("Access to the specified file was denied.");
1015                         }
1016                 }
1017
1018                 internal string GetPhysicalFilePath (string virtualPath)
1019                 {
1020                         Page page = Page;
1021                         
1022                         if (VirtualPathUtility.IsAbsolute (virtualPath))
1023                                 return page != null ? page.MapPath (virtualPath) : Context.Server.MapPath (virtualPath);
1024
1025                         // We need to determine whether one of our parents is a
1026                         // master page. If so, we need to map the path
1027                         // relatively to the master page and not our containing
1028                         // page/control. This is necessary for cases when a
1029                         // relative path is used in a control placed in a master
1030                         // page and the master page is referenced from a
1031                         // location other than its own. In such cases MS.NET looks
1032                         // for the file in the directory where the master page
1033                         // is.
1034                         //
1035                         // An example of where it is needed is at
1036                         //
1037                         // http://quickstarts.asp.net/QuickStartv20/aspnet/samples/masterpages/masterpages_cs/pages/default.aspx
1038                         //
1039                         MasterPage master = null;
1040                         Control ctrl = Parent;
1041
1042                         while (ctrl != null) {
1043                                 if (ctrl is MasterPage) {
1044                                         master = ctrl as MasterPage;
1045                                         break;
1046                                 }
1047                                 ctrl = ctrl.Parent;
1048                         }
1049                         
1050                         string path;
1051                         if (master != null)
1052                                 path = VirtualPathUtility.Combine (master.TemplateSourceDirectory, virtualPath);
1053                         else
1054                                 path = VirtualPathUtility.Combine (TemplateSourceDirectory, virtualPath);
1055                         return page != null ? page.MapPath (path) : Context.Server.MapPath (path);
1056                 }
1057 #endif          
1058
1059                 protected void RaiseBubbleEvent(object source, EventArgs args)
1060                 {
1061                         Control c = Parent;
1062                         while (c != null) {
1063 #if MONO_TRACE
1064                                 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1065                                 string type_name = null;
1066                                 if (trace != null) {
1067                                         type_name = GetType ().Name;
1068                                         trace.Write ("control", String.Format ("RaiseBubbleEvent {0} {1}", _userId, type_name));
1069                                 }
1070 #endif
1071                                 if (c.OnBubbleEvent (source, args)) {
1072 #if MONO_TRACE
1073                                         if (trace != null)
1074                                                 trace.Write ("control", String.Format ("End RaiseBubbleEvent (false) {0} {1}", _userId, type_name));
1075 #endif
1076                                         break;
1077                                 }
1078 #if MONO_TRACE
1079                                 if (trace != null)
1080                                         trace.Write ("control", String.Format ("End RaiseBubbleEvent (true) {0} {1}", _userId, type_name));
1081 #endif
1082                                 c = c.Parent;
1083                         }
1084                 }
1085
1086 #if NET_2_0
1087                 protected internal
1088 #else
1089                 protected
1090 #endif
1091                 virtual void Render(HtmlTextWriter writer) //DIT
1092                 {
1093                         RenderChildren(writer);
1094                 }
1095
1096 #if NET_2_0
1097                 protected internal
1098 #else
1099                 protected
1100 #endif
1101                 virtual void RenderChildren (HtmlTextWriter writer) //DIT
1102                 {
1103                         if (_renderMethodDelegate != null) {
1104                                 _renderMethodDelegate (writer, this);
1105                         } else if (_controls != null) {
1106                                 int len = _controls.Count;
1107                                 Control c;
1108                                 for (int i = 0; i < len; i++) {
1109                                         c = _controls [i];
1110                                         if (c == null)
1111                                                 continue;
1112 #if NET_2_0
1113                                         if (c.Adapter != null)
1114                                                 c.RenderControl (writer, c.Adapter);
1115                                         else
1116 #endif
1117                                                 c.RenderControl (writer);
1118                                 }
1119                         }
1120                 }
1121
1122 #if NET_2_0
1123                 protected virtual ControlAdapter ResolveAdapter ()
1124                 {
1125                         throw new NotImplementedException ();
1126                 }
1127 #endif          
1128
1129                 protected virtual object SaveViewState ()
1130                 {
1131                         if ((stateMask & VISIBLE_CHANGED) != 0) {
1132                                 ViewState ["Visible"] = (stateMask & VISIBLE) != 0;
1133                         } else if (_viewState == null) {
1134                                 return null;
1135                         }
1136
1137                         return _viewState.SaveViewState ();
1138                 }
1139
1140                 protected virtual void TrackViewState()
1141                 {
1142                         if (_viewState != null)
1143                                 _viewState.TrackViewState ();
1144
1145                         stateMask |= TRACK_VIEWSTATE;
1146                 }
1147
1148                 public virtual void Dispose ()
1149                 {
1150                         if ((event_mask & disposed_mask) != 0) {
1151                                 EventHandler eh = (EventHandler)(_events [DisposedEvent]);
1152                                 if (eh != null) eh (this, EventArgs.Empty);
1153                         }
1154                 }
1155
1156                 [WebCategory ("FIXME")]
1157                 [WebSysDescription ("Raised when the contols databound properties are evaluated.")]
1158                 public event EventHandler DataBinding {
1159                         add {
1160                                 event_mask |= databinding_mask;
1161                                 Events.AddHandler (DataBindingEvent, value);
1162                         }
1163                         remove { Events.RemoveHandler (DataBindingEvent, value); }
1164                 }
1165
1166                 [WebSysDescription ("Raised when the contol is disposed.")]
1167                 public event EventHandler Disposed {
1168                         add {
1169                                 event_mask |= disposed_mask;
1170                                 Events.AddHandler (DisposedEvent, value);
1171                         }
1172                         remove { Events.RemoveHandler (DisposedEvent, value); }
1173                 }
1174
1175                 [WebSysDescription ("Raised when the page containing the control is initialized.")]
1176                 public event EventHandler Init {
1177                         add {
1178                                 event_mask |= init_mask;
1179                                 Events.AddHandler (InitEvent, value);
1180                         }
1181                         remove { Events.RemoveHandler (InitEvent, value); }
1182                 }
1183
1184                 [WebSysDescription ("Raised after the page containing the control has been loaded.")]
1185                 public event EventHandler Load {
1186                         add {
1187                                 event_mask |= load_mask;
1188                                 Events.AddHandler (LoadEvent, value);
1189                         }
1190                         remove { Events.RemoveHandler (LoadEvent, value); }
1191                 }
1192
1193                 [WebSysDescription ("Raised before the page containing the control is rendered.")]
1194                 public event EventHandler PreRender {
1195                         add {
1196                                 event_mask |= prerender_mask;
1197                                 Events.AddHandler (PreRenderEvent, value);
1198                         }
1199                         remove { Events.RemoveHandler (PreRenderEvent, value); }
1200                 }
1201
1202                 [WebSysDescription ("Raised when the page containing the control is unloaded.")]
1203                 public event EventHandler Unload {
1204                         add {
1205                                 event_mask |= unload_mask;
1206                                 Events.AddHandler (UnloadEvent, value);
1207                         }
1208                         remove { Events.RemoveHandler (UnloadEvent, value); }
1209                 }
1210
1211                 public virtual void DataBind() //DIT
1212                 {
1213                         #if NET_2_0
1214                         DataBind (true);
1215                         #else
1216                         OnDataBinding (EventArgs.Empty);
1217                         DataBindChildren();
1218                         #endif
1219                 }
1220
1221                 #if NET_2_0
1222                 protected virtual
1223                 #endif
1224                 
1225                 void DataBindChildren ()
1226                 {
1227                         if (!HasControls ())
1228                                 return;
1229                         
1230                         int len = _controls.Count;
1231                         for (int i = 0; i < len; i++) {
1232                                 Control c = _controls [i];
1233                                 c.DataBind ();
1234                         }
1235                 }
1236
1237
1238                 public virtual bool HasControls ()
1239                 {
1240                         return (_controls != null && _controls.Count > 0);
1241                 }
1242
1243 #if NET_2_0
1244                 public virtual
1245 #else
1246                 public
1247 #endif
1248                 void RenderControl (HtmlTextWriter writer)
1249                 {
1250                         if ((stateMask & VISIBLE) != 0) {
1251                                 HttpContext ctx = Context;
1252                                 TraceContext trace = (ctx != null) ? ctx.Trace : null;
1253                                 int pos = 0;
1254                                 if ((trace != null) && trace.IsEnabled)
1255                                         pos = ctx.Response.GetOutputByteCount ();
1256
1257                                 Render(writer);
1258                                 if ((trace != null) && trace.IsEnabled) {
1259                                         int size = ctx.Response.GetOutputByteCount () - pos;
1260                                         trace.SaveSize (this, size >= 0 ? size : 0);
1261                                 }
1262                         }
1263                 }
1264
1265 #if NET_2_0
1266                 protected void RenderControl (HtmlTextWriter writer,
1267                                               ControlAdapter adapter)
1268                 {
1269                         if ((stateMask & VISIBLE) != 0) {
1270                                 adapter.BeginRender (writer);
1271                                 adapter.Render (writer);
1272                                 adapter.EndRender (writer);
1273                         }
1274                 }
1275 #endif          
1276
1277                 public string ResolveUrl (string relativeUrl)
1278                 {
1279                         if (relativeUrl == null)
1280                                 throw new ArgumentNullException ("relativeUrl");
1281
1282                         if (relativeUrl == "")
1283                                 return "";
1284
1285                         if (relativeUrl [0] == '#')
1286                                 return relativeUrl;
1287                         
1288                         string ts = TemplateSourceDirectory;
1289                         if (ts == null || ts.Length == 0 ||
1290                                 Context == null || Context.Response == null ||
1291                                 !UrlUtils.IsRelativeUrl (relativeUrl))
1292                                 return relativeUrl;
1293
1294                         HttpResponse resp = Context.Response;
1295                         return resp.ApplyAppPathModifier (UrlUtils.Combine (ts, relativeUrl));
1296                 }
1297
1298
1299 #if NET_2_0             
1300                 public
1301 #else
1302                 internal
1303 #endif
1304                 string ResolveClientUrl (string relativeUrl)
1305                 {
1306 #if TARGET_J2EE
1307                         // There are no relative paths when rendering a J2EE portlet
1308                         if (Page != null && Page.PortletNamespace != null)
1309                                 return ResolveUrl (relativeUrl);
1310 #endif
1311                         if (relativeUrl == null)
1312                                 throw new ArgumentNullException ("relativeUrl");
1313
1314                         if (relativeUrl.Length == 0)
1315                                 return String.Empty;
1316
1317                         if (VirtualPathUtility.IsAbsolute (relativeUrl) || relativeUrl.IndexOf (':') >= 0)
1318                                 return relativeUrl;
1319
1320                         HttpContext context = Context;
1321                         if (context != null && context.Request != null) {
1322                                 string templateSourceDirectory = TemplateSourceDirectory;
1323                                 if (templateSourceDirectory == null || templateSourceDirectory.Length == 0)
1324                                         return relativeUrl;
1325                                 
1326                                 string basePath = context.Request.CurrentExecutionFilePath;
1327
1328                                 if (basePath.Length > 1 && basePath [basePath.Length - 1] != '/')
1329                                         basePath = VirtualPathUtility.GetDirectory (basePath);
1330                                 
1331                                 if(VirtualPathUtility.IsAppRelative(relativeUrl))
1332                                         return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1333                                 
1334                                 string templatePath = VirtualPathUtility.AppendTrailingSlash (templateSourceDirectory);
1335                                 
1336                                 if (basePath.Length == templatePath.Length && String.CompareOrdinal (basePath, templatePath) == 0)
1337                                         return relativeUrl;
1338                                 
1339                                 relativeUrl = VirtualPathUtility.Combine (templatePath, relativeUrl);
1340                                 return VirtualPathUtility.MakeRelative (basePath, relativeUrl);
1341                         }
1342                         return relativeUrl;
1343                 }
1344                 
1345                 internal bool HasRenderMethodDelegate () {
1346                         return _renderMethodDelegate != null;
1347                 }
1348
1349                 [EditorBrowsable (EditorBrowsableState.Advanced)]
1350                 public void SetRenderMethodDelegate(RenderMethod renderMethod) //DIT
1351                 {
1352                         _renderMethodDelegate = renderMethod;
1353                 }
1354
1355                 internal void LoadRecursive()
1356                 {
1357 #if MONO_TRACE
1358                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1359                         string type_name = null;
1360                         if (trace != null) {
1361                                 type_name = GetType ().Name;
1362                                 trace.Write ("control", String.Format ("LoadRecursive {0} {1}", _userId, type_name));
1363                         }
1364 #endif
1365 #if NET_2_0
1366                         if (Adapter != null)
1367                                 Adapter.OnLoad (EventArgs.Empty);
1368                         else
1369 #endif
1370                                 OnLoad (EventArgs.Empty);
1371                         if (HasControls ()) {
1372                                 int len = _controls.Count;
1373                                 for (int i=0;i<len;i++)
1374                                 {
1375                                         Control c = _controls[i];
1376                                         c.LoadRecursive ();
1377                                 }
1378                         }
1379
1380 #if MONO_TRACE
1381                         if (trace != null)
1382                                 trace.Write ("control", String.Format ("End LoadRecursive {0} {1}", _userId, type_name));
1383 #endif
1384                         stateMask |= LOADED;
1385                 }
1386
1387                 internal void UnloadRecursive(Boolean dispose)
1388                 {
1389 #if MONO_TRACE
1390                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1391                         string type_name = null;
1392                         if (trace != null) {
1393                                 type_name = GetType ().Name;
1394                                 trace.Write ("control", String.Format ("UnloadRecursive {0} {1}", _userId, type_name));
1395                         }
1396 #endif
1397                         if (HasControls ()) {
1398                                 int len = _controls.Count;
1399                                 for (int i=0;i<len;i++)
1400                                 {
1401                                         Control c = _controls[i];                                       
1402                                         c.UnloadRecursive (dispose);
1403                                 }
1404                         }
1405
1406 #if MONO_TRACE
1407                         if (trace != null)
1408                                 trace.Write ("control", String.Format ("End UnloadRecursive {0} {1}", _userId, type_name));
1409 #endif
1410 #if NET_2_0
1411                         if (Adapter != null)
1412                                 Adapter.OnUnload (EventArgs.Empty);
1413                         else
1414 #endif
1415                                 OnUnload (EventArgs.Empty);
1416                         if (dispose)
1417                                 Dispose();
1418                 }
1419
1420                 internal void PreRenderRecursiveInternal()
1421                 {
1422                         if ((stateMask & VISIBLE) != 0) {
1423                                 EnsureChildControls ();
1424 #if MONO_TRACE
1425                                 TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1426                                 string type_name = null;
1427                                 if (trace != null) {
1428                                         type_name = GetType ().Name;
1429                                         trace.Write ("control", String.Format ("PreRenderRecursive {0} {1}", _userId, type_name));
1430                                 }
1431 #endif
1432 #if NET_2_0
1433                                 if (Adapter != null)
1434                                         Adapter.OnPreRender (EventArgs.Empty);
1435                                 else
1436 #endif
1437                                         OnPreRender (EventArgs.Empty);
1438                                 if (!HasControls ())
1439                                         return;
1440                                 
1441                                 int len = _controls.Count;
1442                                 for (int i=0;i<len;i++)
1443                                 {
1444                                         Control c = _controls[i];
1445                                         c.PreRenderRecursiveInternal ();
1446                                 }
1447 #if MONO_TRACE
1448                                 if (trace != null)
1449                                         trace.Write ("control", String.Format ("End PreRenderRecursive {0} {1}", _userId, type_name));
1450 #endif
1451                         }
1452                         stateMask |= PRERENDERED;
1453                 }
1454
1455                 internal void InitRecursive(Control namingContainer)
1456                 {
1457 #if MONO_TRACE
1458                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1459                         string type_name = null;
1460                         if (trace != null) {
1461                                 type_name = GetType ().Name;
1462                                 trace.Write ("control", String.Format ("InitRecursive {0} {1}", _userId, type_name));
1463                         }
1464 #endif
1465                         if (HasControls ()) {
1466                                 if ((stateMask & IS_NAMING_CONTAINER) != 0)
1467                                         namingContainer = this;
1468
1469                                 if (namingContainer != null && 
1470                                     namingContainer._userId == null &&
1471                                     namingContainer.AutoID)
1472                                         namingContainer._userId = namingContainer.GetDefaultName () + "b";
1473
1474                                 int len = _controls.Count;
1475                                 for (int i=0;i<len;i++)
1476                                 {
1477                                         Control c = _controls[i];
1478                                         c._page = Page;
1479                                         c._namingContainer = namingContainer;
1480                                         if (namingContainer != null && c._userId == null && c.AutoID)
1481                                                 c._userId = namingContainer.GetDefaultName () + "c";
1482                                         c.InitRecursive (namingContainer);      
1483                                 }
1484                         }
1485
1486                         stateMask |= INITING;
1487 #if NET_2_0
1488                         ApplyTheme ();
1489                         
1490                         if (Adapter != null)
1491                                 Adapter.OnInit (EventArgs.Empty);
1492                         else
1493 #endif
1494                                 OnInit (EventArgs.Empty);
1495 #if MONO_TRACE
1496                         if (trace != null)
1497                                 trace.Write ("control", String.Format ("End InitRecursive {0} {1}", _userId, type_name));
1498 #endif
1499                         TrackViewState ();
1500                         stateMask |= INITED;
1501                         stateMask &= ~INITING;
1502                 }
1503
1504                 internal object SaveViewStateRecursive ()
1505                 {
1506                         if (!EnableViewState)
1507                                 return null;
1508
1509 #if MONO_TRACE
1510                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1511                         string type_name = null;
1512                         if (trace != null) {
1513                                 type_name = GetType ().Name;
1514                                 trace.Write ("control", String.Format ("SaveViewStateRecursive {0} {1}", _userId, type_name));
1515                         }
1516 #endif
1517
1518                         ArrayList controlList = null;
1519                         ArrayList controlStates = null;
1520
1521                         int idx = -1;
1522                         if (HasControls ())
1523                         {
1524                                 int len = _controls.Count;
1525                                 for (int i=0;i<len;i++)
1526                                 {
1527                                         Control ctrl = _controls[i];
1528                                         object ctrlState = ctrl.SaveViewStateRecursive ();
1529                                         idx++;
1530                                         if (ctrlState == null)
1531                                                 continue;
1532
1533                                         if (controlList == null) 
1534                                         {
1535                                                 controlList = new ArrayList ();
1536                                                 controlStates = new ArrayList ();
1537                                         }
1538
1539                                         controlList.Add (idx);
1540                                         controlStates.Add (ctrlState);
1541                                 }
1542                         }
1543
1544                         object thisState = SaveViewState ();
1545                         if (thisState == null && controlList == null && controlStates == null) {
1546 #if MONO_TRACE
1547                                 if (trace != null) {
1548                                         trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved nothing", _userId, type_name));
1549                                         trace.SaveViewState (this, null);
1550                                 }
1551 #endif
1552                                 return null;
1553                         }
1554
1555 #if MONO_TRACE
1556                         if (trace != null) {
1557                                 trace.Write ("control", String.Format ("End SaveViewStateRecursive {0} {1} saved a Triplet", _userId, type_name));
1558                                 trace.SaveViewState (this, thisState);
1559                         }
1560 #endif
1561                         return new Triplet (thisState, controlList, controlStates);
1562                 }
1563                 
1564                 internal void LoadViewStateRecursive (object savedState)
1565                 {
1566                         if (!EnableViewState || savedState == null)
1567                                 return;
1568
1569 #if MONO_TRACE
1570                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1571                         string type_name = null;
1572                         if (trace != null) {
1573                                 type_name = GetType ().Name;
1574                                 trace.Write ("control", String.Format ("LoadViewStateRecursive {0} {1}", _userId, type_name));
1575                         }
1576 #endif
1577                         Triplet savedInfo = (Triplet) savedState;
1578                         LoadViewState (savedInfo.First);
1579
1580                         ArrayList controlList = savedInfo.Second as ArrayList;
1581                         if (controlList == null)
1582                                 return;
1583                         ArrayList controlStates = savedInfo.Third as ArrayList;
1584                         int nControls = controlList.Count;
1585                         for (int i = 0; i < nControls; i++) {
1586                                 int k = (int) controlList [i];
1587                                 if (k < Controls.Count && controlStates != null) {
1588                                         Control c = Controls [k];
1589                                         c.LoadViewStateRecursive (controlStates [i]);
1590                                 } else {
1591                                         if (pendingVS == null)
1592                                                 pendingVS = new Hashtable ();
1593
1594                                         pendingVS [k] = controlStates [i];
1595                                 }
1596                         }
1597
1598 #if MONO_TRACE
1599                         if (trace != null)
1600                                 trace.Write ("control", String.Format ("End LoadViewStateRecursive {0} {1}", _userId, type_name));
1601 #endif
1602                         stateMask |= VIEWSTATE_LOADED;
1603                 }
1604
1605 #if NET_2_0
1606                 internal ControlSkin controlSkin;
1607
1608                 internal void ApplyTheme ()
1609                 {
1610 #if MONO_TRACE
1611                         TraceContext trace = (Context != null && Context.Trace.IsEnabled) ? Context.Trace : null;
1612                         string type_name = null;
1613                         if (trace != null) {
1614                                 type_name = GetType ().Name;
1615                                 trace.Write ("control", String.Format ("ApplyThemeRecursive {0} {1}", _userId, type_name));
1616                         }
1617 #endif
1618                         if (Page.PageTheme != null && EnableTheming) {
1619                                 ControlSkin controlSkin = Page.PageTheme.GetControlSkin (GetType (), SkinID);
1620                                 if (controlSkin != null)
1621                                         controlSkin.ApplySkin (this);
1622                         }
1623
1624 #if MONO_TRACE
1625                         if (trace != null)
1626                                 trace.Write ("control", String.Format ("End ApplyThemeRecursive {0} {1}", _userId, type_name));
1627 #endif
1628                 }
1629 #endif
1630                 
1631                 internal bool AutoID
1632                 {
1633                         get { return (stateMask & AUTOID) != 0; }
1634                         set {
1635                                 if (value == false && (stateMask & IS_NAMING_CONTAINER) != 0)
1636                                         return;
1637
1638                                 SetMask (AUTOID, value);
1639                         }
1640                 }
1641
1642                 protected internal virtual void RemovedControl (Control control)
1643                 {
1644                         control.UnloadRecursive (false);
1645                         control._parent = null;
1646                         control._page = null;
1647                         control._namingContainer = null;
1648                 }
1649
1650
1651 #if NET_2_0
1652
1653                 string skinId = string.Empty;
1654                 bool _enableTheming = true;
1655                 
1656                 [Browsable (false)]
1657                 [Themeable (false)]
1658                 [DefaultValue (true)]
1659                 public virtual bool EnableTheming
1660                 {
1661                         get
1662                         {
1663                                 if ((stateMask & ENABLE_THEMING) != 0)
1664                                         return _enableTheming;
1665
1666                                 if (_parent != null)
1667                                         return _parent.EnableTheming;
1668
1669                                 return true;
1670                         }
1671                         set 
1672                         { 
1673                                 SetMask (ENABLE_THEMING, true);
1674                                 _enableTheming = value;
1675                         }
1676                 }
1677                 
1678                 [Browsable (false)]
1679                 [DefaultValue ("")]
1680                 [Filterable (false)]
1681                 public virtual string SkinID
1682                 {
1683                         get { return skinId; }
1684                         set { skinId = value; }
1685                 }
1686
1687                 ControlBuilder IControlBuilderAccessor.ControlBuilder { 
1688                         get {throw new NotImplementedException (); }
1689                 }
1690
1691                 IDictionary IControlDesignerAccessor.GetDesignModeState ()
1692                 {
1693                         throw new NotImplementedException ();               
1694                 }
1695
1696                 void IControlDesignerAccessor.SetDesignModeState (IDictionary designData)
1697                 {
1698                         SetDesignModeState (designData);
1699                 }
1700         
1701                 void IControlDesignerAccessor.SetOwnerControl (Control control)
1702                 {
1703                         throw new NotImplementedException ();               
1704                 }
1705                 
1706                 IDictionary IControlDesignerAccessor.UserData { 
1707                         get { throw new NotImplementedException (); }
1708                 }
1709        
1710                 ExpressionBindingCollection expressionBindings;
1711
1712                 ExpressionBindingCollection IExpressionsAccessor.Expressions { 
1713                         get { 
1714                                 if (expressionBindings == null)
1715                                         expressionBindings = new ExpressionBindingCollection ();
1716                                 return expressionBindings;
1717                         } 
1718                 }
1719                 
1720                 bool IExpressionsAccessor.HasExpressions { 
1721                         get {
1722                                 return (expressionBindings != null && expressionBindings.Count > 0);
1723                         }
1724                 }
1725
1726                 public virtual void Focus()
1727                 {
1728                         Page.SetFocus (this);
1729                 }
1730                 
1731                 protected internal virtual void LoadControlState (object state)
1732                 {
1733                 }
1734                 
1735                 protected internal virtual object SaveControlState ()
1736                 {
1737                         return null;
1738                 }
1739                 
1740                 protected virtual void DataBind (bool raiseOnDataBinding)
1741                 {
1742                         bool foundDataItem = false;
1743                         
1744                         if ((stateMask & IS_NAMING_CONTAINER) != 0 && Page != null) {
1745                                 object o = DataBinder.GetDataItem (this, out foundDataItem);
1746                                 if (foundDataItem)
1747                                         Page.PushDataItemContext (o);
1748                         }
1749                         
1750                         try {
1751                                 
1752                                 if (raiseOnDataBinding)
1753                                         OnDataBinding (EventArgs.Empty);
1754                                 DataBindChildren();
1755                         
1756                         } finally {
1757                                 if (foundDataItem)
1758                                         Page.PopDataItemContext ();
1759                         }
1760                 }
1761                 
1762                 protected virtual IDictionary GetDesignModeState ()
1763                 {
1764                         throw new NotImplementedException ();               
1765                 }
1766                 
1767                 protected virtual void SetDesignModeState (IDictionary data)
1768                 {
1769                         throw new NotImplementedException ();               
1770                 }
1771 #endif
1772                 void IParserAccessor.AddParsedSubObject (object obj) {
1773                         this.AddParsedSubObject (obj);
1774                 }
1775
1776                 DataBindingCollection IDataBindingsAccessor.DataBindings {
1777                         get {
1778                                 if (dataBindings == null) {
1779                                         dataBindings = new DataBindingCollection ();
1780                                 }
1781                                 return dataBindings;
1782                         }
1783                 }
1784
1785                 bool IDataBindingsAccessor.HasDataBindings {
1786                         get {
1787                                 if (dataBindings != null && dataBindings.Count > 0) {
1788                                         return true;
1789                                 }
1790                                 return false;
1791                         }
1792                 }
1793         }
1794 }