
Core.registerNamespace("Reflective.Web.UI.Controls");

Reflective.Web.UI.Controls.CancelEventArgs = function()
{
    this.Inherits(Reflective.Web.EventArgs);
}
Reflective.Web.UI.Controls.FormBase = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.AjaxEnabledControl, clientId, serverId, rootElementId);
    this._submitting = false;
    this._hiddenInputs = new Reflective.Web.Hashtable();
    this._panels = new  Reflective.Web.Hashtable();
}

Core.setInheritance(Reflective.Web.UI.Controls.FormBase,
    Reflective.Web.UI.AjaxEnabledControl);
    

Core.extend(Reflective.Web.UI.Controls.FormBase,
    {
        OnInit : function()
        {
			this._findPanels();
			this._findHiddenInputs();
        },
        _iframe : function() { return this._("iframe"); },
        _formElement : function() { return this._("form"); },
        _findHiddenInputs : function()
        {
			console.log("FormBase._findHiddenInputs");
			
			var inputs = $("[@formId='" + this.ClientId + "'][@isInput='1'][@type='hidden'][@parentPanelId='']");
            for (var i = 0; i < inputs.length; i++)
            {
				var input = window[$(inputs[i]).attr("ClientId")];
				console.log("Found global hidden input " + input.ServerId);
				this._hiddenInputs.set(input.ServerId, input);
            }
        },
        _findPanels : function()
        {
			console.log("FormBase._findPanels");
			
			var panels = $("[@formId='" + this.ClientId + "'][@isPanel='1']");
            for (var i = 0; i < panels.length; i++)
            {
				this.OnFoundPanel(window[$(panels[i]).attr("ClientId")]);
            }
        },
        OnFoundPanel : function(panel)
        {
            this._panels.set(panel.ServerId, panel);
            console.log("panel " + panel.ServerId + " found.");
        },
        Validate : function()
        {
            if (!this.OnValidate())
            {
				this.OnValidationFailed();
				return false;
            }
            else
				return true;
        },
        OnValidate : function()
        {
			return true;
        },
        OnValidationFailed : function()
        {
			this.FireEvent("onvalidationfailed");
        },
        EnterPressed : function(e)
        {
            this.OnEnterPressed(e);
        },
        OnEnterPressed : function(e) {},
        Submit : function(e)
        {
			console.log("Form is submitting...");
            if (!this.Validate())
            {
				console.log("Form did not validate.");
                return false;
            }
            else
            {
				console.log("Validation passed...");
				if (this.EventIsBound("onsubmit"))
				{
					console.log("onsubmit event bound. exiting.");
					//the code has indicated it will entirely handle the submit process
					this.OnSubmit();
				}
				else
				{
					console.log("Beginning submit process.");
					if (!this._submitBegin())
					{
						console.log("Submit aborted (_submitBegin returned false)");
						return false;
	                }
	                console.log("Will use ajax: " + this.UseAjax());
	                this._formElement().submit();
	                console.log("submit event fired.");
//					if (this.UseAjax())
//					{
//						console.log("Ajax form detected.");
//						DomHelper.CancelEvent(e); //cancel full page post
//	                    
//						this.ClearCallBackParams();
//						console.log("Initializing callback parameters.");
//						//serialize and post using callback...
//						
//						var valueSet = new Reflective.Web.Hashtable();
//	                    this.OnGetValuesForSubmit(valueSet);
//						
//						this._hiddenInputs.foreach(
//							function(input)
//							{
//								input.GetValueForSubmit(valueSet);
//							}
//						);
//							                    
//	                    var t = this;
//	                    
//						valueSet.foreachKey(
//							function(key)
//							{
//								console.log("Rendering value for " + key + "...");
//								t.SetCallBackParam(key, valueSet.get(key));
//								console.log("Value for " + key + " rendered for callback.");
//							}
//						);
//						

//						console.log("All input values rendered.");
//						this.SetCallBackParam(this.ServerId + "_submit", "1");
//						this.FireServerEvent("submit");
//						console.log("Server submit initiated.");
//						this._formElement().submit();
//					}
//					else
//					{
//						console.log("Beginning non-ajax submit...");
//						//The following code is a workaround of the ASP.NET built-in form, which
//						// submits all inputs on the page in a single post. We want to contain just the elements
//						// defined by this form in the post data, so we will create a "shadow form" 
//						// in the document and populate with hidden inputs with
//						// same names/values as this form's inputs,
//						// then call submit on the shadow form, then destroy it.
//	                
//						var form = document.createElement("FORM");
//						document.body.appendChild(form);
//						form.action = this._attr("Action");
//						form.method = this._attr("Method");
//						
//						console.log("form element created...");
//						
//						var valueSet = new Reflective.Web.Hashtable();
//	                    this.OnGetValuesForSubmit(valueSet);
//	                    
//	                    console.log("values loaded...");
//	                    
//	                    this._hiddenInputs.foreach(
//							function(input)
//							{
//								input.GetValueForSubmit(valueSet);
//							}
//						);
//						
//						console.log("hidden input values loaded...");
//						
//	                    var t = this;
//	                    
//						valueSet.foreachKey(
//							function(key)
//							{
//								t._createShadowInput(form, key, valueSet.get(key));
//								console.log("shadow input created for: " + key);
//							}
//						);
//	                    
//	                    console.log("shadow inputs created...");
//						this._createShadowInput(form, this.ServerId + "_submit", "1");
//						form.submit();
//					}
				}
            }
        },
        OnGetValuesForSubmit : function(valueSet)
        {
			alert("The form does not submit any values.");
        },
        _createShadowInput : function(parentFormElement, name, value)
        {
            var hidden = document.createElement("INPUT");
            hidden.type = "hidden";
            hidden.name = name;
            hidden.value = value;
            parentFormElement.appendChild(hidden);
        },
        _submitBegin : function()
        {
            this._submitting = true;
            var args = new Reflective.Web.UI.Controls.FormSubmitEventArgs();
            this.OnSubmitBegin(args);
            console.log("_submitBegin complete. args.Continue = " + args.Continue);
            return args.Continue;
        },
        _submitEnd : function(args)
        {
            this._submitting = false;
            this.OnSubmitEnd(args);
        },
        OnSubmit : function()
        {
			console.log(this.id + ".OnSubmit");
			this.FireEvent("onsubmit");
        },
        OnSubmitBegin : function(args)
        {
			this.FireEvent("onsubmitbegin", args);
        },
        OnSubmitEnd : function(args)
        {
			this.FireEvent("onsubmitcomplete", args);
        },
        AllowSubmit : function(allow)
        {
			this.OnAllowSubmit(allow);
        },
        OnAllowSubmit : function(allow) {},
        Cancel : function()
        {
			console.log("Form cancelled.");
			this.OnCancel();
        },
        OnCancel : function() 
        { 
			var args = new Reflective.Web.ContinueEventArgs();
			this.FireEvent("oncancel", args); 
			
			if (args.Continue)
			{
				if (this._attr("confirmOnCancel"))
				{
					YesNoDialog.Show(this._attr("cancelDialogText"), this._attr("cancelDialogTitle"));
					var url = this._attr("cancelUrl");
		            
					YesNoDialog.OnButtonClick(
						function(resultCode)
						{
							if (resultCode == Reflective.Web.UI.DialogResult.Yes)
								window.location.href = url;
						}
					);
				}
			}
        },
        GetInput : function(id)
        {
			if (this._hiddenInputs.containskey(id))
				return this._hiddenInputs.get(id).GetValue();
				
            return this.OnGetInput(id);
        },
        
        OnGetInput : function(id)
        {
			return null;
        },
        //Gets inputs based on the type which can be: "text", "checkbox", "select", "radio", "textarea", "password"
        GetInputsOfType : function(inputType)
		{
			var inputList = new Array();
			this._inputs.foreach(
				function(item)
				{
					if (item.InputType == inputType)
						inputList.add(item);
				}
			);
			
			return inputList;
		},
        _iframeSubmitComplete : function(ajaxResult)
        {
			if (ajaxResult.ResultType == "Error")
			{
				this._submitEnd(new Reflective.Web.UI.Controls.FormErrorEventArgs(ajaxResult));
			}
			else
			{
				this._submitEnd(new Reflective.Web.UI.Controls.FormSuccessEventArgs(ajaxResult));
			}
        },
//        OnCallBackComplete : function(args)
//        {
//            this._submitEnd(args);
//        },
//        OnCallBackError : function(args)
//        {
//            this._submitEnd(args);
//        },
        GetPanel : function(panelId)
        {
			return this._panels.get(panelId);
        },
        SetPanelVisible : function(panelId, visible)
        {
			this.GetPanel(panelId).SetVisible(visible);
        },
        GetPanelVisible : function(panelId)
        {
			return this.GetPanel(panelId).Visible();
        },
        AllowInput : function(allow)
        {
            this.OnAllowInput(allow);  
        },
        OnAllowInput : function(allow)
        {   
        },
        Reset : function()
        {
			this.OnReset();
        },
        OnReset : function()
        {
			this.FireEvent("onreset");
        }
    }
);


Reflective.Web.UI.Controls.FormValidationEventArgs = function()
{
    this.Inherits(Reflective.Web.EventArgs, null);
    this.IsValid = true;
}
Core.setInheritance(Reflective.Web.UI.Controls.FormValidationEventArgs,
    Reflective.Web.EventArgs);
    
Core.extend(Reflective.Web.UI.Controls.FormValidationEventArgs,
    {
        
    }
);

Reflective.Web.UI.Controls.FormSubmitEventArgs = function()
{
    this.Inherits(Reflective.Web.EventArgs, null);
    this.Continue = true;
}
Core.setInheritance(Reflective.Web.UI.Controls.FormSubmitEventArgs,
    Reflective.Web.EventArgs);
    
Core.extend(Reflective.Web.UI.Controls.FormSubmitEventArgs,
    {
        
    }
);

Reflective.Web.UI.Controls.FormSuccessEventArgs = function(ajaxResult)
{
    this.Inherits(Reflective.Web.EventArgs, null);
    this.Message = ajaxResult ? ajaxResult.Message : "";
    this.Params = ajaxResult ? ajaxResult.Params.clone() : null;
    if (this.Params)
    {
		console.log("Form submit success");
		console.log(this.Params.join(" :: ", " = "));
    }
    this.IsError = false;
}
Core.setInheritance(Reflective.Web.UI.Controls.FormSuccessEventArgs,
    Reflective.Web.EventArgs);
    
Core.extend(Reflective.Web.UI.Controls.FormSuccessEventArgs,
    {
        
    }
);

Reflective.Web.UI.Controls.FormErrorEventArgs = function(ajaxResult)
{
    this.Inherits(Reflective.Web.UI.Controls.FormSuccessEventArgs, ajaxResult);
    this.IsError = true;
}

Core.setInheritance(Reflective.Web.UI.Controls.FormErrorEventArgs,
    Reflective.Web.UI.Controls.FormSuccessEventArgs);
    
Core.extend(Reflective.Web.UI.Controls.FormErrorEventArgs,
    {
        
    }
);
Reflective.Web.UI.Controls.Form = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormBase, clientId, serverId, rootElementId);
    this._pageCount = 0;
    
    this._pageClientIds = null;
    this._pageIds = null;
    this._startPageId = null;
    this._pageId = null;
    this._pageCount = 0;
    this._pageIndex = 0;
    
    this._inputs = new Reflective.Web.Hashtable();     
    this._buttons = new Reflective.Web.Hashtable();
    
    this._submitBtns = new Array();
    
    this._submitBtn = null;
    this._cancelBtn = null;
    this._resetBtn = null;
    
    this._allowSubmit = true;
}

Core.setInheritance(Reflective.Web.UI.Controls.Form,
    Reflective.Web.UI.Controls.FormBase);


Core.extend(Reflective.Web.UI.Controls.Form,
    {
    	OnInit: function() 
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnInit");
    		this._initPages();
    		this._findInputs();
			this._findButtons();
			
			if (this._attr("submitOnChg"))
			{
				this.AllowSubmit(false);
			}
    	},
    	_initPages : function()
    	{
    		console.log("Form._initPages");
    		this._pageCount = parseInt(this._attr("pageCount"));
            
            if (this._pageCount != 0)
            {
                this._pageId = this._startPageId = this._attr("startPageId");
                this._pageClientIds = this._attr("pageClientIds").split(';');
                this._pageIds = this._attr("pageIds").split(';');
                this._pageIndex = this.GetPageIndex(this._pageId);
            
            
                var me = this;
                this._pageIds.foreach(
                
                    function(pageId)
                    {
                        me.GetPage(pageId)._formInit();
                    }
                );
            }
    	},
    	_findInputs : function()
        {
			console.log("Form._findInputs");
            var inputs = $("[@formId='" + this.ClientId + "'][@isInput='1']");
            for (var i = 0; i < inputs.length; i++)
            {
				this.OnFoundInput(window[$(inputs[i]).attr("ClientId")]);
            }
           
        },
        _findButtons : function()
        {
			console.log("Form._findButtons");
			var buttons = $("[@formId='" + this.ClientId + "'][@isButton='1']");
            for (var i = 0; i < buttons.length; i++)
            {
				var element = $(buttons[i]);
				this.OnFoundButton(window[element.attr("ClientId")], 
					element.attr("type"));
            }
        },
        OnFoundInput : function(input)
        {
            this._inputs.set(input.ServerId, input);
            input.BindEvent("onvaluechanged", this.id, "_inputValueChanged");
			input.BindEvent("onenterpressed", this.id, "_inputEnterPressed");
			
            console.log("input " + input.ServerId + " (" + input.InputType + ") found.");
        },
        OnFoundButton : function(button, type)
        {
			this._buttons.set(button.id, button);
			console.log("button " + button.id + " found.");
			
			if (type == "submit")
			{
				button.BindEvent("onclick", this.id, "_submitBtnClick");	
				this._submitBtns.add(button);
			}
			else if (type == "cancel")
			{
				button.BindEvent("onclick", this.id, "_cancelClick");
			}
        },
        OnValidate : function()
        {
			var args = new Reflective.Web.UI.Controls.FormValidationEventArgs();
            this.FireEvent("onvalidate", args);
            return args.IsValid;
            
        },
        IsValid : function()
        {
			var inputs = this._inputs.values();
			for (var i = 0; i < inputs.length; i++)
			{
				var input = inputs[i];
				console.log("validating input " + input.id + ".");
				if (!input.IsValid())
				{
					console.log("input " + input.id + " does not validate.");
					return false;
				}
				else
					console.log("input " + input.id + " validates.");
			}
			
			return true;
        },
        SubmitButtons : function() { return this._submitBtns; },
    	_submitBtnClick: function(sender, e) 
    	{
    		//first cancel the submit event on the form 
    		DomHelper.CancelBubble(e);
    		DomHelper.CancelEvent(e);
    		this.Submit(e);
    	},
        _cancelClick : function(sender, e)
        {
			DomHelper.CancelEvent(e);
			DomHelper.CancelBubble(e);
            this.Cancel();
        },
        _inputEnterPressed : function(sender, e)
        {
			if (this._allowSubmit)
				this.Submit(e);
        },
        _inputValueChanged : function(sender)
        {
			this.OnInputValueChanged(sender);
        },
        OnInputValueChanged : function(input)
        {
			this.FireEvent("onvaluechanged", this, input);
			if (this._attr("submitOnChg"))
			{
				var allow = this.IsValid();
				console.log("Form is valid: " + allow);
				this.AllowSubmit(allow);
			}
        },
    	_btnBar: function() { return this._(this._attr("btnBarId")); },
    	OnGetValuesForSubmit : function(valueSet)
    	{
    		this._inputs.foreach(
    			function(item)
    			{
    				console.log("Adding value for " + item.id);
    				item.GetValueForSubmit(valueSet);
    				console.log("Value added: " + valueSet.get(item.requestKeyName()));
    			}
    		);
    	},
    	OnEnterPressed : function(e) { this.Submit(e); },
    	OnAllowSubmit : function(allow)
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnAllowSubmit", allow);
    		
    		this._allowSubmit = allow;
			this.SubmitButtons().foreach(
				function(btn)
				{
					console.log("Setting enabled for: " + btn.id + " (" + allow + ")");
					btn.SetEnabled(allow);
				}
			);
    	},
    	OnAllowInput : function(allow)
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnAllowInput", allow);
    		
    		if (!allow)
                this._saveBtnState();
            
            this._setBtnAllowInput(allow);
    	},
    	OnSubmitBegin : function(args)
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnSubmitBegin", args);
    		if (!args.Continue)
            {
				this._submitting = false;
			}
			return args.Continue;
    	},
    	OnSubmitEnd : function(args)
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnSubmitEnd", args);
    		
    		var form = this;
			this._inputs.foreach(
				function(item)
				{
					item._formSubmitComplete(form, args);
				}
			);
			
    	},
        OnGetInput : function(id)
        {
			return this._inputs.get(id);
        },
        OnAllowInput : function(allow)
        {
            this._inputs.foreach(
                function(input)
                {
                    input.AllowInput(allow);
                }
            );   
        },
        _saveBtnState : function()
        {
            this._buttons.foreach(
                function(button)
                {
                    button._wasDisabled = !button.Enabled();
                }
            );  
        },
        _setBtnAllowInput : function(allow)
        {
            this._buttons.foreach(
                function(button)
                {
                    if (!button._wasDisabled)
                        button.SetEnabled(allow);
                }
            );  
        },
        GetPage : function(pageId)
        {
            return window[this._getPageClientId(pageId)];
        },
        GetPageIndex : function(pageId)
        {
            for (var i = 0; i < this._pageIds.length; i++)
            {
                if (this._pageIds[i] == pageId)
                    return i;
            }
            return -1;
        },
        GetMenuItem : function(pageId)
        {
            return this._("Menu_" + pageId);
        },
        PageCount : function () { return this._pageIds.length; },
        _getPageClientIdIndex : function(pageClientId)
        {
            for (var i = 0; i < this._pageClientIds.length; i++)
            {
                if (this._pageClientIds[i] == pageClientId)
                    return i;
            }
            return -1;
        },
        _getPageIdIndex : function(pageId)
        {
            for (var i = 0; i < this._pageIds.length; i++)
            {
                if (this._pageIds[i] == pageId)
                    return i;
            }
            return -1;
        },
        _getPageClientId : function(pageId)
        {
            return this._pageClientIds[this._getPageIdIndex(pageId)];
        },
        GetNextPageId : function(pageId)
        {
            for (var i = 0; i < this._pageIds.length; i++)
            {
                if (this._pageIds[i] == pageId && i < this._pageIds.length - 1)
                    return this._pageIds[i+1];
            }
            return '';
        },
        GetPrevPageId : function(pageId)
        {
            for (var i = 0; i < this._pageIds.length; i++)
            {
                if (this._pageIds[i] == pageId && i > 0)
                    return this._pageIds[i-1];
            }
            return '';
        },
        ShowPage : function(pageId)
        {
            if (!this._menuItemIsEnabled(pageId)) return;
            
            this.GetPage(this._pageId).Hide();
            this.GetPage(pageId).Show(true, 300);
            
            this.SelectMenuItem(this._pageId, false);
            this.SelectMenuItem(pageId, true);

            this._pageId = pageId;
            this._pageIndex = this.GetPageIndex(pageId);
            
            this.FireEvent("pagechanged", this, new Reflective.Web.UI.Controls.WizardPageEventArgs(pageId));
        },
        EnableMenuItem : function(pageId, enable)
        {
            if (pageId && pageId != this._pageId)
                this.GetMenuItem(pageId).attr("class", enable ? this._attr("menuItemClass") : this._attr("menuItemClassDisabled"));
        },
        SelectMenuItem : function(pageId, select)
        {
            if (pageId)
                this.GetMenuItem(pageId).attr("class", select ? this._attr("menuItemClassSelected") : this._attr("menuItemClass"));
        },
        _menuItemIsEnabled : function(pageId)
        {
            return this.GetMenuItem(pageId).attr("class") != this._attr("menuItemClassDisabled");
        },
		_summaryDiv : function()
		{
			return $("#" + this._attr("summaryClientId"));
		},
		HasSummary : function()
		{
			return this._attr("summaryClientId") != "";
		},
		ToggleSummary : function()
		{
			this.SummaryVisible(!this.SummaryVisible());
		},
		ShowSummary : function()
		{
			this.SummaryVisible(true);
		},
		HideSummary : function()
		{
			this.SummaryVisible(false);
		},
		SummaryVisible : function(visible)
		{
			if (visible == null)
			{
				return this.HasSummary() && this._summaryDiv().css("display") != "none";
			}
			else
			{
				if (!visible)
				{
					this.OnHideSummary();
				}
				else
				{
					this.OnShowSummary();					
				}
			}
		},
		OnShowSummary : function()
		{
			if (!this.HasSummary()) return;
			
			this._("content").hide();
			this._summaryDiv().fadeIn(2000);
			this._("toggleLink").text(this._attr("HideSummaryButtonText"));
		},
		OnHideSummary : function()
		{
			if (!this.HasSummary()) return;
			
			var content = this._("content");
			this._summaryDiv().fadeOut(500, 
				function callback()
				{
					content.fadeIn(1000);
				}
			);
			this._("toggleLink").text(this._attr("ShowSummaryButtonText"));	
		},
		OnReset : function()
		{
			this._formElement()[0].reset();
			this._inputs.foreach(
                function(input)
                {
                    input.Reset();
                }
            );   
		}
    }
);




Reflective.Web.UI.Controls.FormInput = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.AjaxEnabledControl, clientId, serverId, rootElementId);
    this._input = null;
    this._validatorIds = null;
    this._enabledState = false; //stores the enabled/disabled state for when _formEnable / _formDisable is called.
}

Core.setInheritance(Reflective.Web.UI.Controls.FormInput, 
    Reflective.Web.UI.AjaxEnabledControl);
    
Core.extend(Reflective.Web.UI.Controls.FormInput,
    {
        OnInit : function()
        {
            this._input = this.inputElement();
            this._validatorIds = new Array();
            
            var ids = this.validatorIds();
            if (ids)
            {
				this._validatorIds = ids.split(";");
            }
        },
        inputElement : function() { return this._selectById(this.inputElementClientId()); },
        inputElementName : function() { return this._attr("inputName"); },
        inputElementClientId : function() { return this._attr("inputClientId"); },
        originalValueInputElement : function() { return this._selectById(this.originalValueInputClientId()); },
        originalValueInputName : function() { return this.ServerId + "_orig"; },
        originalValueInputClientId : function() { return this.ClientId + "_orig"; },
        validatorIds : function() { return this._attr("validators"); },
        OnEnable : function()
        {
			this.inputElement().attr("disabled", false);
			return true;
        },
        OnDisable : function()
        {
			this.inputElement().attr("disabled", true);
			return true;
        },
        SetValue : function(value)
        {
            this.OnSetValue(value);
            this._checkIfChanged();
        },
        GetValue : function()
        {
            return this.OnGetValue();
        },
        GetOriginalValue : function()
        {
            return this.OnGetOriginalValue();
        },
        OnSetValue : function(value)
        {
            this.inputElement().val(value);
        },
        OnGetValue : function()
        {
            return this.inputElement().val();
        },
        OnGetOriginalValue : function()
        {
            return this.originalValueInputElement().val();
        },
        ResetOriginalValue : function()
        {
			this.originalValueInputElement().val(this.GetValue());
        },
        requestKeyName : function()
        {
            return this.inputElementName();
        },
        _form : function()
        {
            return window[this._attr("formId")];
        },
        _panel : function()
        {
            return window[this._attr("parentPanelId")];
        },
		GetValueForSubmit : function(valueSet)
        {
			this.OnGetValueForSubmit(valueSet);
        },        
        OnGetValueForSubmit : function(valueSet)
        {
			valueSet.set(this.requestKeyName(), this.GetValue());
			this.GetOriginalValueForSubmit(valueSet);
        },
        GetOriginalValueForSubmit : function(valueSet)
        {
			this.OnGetOriginalValueForSubmit(valueSet);
        },        
        OnGetOriginalValueForSubmit : function(valueSet)
        {
            valueSet.set(this.originalValueInputName(), this.GetOriginalValue()); 
        },
        AllowInput : function(allow) //this method gets called by the form only, and is used to disable the form temporarily
        {
            this.OnAllowInput(allow);
        },
        OnAllowInput : function(allow)
        {
            if (!allow)
            {
                this._enabledState = this.Enabled();
                if (this._enabledState)
                    this.Disable(true);
            }
            else
            {
                if (!this._enabledState)
                    this.SetEnabled(this._enabledState);
            }
        },
        _formSubmitComplete : function(sender, args)
        {
			if (!args.IsError)
			{
				this.ResetOriginalValue();
			}
        },
        dualMode : function()
        {
			return this._attr("dualMode");
        },
        _checkIfChanged : function()
        {
			if (this.ValueChanged())
				this.ValueChanged(true);
        },
        ValueChanged : function(changed)
        {
			if (changed == null)
				return this.GetValue() != this.GetOriginalValue();
			else if (changed)
				this.OnValueChanged();
        },
        OnValueChanged : function()
        {
			this.FireEvent("onvaluechanged", null);
        },
        Validate : function()
        {
			return this.OnValidate();
        },
        OnValidate : function()
        {
			for (var i = 0; i < this._validatorIds.length; i++)
			{
				if (!window[this._validatorIds[i]].Validate())
				{
					console.log(this.id + " does not pass validation.");
					return false;
				}
			}
			
			console.log(this.id + " does passes validation.");
			return true;
        },
        IsValid : function()
        {
			return this.Validate();
        },
        OnSetStyle : function(styleName, value)
        {
			this.inputElement().css(styleName, value);
        },
        OnGetStyle : function(styleName)
        {
			return this.inputElement().css(styleName);
        },
        OnKeyPress : function(e)
        {
            if (DomHelper.eventKeyCode(e) == Environment.KeyCodes.Enter) 
                return this.OnEnterPressed(e);
                
            return true;
        },
        OnEnterPressed : function(e)
        {
			this.FireEvent("onenterpressed", e);
        },
        Reset : function()
        {
			this.OnReset();
        },
        OnReset : function()
        {
			this.SetValue("");
        }
        
    }
);


Reflective.Web.UI.Controls.FormControl = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormInput, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.FormControl, 
    Reflective.Web.UI.Controls.FormInput);
    
Core.extend(Reflective.Web.UI.Controls.FormControl, 
    {
        OnSetClass : function(className)
        {
            this.inputElement().attr("class", className);
        },
        OnGetClass : function()
        {
            return this.inputElement().attr("class");
        }
    }
);

Reflective.Web.UI.Controls.FormAutoLabelInput = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.FormAutoLabelInput, 
    Reflective.Web.UI.Controls.FormControl);
    
Core.extend(Reflective.Web.UI.Controls.FormAutoLabelInput,
    {
        label : function(htmlOrText)
        {
            if (htmlOrText)
                this._("label").html(htmlOrText);
            else
                return this._("label").html();
        }
    }
);
Reflective.Web.UI.Controls.TextInput = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormAutoLabelInput, clientId, serverId, rootElementId);
    this.InputType = "text";
    this._isSingleLine = true;
    this._waterMarkVisible = false;
}

Core.setInheritance(Reflective.Web.UI.Controls.TextInput, 
    Reflective.Web.UI.Controls.FormAutoLabelInput);
    
Core.extend(Reflective.Web.UI.Controls.TextInput,
    {
        OnInit : function()
        {
            this.CallBase(Reflective.Web.UI.Controls.FormAutoLabelInput, "OnInit");
            this._setWaterMark();
        },
        OnKeyUp : function(e)
        {
			DomHelper.CancelBubble(e);
			
			if (this._isSingleLine && DomHelper.eventKeyCode(e) == Environment.KeyCodes.Enter)
				return false;
			
			this._checkIfChanged();
			
            return true;
        },
        OnFocus : function(e)
        {
            if (this._attr("focusClass"))
            {
                this.SetClass(this._attr("focusClass"));
            }
            
            this._clearWaterMark();
            this.inputElement().focus();
            return true;
        },
        OnBlur : function(e)
        {
            this.SetClass(this._attr("mainClass"));
            this._setWaterMark();
            return true;
        },
        OnKeyPress : function(e)
        {
			if (!this.CallBase(Reflective.Web.UI.Controls.FormInput, "OnKeyPress", e))
				return false;
				
            var keyCode = DomHelper.eventKeyCode(e);
            
            if (keyCode == Environment.KeyCodes.Tab
                || keyCode == Environment.KeyCodes.Enter
                || keyCode == Environment.KeyCodes.Backspace) 
                return true;
                
            return !this._attr("allowedChars")
                || this._attr("allowedChars").indexOf(String.fromCharCode(DomHelper.eventKeyCode(e))) > -1;
        },
        OnEnterPressed : function(e)
        {
			if (this._isSingleLine)
				this.CallBase(Reflective.Web.UI.Controls.FormInput, "OnEnterPressed", e);
			
			return true;
        },
        _setWaterMark : function()
        {
            if (!this._attr("waterMark"))
                return;
            
            if (!this._waterMarkVisible && this.GetValue() == "")
            {
                var input = this.inputElement();
                this.SetValue(this._attr("waterMark"));
                this._attr("mainColor", input.css("color") || "");
                input.css("color", this._attr("waterMarkColor"));
                this._waterMarkVisible = true;
            }
        },
        _clearWaterMark : function()
        {
            if (!this._attr("waterMark"))
                return;
            
            if (this._waterMarkVisible /*this.GetValue() == this._attr("waterMark")*/)
            {
                if (this._attr("mainColor"))
                    this.inputElement().css("color", this._attr("mainColor"));
                    
                this.SetValue("");
                this._waterMarkVisible = false;
            }
        },
        Clear : function() { this.SetValue(""); this._setWaterMark(); },
        OnGetValue : function()
        {
            if (this._waterMarkVisible)
                return "";
            else
                return this.inputElement().val();
        },
        Select : function()
        {
            this.SetFocus();
            this.inputElement().select();
        }
    }
);

Reflective.Web.UI.Controls.TypeAheadTextInput = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.TextInput, clientId, serverId, rootElementId);
    this._optionIndex = -1;
}

Core.setInheritance(Reflective.Web.UI.Controls.TypeAheadTextInput, 
    Reflective.Web.UI.Controls.TextInput);
    
Core.extend(Reflective.Web.UI.Controls.TypeAheadTextInput,
    {
		OnInit : function()
        {
            this.CallBase(Reflective.Web.UI.Controls.TextInput, "OnInit");
        },
        _optionsDiv : function() { return this._("optionsDiv"); },
        _optionCssClass : function() { return this._attr("optionClass"); },
        _optionSelCssClass : function() { return this._attr("optionSelClass"); },
        OnKeyUp : function(e)
        {
			if (!this.CallBase(Reflective.Web.UI.Controls.TextInput, "OnKeyUp", e))
				return false;
			
			if (Environment.KeyIsAlphaNumeric(e.keyCode))
			{
				var val = this.GetValue();
				if (val.length >= this._minCharsForSearch())
				{
					this._beginSearch(val);
				}
			}
            return true;
        },
        OnKeyPress : function(e)
        {
			if (this.OptionsVisible())
			{
				if (e.keyCode == Environment.KeyCodes.Enter)
				{
					this.SetValue(this.SelectedValue());
					this.HideOptions();
					return false;
				}
			}
			if (!this.CallBase(Reflective.Web.UI.Controls.TextInput, "OnKeyPress", e))
				return false;
			
			if (e.keyCode == Environment.KeyCodes.UpArrow)
			{
				this.SelectPrevOption();
			}
			else if (e.keyCode == Environment.KeyCodes.DownArrow)
			{
				this.SelectNextOption();
			}
			return true;
        },
        SelectNextOption : function()
        {
			if (this.OptionsVisible())
			{
				this._optionIndex++;
				if (this._optionIndex >= this.OptionCount())
					this._optionIndex = 0;
					
				this.SelectOption(this._optionIndex);
			}
        },
        SelectPrevOption : function()
        {
			if (this.OptionsVisible())
			{
				this._optionIndex--;
				if (this._optionIndex < 0)
					this._optionIndex = this.OptionCount() - 1;
					
				this.SelectOption(this._optionIndex);
			}
        },
        SelectOption : function(index)
        {
			var d = this._optionsDiv();
			d.find("[selected='1']").attr( { "selected" : "", "class" : this._optionCssClass() } );
			d.find("[index='" + index + "']").attr({ "selected" : "1", "class" : this._optionSelCssClass() });
        },
        SelectedValue : function()
        {
			var o = this._optionsDiv().find("[selected='1']");
			return o.length > 0 ? o.attr("optionValue") : "";
        },
        OptionClicked : function(optionElement, e)
        {
			DomHelper.CancelBubble(e);
			console.log($(optionElement).attr("index"));
			this.SetValue($(optionElement).attr("optionValue"));
			this.HideOptions();
        },
        _minCharsForSearch : function() { return parseInt(this._attr("minChars")); },
        _beginSearch : function(value)
        {
			this.ShowOptions();
			this.SetCallBackParam("value", value);
			this.FireServerEvent("search");
        },
        OnCallBackComplete : function(sender, args)
        {
			this._optionsDiv().html(args.responseText);
			console.log("Options returned: " + this.OptionCount());
        },
        OnCallBackError : function(sender, args)
        {
			Alert.Show(args.Error.Message);
        },
        OptionCount : function()
        {
			if (!this.OptionsVisible())
				return 0;
			else
				return this._optionsDiv().find("div").length;
        },
        OnBlur : function(e)
        {
			if (!this.CallBase(Reflective.Web.UI.Controls.TextInput, "OnBlur", e))
				return false;
		
			this.HideOptions();
            return true;
        },
        ShowOptions : function()
        {
			if (!this.OptionsVisible())
			{
				this._optionIndex = -1;
				var offset = this.inputElement().offset();
				offset.top += this.inputElement().outerHeight();
				
				$(document.body).append(this._optionsDiv());
				this._optionsDiv().css(offset);
				this._optionsDiv().fadeIn();
			}
        },
        HideOptions : function()
        {
			if (this.OptionsVisible())
				this._optionsDiv().fadeOut();
        },
        OptionsVisible : function()
        {
			return this._optionsDiv().css("display") != "none";
        }
    }
);
Reflective.Web.UI.Controls.TextArea = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.TextInput, clientId, serverId, rootElementId);
    this.InputType = "textarea";
    this._isSingleLine = false;
}

Core.setInheritance(Reflective.Web.UI.Controls.TextArea, 
    Reflective.Web.UI.Controls.TextInput);
    
Core.extend(Reflective.Web.UI.Controls.TextArea,
    {
    }
);


Reflective.Web.UI.Controls.Button = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
	this.InputType = "button";   
	this._progressDimensions = [];
}

Core.setInheritance(Reflective.Web.UI.Controls.Button, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.Controls.Button, 
    {
		OnInit : function() 
		{
			if (this._attr("formId")
				&& this._attr("progOnClick"))
			{
				var id = this._attr("formId");
				window[id].BindEvent("onsubmitbegin", this.id, "_formSubmitBegin");
				window[id].BindEvent("onsubmitcomplete", this.id, "_formSubmitEnd");
				this._progressDimensions = 
					[this.$el().outerWidth(), this.$el().outerHeight()];
			}
		},
        SetText : function(text) { this.$el().val(text); },
        GetText : function() { return this.$el().val(); },
        OnEnable : function() { this.$el().attr("disabled", false); return true; },
        OnDisable : function() { this.$el().attr("disabled", true); return true; },
        _formSubmitBegin : function(sender, args)
        {
			this._showProgress(true);
        },
        _formSubmitEnd : function(sender, args)
        {
			window.setTimeout(this.id + "._showProgress(false);", this.ProgressHideDelay);
        },
        _showProgress : function(show)
        {
			if (show)
			{
				this.$el().hide();
				this._("progressDiv").show();
				this._("progressDiv").css("width", this._progressDimensions[0] + "px");
				this._("progressDiv").css("height", this._progressDimensions[1] + "px");
			}
			else
			{
				this._("progressDiv").hide();
				this.$el().show();
			}
        }
    }
    
);

Reflective.Web.UI.Controls.InputButton = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.Button, sClientId, sServerId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.InputButton, 
    Reflective.Web.UI.Controls.Button);
    
Core.extend(
    Reflective.Web.UI.Controls.InputButton, 
    {
    }
);


Reflective.Web.UI.Controls.SubmitButton = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.Button, sClientId, sServerId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.SubmitButton, 
    Reflective.Web.UI.Controls.Button);
    
Core.extend(
    Reflective.Web.UI.Controls.SubmitButton, 
    {
    }
);

Reflective.Web.UI.Controls.CancelButton = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.Button, sClientId, sServerId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.CancelButton, 
    Reflective.Web.UI.Controls.Button);
    
Core.extend(
    Reflective.Web.UI.Controls.CancelButton, 
    {
    }
);

Reflective.Web.UI.Controls.LinkButton = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.Button, sClientId, sServerId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.LinkButton, 
    Reflective.Web.UI.Controls.Button);
    
Core.extend(
    Reflective.Web.UI.Controls.LinkButton, 
    {
		OnInit : function()
		{
		},
		OnClick : function(e)
		{
			if (this._attr("targetUrl"))
			{
				DomHelper.CancelBubble(e);
				window.location.href = this._attr("targetUrl");
				return false;
			}
			else
				return this.CallBase(Reflective.Web.UI.Controls.Button, "OnClick", e);
		},
		OnEnable : function() { this.$el().attr("disabled", false); return true; },
        OnDisable : function() { this.$el().attr("disabled", true); return true; },
		TargetUrl : function(value) 
		{ 
			if (value)
				this._attr("targetUrl", value);
			else
				return this._attr("targetUrl"); 
		},
		Text : function(value)
		{
			if (value)
			{
				this._("text").html(value);
			}
			else
			{
				return this._("text").html();
			}
		}
    }
);


Reflective.Web.UI.Controls.LinkButtonPanel = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
    this._buttons = new Reflective.Web.Hashtable();
}

Core.setInheritance(Reflective.Web.UI.Controls.LinkButtonPanel,
	Reflective.Web.UI.ReflectiveControl);
	
Core.extend(Reflective.Web.UI.Controls.LinkButtonPanel,
	{
		OnInit : function()
		{
			var buttonIds = this._attr("ButtonIds");
			if (buttonIds)
			{
				var ids = buttonIds.split(";");
				var t = this;
				ids.foreach(
					function(id)
					{
						t._buttons.add(id, window[id]);
					}
				);
			}
		},
		Buttons : function()
		{
			return this._buttons.values();
		}
	}
);
Reflective.Web.UI.Controls.CheckBox = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormInput, clientId, serverId, rootElementId);
    this.InputType = "checkbox";
}

Core.setInheritance(Reflective.Web.UI.Controls.CheckBox, 
    Reflective.Web.UI.Controls.FormInput);
    
Core.extend(Reflective.Web.UI.Controls.CheckBox,
    {
        SetChecked : function(value)
        {
            this.inputElement().attr("checked", value);
            this.OnCheckedChanged();
        },
        GetChecked : function()
        {
			if (this.inputElement().is(':checked'))
                return true;
            
            return false;
        },
        Checked : function(value)
        {
			if (value != null)
				this.SetChecked(value);
			else
				return this.GetChecked();
        },
        Click : function(e)
        {
            this.FireEvent("onclick");
            this.OnCheckedChanged();
        },
        OnGetValue : function()
        {
            if (this.GetChecked())
                return this.inputElement().val();
            else
                return "";
        },
        OnCheckedChanged : function()
        {
            this.FireEvent("checkedchanged", this.GetChecked());
            this._checkIfChanged();
        }
    }
);


Reflective.Web.UI.Controls.BaseContentBlock = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
    this._moduleId = "";
}

Core.setInheritance(Reflective.Web.UI.Controls.BaseContentBlock, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.Controls.BaseContentBlock, 
    {
        OnInit : function()
        {
        },
        _textDiv : function() { return this._("text"); },
        _bodyDiv : function() { return this._("body"); },
        SetContent : function(text) { this._bodyDiv().html(text); },
        GetContent : function() { return this._bodyDiv().html(); },
        SetText : function(text) { this._textDiv() ? this._textDiv().html(text) : ""; },
        GetText : function() { return this._textDiv() ? this._textDiv().html() : ""; },
        _expanderIcon : function()
        {
            return this._("expander");
        },
        ExpanderClick : function()
        {
            this.ToggleState();
        },
        Expanded : function()
        {
            return this._attr("Expanded") == "1";
        },
        Expand : function()
        {
            if (this.Expanded()) return;
            this._attr("Expanded", "1");
            this._expanderIcon().attr("src", this._getExpIconUrl(true));
            this._bodyDiv().slideDown();
        },
        Collapse : function()
        {
            if (!this.Expanded()) return;
            this._attr("Expanded", "");
            this._expanderIcon().attr("src", this._getExpIconUrl(false));
            this._bodyDiv().slideUp();
        },
        ToggleState : function()
        {
            if (!this.Expanded())
                this.Expand();
            else
                this.Collapse();
        },
        _getExpIconUrl : function(panelExpanded)
        {
            var src = this._expanderIcon().attr("src");
            var ext = src.substring(src.lastIndexOf("."));
            var rootName = src.substring(0, src.length - ext.length - 1);
            rootName = rootName.substring(0, rootName.lastIndexOf("."));
            return rootName + (panelExpanded ? ".collapse" : ".expand") + ext;
        }
    }
    
);


Reflective.Web.UI.Controls.ContentBlock = function(sClientId, sServerId)
{
    this.Inherits(Reflective.Web.UI.Controls.BaseContentBlock, sClientId, sServerId);
    this._moduleId = "";
}

Core.setInheritance(Reflective.Web.UI.Controls.ContentBlock, 
    Reflective.Web.UI.Controls.BaseContentBlock);
    
Core.extend(
    Reflective.Web.UI.Controls.ContentBlock, 
    {
        OnInit : function()
        {
        },
        ModuleInstance : function() { return window[this._moduleId]; }
    }
    
);


Reflective.Web.UI.Controls.ContentRotator = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
    this._delay = 5;
    this._index = 0;
    this._divs = null;
    this._infinite = false;
    this._playing = true;
    this._intervalId = 0;
    this._hideIndex = 0;
}

Core.setInheritance(Reflective.Web.UI.Controls.ContentRotator, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.Controls.ContentRotator, 
    {
        OnInit : function()
        {
            this._divs = this.$el().find("div[rotatorId='" + this.ClientId + "']");
            this._delay = this._attr("Delay");
            this._intervalId = window.setInterval(this.ClientId + "._loadNext();", this._delay * 1000);
        },
        Play : function()
        {
            this._loadNext();
            this._intervalId = window.setInterval(this.ClientId + "._loadNext();", this._delay * 1000);
            this._playing = true;
            $g(this.ClientId + "_btnLink").innerHTML = this._attr("PauseBtnText");
        },
        Pause : function()
        {
            window.clearInterval(this._intervalId);
            this._playing = false;
            
            $g(this.ClientId + "_btnLink").innerHTML = this._attr("ResumeBtnText");
        },
        _incrementIndex : function()
        {
            this._hideIndex = this._index;
            this._index++;
        },
        _loadNext : function()
        {
            this._incrementIndex();
            
            if (this._index >= this._divs.length) this._index = 0;
            $(this._divs.get(this._hideIndex)).hide();
            $(this._divs.get(this._index)).fadeIn(1000);
        },
        _pauseResume : function()
        {
            if (this._playing)
                this.Pause();
            else
                this.Play();
        },
        _nextClick : function()
        {
            if (this._playing) this.Pause();
            this._loadNext();
        }
    }
    
);

Reflective.Web.UI.Controls.DropDownList = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormAutoLabelInput, clientId, serverId, rootElementId);
    this.InputType = "dropdown";
}

Core.setInheritance(Reflective.Web.UI.Controls.DropDownList, 
    Reflective.Web.UI.Controls.FormAutoLabelInput);
    
Core.extend(Reflective.Web.UI.Controls.DropDownList,
    {
        OnFocus : function(e)
        {
            if (this._attr("focusClass"))
            {
                this.SetClass(this._attr("focusClass"));
            }
        },
        OnBlur : function(e)
        {
            this.SetClass(this._attr("mainClass"));
        },
        Change : function(e)
        {
            this.FireEvent("onchange", this);
            this._checkIfChanged();
        }
        
    }
);

Reflective.Web.UI.Controls.FileInput = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormAutoLabelInput, clientId, serverId, rootElementId);
    this.InputType = "file";
}

Core.setInheritance(Reflective.Web.UI.Controls.FileInput, 
    Reflective.Web.UI.Controls.FormAutoLabelInput);
    
Core.extend(Reflective.Web.UI.Controls.FileInput,
    {
        OnInit : function()
        {
            this.CallBase(Reflective.Web.UI.Controls.FormAutoLabelInput, "OnInit");
            this.OnChange();
        },
        OnChange : function(e)
        {
			this._("displayValue").html(this.GetValue());
			return true;
        },
        OnDisable : function()
        {
			this._("button").attr("disabled", true);
			return true;
        },
        OnReset : function()
        {
			this.OnChange();
        }
    }
);


Reflective.Web.UI.Controls.FileUploadForm = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.AjaxEnabledControl, clientId, serverId, rootElementId);
    this.InputType = "file";
}

Core.setInheritance(Reflective.Web.UI.Controls.FileUploadForm, 
    Reflective.Web.UI.AjaxEnabledControl);
    
Core.extend(Reflective.Web.UI.Controls.FileUploadForm,
    {
        OnInit : function()
        {
            this.CallBase(Reflective.Web.UI.ReflectiveControl, "OnInit");
            this._syncState();
            this._iframe().attr("width", "100%");
            this._iframe().attr("height", "100");
        },
        _syncState : function()
        {
			this._submitBtn().css("display", this.Value() ? "" : "none");
        },
        _form : function() { return this._("form"); },
        _input : function() { return this._("file"); },
        _submitBtn : function() { return this._("submitBtn"); },
        _iframe : function() { return this._("iframe"); },
        _submitClick : function(sender, e)
        {
			this._form().submit();
        },
        Value : function()
        {
			return this._input().val();
        },
        OnChange : function(e)
        {
			this._("displayValue").html(this.Value());
			this._syncState();
			return true;
        },
        OnDisable : function()
        {
			this._("button").attr("disabled", true);
			return true;
        },
        _submitComplete : function(result) 
        { 
			alert("Result: " + result.ResultType);
			if (result.ResultType == "Error")
				this.OnError(result);
			else
				this.OnSuccess(result);
		},
        OnError : function(result) {this.FireEvent("onerror", result); },
        OnSuccess : function(result) { this.FireEvent("onsuccess", result); }
    }
);



Reflective.Web.UI.Controls.FormInputValidator = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
    this._input = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.FormInputValidator, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.FormInputValidator,
    {
		OnInit : function()
		{
			var trigger = this.TriggerType();
			var eventName = "";
		
			if (trigger == "KeyUp")
				eventName = "onkeyup";
			else if (trigger == "Click")
				eventName = "onclick";
			else if (trigger == "Focus")
				eventName = "onfocus";
			else if (trigger == "Blur")
				eventName = "onblur";
			else if (trigger == "KeyPress")
				eventName = "onkeypress";
			
			if (eventName)
				this.input().BindEvent(eventName, this.id, "_handleTrigger");	
			
		},
		_handleTrigger : function(sender, args)
		{
			console.log(this.input().id + " has triggered validation.");
			this.Validate();
		},
		Validate : function()
		{
			var args = new Reflective.Web.UI.Controls.InputValidationArgs();
			this.OnValidate(args);
			if (!args.IsValid)
				this.OnValidationFailed();
			else
				this.OnValidationPassed();
			
			console.log("validation passed: " + args.IsValid);
			
			return args.IsValid;
			
		},
		OnValidate : function(args)
		{
		},
		OnValidationFailed : function()
		{
			this._setDisplayState(false);
		},
		OnValidationPassed : function()
		{
			this._setDisplayState(true);
		},
		_setDisplayState : function(valid)
		{
			var v = this._validDisplay();
			var i = this._invalidDisplay();
			if (valid)
			{
				if (v) v.show();
				if (i) i.hide();
			}
			else
			{
				if (v) v.hide();
				if (i) i.show();
			}
			
			this._runActions(valid);
		},
		_runActions : function(validState)
		{
			var actionIds = this._attr("actionIds");
			console.log("actionIds = " + actionIds);
			if (actionIds)
			{
				var idArray = actionIds.split(";");
				console.log("actions count: " + idArray.length);
				
				var input = this.input();
				
				idArray.foreach(
					function(id)
					{
						window[id].Run(input, validState);
					}
				);
			}
		},
		_validDisplay : function()
		{
			if (this._attr("validDisplay"))
				return this._("validDisplay");
			else
				return null;
		},
		_invalidDisplay : function()
		{
			if (this._attr("invalidDisplay"))
				return this._("invalidDisplay");
			else
				return null;
		},
		input : function()
		{
			return window[this._attr("inputId")];
		},
		TriggerType : function() { return this._attr("trigger"); }
    }
);

Reflective.Web.UI.Controls.InputValidationArgs = function()
{
	this.IsValid = true;
}

Reflective.Web.UI.Controls.InputRegExpValidator = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormInputValidator, clientId, serverId, rootElementId);
    this.Expression = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.InputRegExpValidator, 
    Reflective.Web.UI.Controls.FormInputValidator);
    
Core.extend(Reflective.Web.UI.Controls.FormInputValidator,
    {
		OnValidate : function(args)
		{
			if (this.input().GetValue() != "")
				args.IsValid = this.Expression.test(this.input().GetValue());
			else
				args.IsValid = true;
		}
	}
);

Reflective.Web.UI.Controls.EmailAddressValidator = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.InputRegExpValidator, clientId, serverId, rootElementId);
    this.Expression = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.EmailAddressValidator, 
    Reflective.Web.UI.Controls.InputRegExpValidator);
    
Core.extend(Reflective.Web.UI.Controls.EmailAddressValidator,
    {
		
	}
);

Reflective.Web.UI.Controls.FormInputValidatorAction = function(clientId, serverId, rootElementId)
{
	this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.FormInputValidatorAction, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.FormInputValidatorAction,
    {
		TriggerType : function() { return this._attr("trigger"); },
		Run : function(targetInput, validState)
		{
			this.OnRun(targetInput, validState);
		},
		OnRun : function(targetInput, validState)
		{
		}
	}
);

Reflective.Web.UI.Controls.InputValidatorSetClassAction = function(clientId, serverId, rootElementId)
{
	this.Inherits(Reflective.Web.UI.Controls.FormInputValidatorAction, clientId, serverId, rootElementId);
	this._origClass = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.InputValidatorSetClassAction, 
    Reflective.Web.UI.Controls.FormInputValidatorAction);
    
Core.extend(Reflective.Web.UI.Controls.InputValidatorSetClassAction,
    {
		OnRun : function(targetInput, validState)
		{
			if (this._origClass == null)
			{
				this._origClass = targetInput._attr("class");
			}
			if (validState)
				targetInput.SetClass(this._origClass);
			else
				targetInput.SetClass(this._attr("cssClassValue"));
		}
	}
);

Reflective.Web.UI.Controls.InputValidatorSetStyleAction = function(clientId, serverId, rootElementId)
{
	this.Inherits(Reflective.Web.UI.Controls.FormInputValidatorAction, clientId, serverId, rootElementId);
	this._origStyle = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.InputValidatorSetStyleAction, 
    Reflective.Web.UI.Controls.FormInputValidatorAction);
    
Core.extend(Reflective.Web.UI.Controls.InputValidatorSetStyleAction,
    {
		OnRun : function(targetInput, validState)
		{
			console.log("InputValidatorSetStyleAction.OnRun");
			console.log("stylename = " + this._attr("styleName"));
			if (this._origStyle == null)
			{
				this._origStyle = targetInput.GetStyle(this._attr("styleName"));
				console.log("originalstyle = '" + this._origStyle + "'");
			}
			if (validState)
				targetInput.SetStyle(this._attr("styleName"), this._origStyle);
			else
				targetInput.SetStyle(this._attr("styleName"), this._attr("styleValue"));
				
			console.log("new style = '" + targetInput.GetStyle(this._attr("styleName")) + "'");
		}
	}
);

Reflective.Web.UI.Controls.FormLayoutPanel = function(clientId, serverId, rootElementId)
{
	this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.FormLayoutPanel, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.FormLayoutPanel,
    {
		OnInit : function()
		{
			
		},
		_form : function()
		{
			return window[this._attr("formId")];
		},
		_inputEnterPressed : function(e)
		{
			this.OnInputEnterPressed(e);
		},
		OnInputEnterPressed : function(e)
		{
			this._form().OnEnterPressed(e);
		},
		Expand : function()
		{
			this.Expanded(true);
		},
		Collapse : function()
		{
			this.Expanded(false);
		},
		Expanded : function(value)
		{
			if (value == null)
			{
				return this._attr("Expanded") == "true";
			}
			else
			{
				this._attr("Expanded", value ? "true" : "false");
				
				if (!value)
				{
					this.OnCollapse();
				}
				else
				{
					this.OnExpand();					
				}
			}
		},
		ToggleView : function()
		{
			this.Expanded(!this.Expanded());
		},
		OnExpand : function()
		{
			this._("content").fadeIn(1000);
		},
		OnCollapse : function()
		{
			this._("content").hide();
		},
		GetInput : function(id)
		{
			return this.OnGetInput(id);
		},
		OnGetInput : function(id)
		{
			var element = this.$el().find("[@ServerId='" + id + "'][@isInput='1']");
			
			if (element)
				return window[$(element).attr("ClientId")];
			else
				return null;
		}
    }
);


Reflective.Web.UI.Controls.FormPage = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
    this._isComplete = false;
}

Core.setInheritance(Reflective.Web.UI.Controls.FormPage,
    Reflective.Web.UI.ReflectiveControl);
    

Core.extend(Reflective.Web.UI.Controls.FormPage,
    {
        OnInit : function()
        {
        },
        _formInit : function()
        {
            this.OnFormInit();
        },
        OnFormInit : function() { this.FireEvent("forminit", this); },
        Form : function() { return window[this._attr("formClientId")]; },
        GetInput : function(id)
        {
            return this.Form().GetInput(id);
        },
        IsComplete : function(isComplete)
        {
            if (isComplete != null)
            {
                if (this._isComplete != isComplete)
                {
                    this._isComplete = isComplete;
                    this.FireEvent("oncompletechanged", this, isComplete);
                }
            }
            else
            {
                var args = new Reflective.Web.UI.Controls.FormPageCompleteEventArgs(this);
                this.FireEvent("oncheckcomplete", this, args);
                
                if (args.MarkComplete != null) //this means the event was handled...
                    this._isComplete = args.MarkComplete;
                    
                return this._isComplete;
            }
        }
    }
);

Reflective.Web.UI.Controls.FormPageCompleteEventArgs = function(page)
{
    this.page = page;
    this.MarkComplete = null;
}

Reflective.Web.UI.Controls.FormUserControlPage = function(clientId, typeName)
{
    this.Inherits(Reflective.Web.UI.UserControl, clientId, typeName);
    this._formPageClientId = "";
    this.FormPage = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.FormUserControlPage,
    Reflective.Web.UI.UserControl);
    
Core.extend(
    Reflective.Web.UI.Controls.FormUserControlPage, 
    {
        OnInit : function() 
        {
            this.FormPage = window[this._formPageClientId];
            this.FormPage.BindEvent("forminit", this.id, "_formInit");
            this.FormPage.BindEvent("oncheckcomplete", this.id, "_checkComplete");
        },
        _formInit : function()
        {
            this.OnFormInit();
        },
        _checkComplete : function(page, args)
        {
            var isComplete = this.OnCheckComplete();
            if (isComplete != null)
                args.MarkComplete = isComplete;
        },
        OnCheckComplete : function() { return null; },
        OnFormInit : function() {},
        GetInput : function(id)
        {
            return this.FormPage.GetInput(id);
        },
        IsComplete : function(isComplete)
        {
            return this.FormPage.IsComplete(isComplete);
        }
    }
    
);

Reflective.Web.UI.Controls.HiddenInput = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormInput, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.HiddenInput, 
    Reflective.Web.UI.Controls.FormInput);
    
Core.extend(Reflective.Web.UI.Controls.HiddenInput,
    {
        OnGetOriginalValueForSubmit : function(valueSet)
        {
        }
    }
);

Reflective.Web.UI.Controls.HtmlEditor = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormAutoLabelInput, clientId, serverId, rootElementId);
    this.InputType = "html";
    this._initialValue = "";
}

Core.setInheritance(Reflective.Web.UI.Controls.HtmlEditor, 
    Reflective.Web.UI.Controls.FormAutoLabelInput);
    
Core.extend(Reflective.Web.UI.Controls.HtmlEditor,
    {
        OnInit : function()
        {
            this.CallBase(Reflective.Web.UI.Controls.FormAutoLabelInput, "OnInit");
        	console.log("initializing tinymce");
			var mytheme = this.EditorTheme().toLowerCase();
			var t = this;
			tinyMCE.init(
					{ 
					mode : 'exact', theme : mytheme, elements : this.inputElementClientId() ,
					theme_advanced_toolbar_location : "top",
					theme_advanced_toolbar_align : "left",
					oninit : this.id + "._editorInit"
					}
				);
        },
        _editorInit : function()
        {
			this.SetValue("<b>Hello!</b>");
			var t = this;
			var ed = this._editor();
			ed.onKeyUp.add(function(ed, e) { t.KeyUp(e); });
			ed.onClick.add(function(ed, e) { t.Click(e); });
			ed.onKeyPress.add(function(ed, e) { t.KeyPress(e); });
			if (this._initialValue) this.SetValue(this._initialValue);
        },
        _editor : function() { return tinymce.EditorManager.get(this.inputElementClientId()); },
        OnKeyUp : function(e)
        {
			return true;
        },
        Clear : function() { this.SetValue(""); },
        OnGetValue : function()
        {
            if (this._editor()) return this._editor().getContent();
            
            return "";
        },
        OnSetValue : function(value)
        {
			if (this._editor())
				this._editor().setContent(value);
			else
				this._initialValue = value;
        },
        Select : function()
        {
			this.SetFocus();
        },
        OnFocus : function(e)
        {
			if (this._editor())
				this._editor().focus();
            
			return true;
        },
        EditorTheme : function() { return this._attr("htmlTheme"); },
        
    }
);


Reflective.Web.UI.Controls.IFramePanel = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.BaseContentBlock, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.IFramePanel, 
    Reflective.Web.UI.Controls.BaseContentBlock);
    
Core.extend(Reflective.Web.UI.Controls.IFramePanel,
    {
        OnInit : function()
        {
            
        },
        _contentSrc : function() { return this._attr("ContentSrc"); },
        _iframe : function() { return this._("iframe"); },
        Refresh : function()
        {
            this._iframe()[0].location = this._contentSrc();
        }
    }
);


Reflective.Web.UI.Controls.ImageMontage = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
    this._delay = 5;
    this._imgIndex = 0;
    this._images = null;
    this._infinite = false;
}

Core.setInheritance(Reflective.Web.UI.Controls.ImageMontage, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.Controls.ImageMontage, 
    {
        OnInit : function()
        {
            this._images = this.$el().find("img[montageId='" + this.ClientId + "']");
            this._delay = this._attr("delay");
            
            this._infinite  = this._attr("InfiniteLoop") == "1";
            if (!this._infinite)
            {
                DomHelper.AttachEventString(this._images[this._images.length -1], "onclick", this.ClientId + "._loadNext");
                this._images[this._images.length -1].style.cursor = "hand";
            }
            window.setTimeout(this.ClientId + "._loadNext();", this._delay * 1000);
        },
        _loadNext : function()
        {
            var hideIndex = this._imgIndex;
            this._imgIndex++;
            
            if (this._imgIndex >= this._images.length) this._imgIndex = 0;
            $(this._images.get(hideIndex)).fadeOut(1000);
            $(this._images.get(this._imgIndex)).fadeIn(2000);
            
            if (this._infinite || this._imgIndex < this._images.length - 1)
                window.setTimeout(this.ClientId + "._loadNext();", this._delay * 1000);
        }
    }
    
);

Reflective.Web.UI.Controls.LinkPhrase = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.LinkPhrase, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.LinkPhrase,
    {
        LinkClick : function(id)
        {
			this.FireEvent("linkclicked", id);
        },
        GetLink : function(id)
        {
			return this._(id);
        }
    }
);


Reflective.Web.UI.Controls.ListView = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.AjaxEnabledControl, clientId, serverId, rootElementId);
    
    this._dropDownMenu = null;
    this._headers = new Reflective.Web.Hashtable();
    this._searchString = "";
}

Core.setInheritance(Reflective.Web.UI.Controls.ListView, 
    Reflective.Web.UI.AjaxEnabledControl);
    
Core.extend(Reflective.Web.UI.Controls.ListView,
    {
        OnInit : function()
        {
			window.Page.BindEvent("onclick", this.id + ".HideDropDown");
			
			var headers = $("[isHeader = '1'][listViewId='" + this.id + "']");
			console.log("discovered " + headers.length + " headers");
			for (var i = 0; i < headers.length; i++)
			{
				var header = window[$(headers[i]).attr("ClientId")];
				header.BindEvent("onclick", this.id, "HeaderClick");
				console.log("Header click for " + header.ServerId + " bound.");
				this._headers.set(header.ServerId, header);
			}
			
			if (this._searchBox())
				this._searchBox().BindEvent("onsearch", this.id, "Search");
			
			if (this._filterDisplayBox())
				this._filterDisplayBox().BindEvent("onclear", this.id, "ClearFilter");
        },
        Search : function(sender, value)
        {	
			if (typeof(sender) == "string")
				this._searchString = sender;
			else
				this._searchString = value;
			
			this.Refresh();
        },
        _searchBox : function()
        {
			if (this._attr("searchBoxId"))
				return window[this._attr("searchBoxId")];
			else
				return null;
        },
        SearchString : function()
        {
			return this._searchString;
        },
        _filterDisplayBox : function()
        {
			if (this._attr("filterDisplayBoxId"))
				return window[this._attr("filterDisplayBoxId")];
			else
				return null;
        },
        _filterDisplayDiv : function()
        {
			return this._("filterDisplayDiv");
        },
        
        _rowContainer : function()
        {
			return this._("rowContainer");
        },
        PageNumber : function(value)
        {
			if (value == null)
				return parseInt(this._rowContainer().attr("pageNumber"));
			else
			{
				this._rowContainer().attr("pageNumber", value);
			}
        },
        TotalRows : function()
        {
			return parseInt(this._rowContainer().attr("totalRows"));
        },
        PageSize : function(value)
        {
			if (value == null)
				return parseInt(this._rowContainer().attr("pageSize"));
			else
			{
				this._rowContainer().attr("pageSize", value);
			}
        },
        PageCount : function()
        {
			return parseInt(this._rowContainer().attr("pageCount"));
        },
        Refresh : function()
        {
			this.OnRefresh();
        },
        OnRefresh : function()
        {
			var args = new Reflective.Web.CancelEventArgs();
			this.FireEvent("onbeforerefresh", args);
			if (!args.Cancel)
			{
				this.OnBeforeCallBack();
				this.FireEvent("onbeginrefresh");
				this.FireServerEvent(this.EVENT_NAME_REFRESH);
			}
        },
        _rowsDiv : function() { return this._("rowsDiv"); },
        RowMouseOver : function(rowElement, e)
        {
			DomHelper.CancelBubble(e);
        	this.OnRowMouseOver(new Reflective.Web.UI.Controls.ListViewRowEventArgs(rowElement));
        },
        OnRowMouseOver : function(args)
        {
			this.FireEvent("onrowmouseover", args);
        },
        RowMouseOut : function(rowElement, e)
        {
			DomHelper.CancelBubble(e);
			this.OnRowMouseOut(new Reflective.Web.UI.Controls.ListViewRowEventArgs(rowElement));
        },
        OnRowMouseOut : function(args)
        {
			this.FireEvent("onrowmouseout", args);
        },
        RowClick : function(rowElement, e)
        {
			DomHelper.CancelBubble(e);
			this.OnRowClick(new Reflective.Web.UI.Controls.ListViewRowEventArgs(rowElement));
        },
        OnRowClick : function(args)
        {
			if (args.TargetUrl)
				window.location.href = args.TargetUrl;
			else
				this.FireEvent("onrowclick", args);
        },
        SelectAll : function(clickedElement, select)
        {
			this.$el().find("[type='checkbox'][isSelector='1']").attr("checked", select);
			
			if (clickedElement.tagName == "A")
			{
				if (clickedElement.id == this.id + "_selectAllLink")
				{
					this._("selectAllLink").hide();
					this._("deselectAllLink").show();
				}
				else
				{
					this._("selectAllLink").show();
					this._("deselectAllLink").hide();
				}
			}
        },
        RowCheckBoxClick : function(checkBoxElement, e)
        {
        },
        OnRowCheckBoxClick : function(args)
        {
        },
        TaskClick : function(taskElement, e)
        {
			DomHelper.CancelBubble(e);
			var args = new Reflective.Web.UI.Controls.ListViewTaskEventArgs(taskElement);
			if (args.Enabled)
				this.OnTaskClick(args);
        },
        OnTaskClick : function(args)
        {
			if (args.TargetUrl)
			{
				window.location.href = args.TargetUrl;
			}
			else
			{
				this.FireEvent("onrowtaskclick", args);
			}
        },
        HeaderClick : function(sender, args)
        {
			console.log("HeaderClick: " + sender.id);
			this.OnHeaderClick(new Reflective.Web.UI.Controls.ListViewHeaderEventArgs(sender));
        },
        OnHeaderClick : function(args)
        {
			if (args.Header.AllowSort())
			{
				this.Sort(args.Header.ServerId);
			}
        },
        SortColumnID : function(value)
        {
			if (value == null)
				return this._attr("sortColumnId") ? this._attr("sortColumnId") : "";
			else
				this._attr("sortColumnId", value);
        },
        FilterID : function(value)
        {
			if (value == null)
				return this._attr("filterId") ? this._attr("filterId") : "";
			else
				this._attr("filterId", value);
        },
        ClearFilter : function()
        {
			this.FilterID("");
			this.Refresh();
        },
        SortDirection : function(value)
        {
			if (value == null)
			{
				return this._attr("sortDirection");
			}
			else
			{
				this._attr("sortDirection", value);
			}
        },
        Sort : function(headerId)
        {
			console.log("Sort: headerId: " + headerId);
			var header = this._headers.get(headerId);
			console.log(header);
			var columnId = header.ColumnID();
			
			if (columnId != this.SortColumnID())
			{
				this.SortDirection("Ascending");
				this.SortColumnID(header.ColumnID());
			}
			else
				this.SortDirection(
					this.SortDirection() == "Descending" ? "Ascending" : "Descending");
			
			this.OnSort(new Reflective.Web.UI.Controls.ListViewHeaderEventArgs(header));
        },
        OnSort : function(headerArgs)
        {
			this.FireEvent("onsort", headerArgs);
			console.log("onsort fired.");
			if (!headerArgs.Cancel)
			{
				this._headers.foreach(
					function(item)
					{
						item.ShowArrow("NotSet");
					}
				);
				console.log("arrows reset.");
				headerArgs.Header.ShowArrow(this.SortDirection());
				console.log("sort arrow revealed.");
				this.OnBeforeCallBack();
				console.log("callback configured.");
				this.Refresh();
				//this.FireServerEvent(this.EVENT_NAME_SORT);
			}
        },
        OnSortComplete : function(args)
        {
			this.FireEvent("sortcomplete", args);
			this._rowsDiv().html(args.responseText);
        },
        ShowPage : function(pageNameOrNumber)
        {
			var p = pageNameOrNumber;
			var pageNum = this.PageNumber();
			var pageCount = this.PageCount();
			
			if (typeof(p) == "string")
			{
				
				if (p == "next" && pageNum < pageCount)
				{
					this.PageNumber(pageNum+1);
					this.Refresh();
				}
				else if (p == "prev" && pageNum > 1)
				{
					this.PageNumber(pageNum-1);
					this.Refresh();
				}
				else if (p == "last" && pageNum < pageCount)
				{
					this.PageNumber(pageCount);
					this.Refresh();
				}
				else if (p == "first" && pageNum > 1)
				{
					this.PageNumber(1);
					this.Refresh();
				}
			}
			else
			{
				var num = parseInt(p);
				if (num > 0 && num <= pageCount)
				{
					this.PageNumber(num);
					this.Refresh();
				}
			}
        },
        OnBeforeCallBack : function()
        {
			this.ClearCallBackParams();
			this.SetCallBackParam("SearchString", this.SearchString());
			this.SetCallBackParam("PageSize", this.PageSize());
			this.SetCallBackParam("PageNumber", this.PageNumber());
			this.SetCallBackParam("sortColumnId", this.SortColumnID());
			this.SetCallBackParam("sortDirection", this.SortDirection());
			this.SetCallBackParam("filterId", this.FilterID());

        },
        OnRefreshComplete : function(args)
        {
			this._rowsDiv().html(args.responseText);
			this._rowsDiv().fadeIn();
			
			console.log("OnRefreshComplete");
			
			if (this._filterDisplayDiv())
			{
				if (this.FilterID())
				{
					console.log("showing filter display");
					this._filterDisplayDiv().fadeIn();
				}
				else
				{
					console.log("hiding filter display");
					if (this._filterDisplayDiv().css("display") != "none")
						this._filterDisplayDiv().fadeOut();
				}
			}
			this.FireEvent("refreshcomplete", args);
        },
        OnCallBackComplete : function(sender, args)
        {
			if (args.EventName == this.EVENT_NAME_SORT)
			{
				this.OnSortComplete(args);
			}
			else if (args.EventName == this.EVENT_NAME_REFRESH)
			{
				this.OnRefreshComplete(args);
			}
        },
        OnCallBackError : function(sender, args)
        {
			Alert.Show(args.Error.Message, "Error");
        },
        DropDownTaskMouseOver : function(taskElement, e)
        {
			DomHelper.CancelBubble(e);
			this.OnDropDownTaskMouseOver(new Reflective.Web.UI.Controls.ListViewTaskEventArgs(taskElement));
        },
        OnDropDownTaskMouseOver : function(args)
        {
			this._dropDownShowTimeoutId = window.setTimeout(this.id + ".ShowDropDown('" + args.TaskClientID + "');", 1000);
        },
        DropDownTaskMouseOut : function(taskElement, e)
        {
			DomHelper.CancelBubble(e);
			this.OnDropDownTaskMouseOut(new Reflective.Web.UI.Controls.ListViewTaskEventArgs(taskElement));
        },
        OnDropDownTaskMouseOut : function(args)
        {
			if (this._dropDownShowTimeoutId)
				window.clearTimeout(this._dropDownShowTimeoutId)
			else	
				this._dropDownTimeoutId = window.setTimeout(this.id + ".HideDropDown();", 1500);
        },
        DropDownMenuMouseOver : function(menuElement, e)
        {
			window.clearTimeout(this._dropDownTimeoutId);
        },
        DropDownMenuMouseOut : function(menuElement, e)
        {
			this._dropDownTimeoutId = window.setTimeout(this.id + ".HideDropDown();", 1500);
        },
        ShowDropDown : function(taskClientId)
        {
			this.HideDropDown();
				
			var taskElement = $("#" + taskClientId);
			this._dropDownMenu = $("#" + taskClientId + "_subTasks");
			var offset = taskElement.offset();
            offset.top += taskElement.outerHeight();
            
            $(document.body).append(this._dropDownMenu);
            this._dropDownMenu.css(offset);
            this._dropDownMenu.show();
        },
        HideDropDown : function()
        {
			if (this._dropDownMenu)
				this._dropDownMenu.hide();
        }
        
    }
);

Reflective.Web.UI.Controls.ListViewRowEventArgs = function(rowElement)
{
	var r = $(rowElement);
	this.RowKey = r.attr("key");
	this.RowIndex = r.attr("index");
	this.TargetUrl = r.attr("clickUrl"); 
}

Reflective.Web.UI.Controls.ListViewTaskEventArgs = function(taskElement)
{
	var el = $(taskElement);
	this.TaskClientID = el.attr("id");
	this.TaskID = el.attr("taskId");
	this.RowKey = el.attr("rowKey");
	this.IsDropDown = el.attr("isDropDown");
	this.TargetUrl = el.attr("clickUrl");
	this.Enabled = el.attr("enabled") == "1"; 
}

Reflective.Web.UI.Controls.ListViewHeaderEventArgs = function(header)
{
	this.Header = header;
	this.Cancel = false;
}

Reflective.Web.UI.Controls.ListViewRowTask = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.ListViewRowTask, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.ListViewRowTask,
    {
        OnInit : function()
        {
			
        },
        RowKey : function()
        {
			return this._attr("rowKey");
        }
    }
   
);

Reflective.Web.UI.Controls.ListViewColumnHeader = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.ListViewColumnHeader, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.ListViewColumnHeader,
    {
        OnInit : function()
        {
			this.AllowSort(this.AllowSort());
        },
        _listView : function()
        {
			return window[this._attr("listViewId")];
        },
        AllowSort : function(allow)
        {
			if (allow == null)
			{
				return this._attr("AllowSort");
			}
			else
			{
				this._attr("AllowSort", allow ? "1" : "");
				
				if (allow)
				{
					this.$el().css("cursor", "pointer");
					this.$el().attr("title", this._listView().SortableColumnToolTip);
				}
			}
        },
        ColumnID : function()
        {
			return this._attr("ColumnID");
        },
        ShowArrow : function(name)
        {
			this._("sortArrowNone").css("display", name == "NotSet" ? "" : "none");
			this._("sortArrowAsc").css("display", name == "Ascending" ? "" : "none");
			this._("sortArrowDesc").css("display", name == "Descending" ? "" : "none");
        }
    }
);


Reflective.Web.UI.Controls.ListViewPagingMenu = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.ListViewPagingMenu, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.ListViewPagingMenu,
    {
        OnInit : function()
        {
			this._listView().BindEvent("onbeginrefresh", this.id, "_listRefreshing");
			this._listView().BindEvent("refreshcomplete", this.id, "_listRefreshComplete");
			this._syncState();
        },
        _listView : function()
        {
			return window[this._attr("listViewId")];
        },
        _listRefreshing : function(sender)
        {
			this._disable();
        },
        _listRefreshComplete : function(sender)
        {
			this._syncState();
        },
        _syncState : function()
        {
			console.log("Syncing paging menu.");
			var pageCount = this._listView().PageCount();
			var pageNum = this._listView().PageNumber();
			var totalRows = this._listView().TotalRows();
			
			if (totalRows == 0)
				this.Hide();
			else
			{
				if (!this.Visible()) this.Show();
				
				this._pageNumInput().attr("disabled", false);
				this._pageNumInput().val(this._listView().PageNumber());
				
				this._pageCountDiv().text(pageCount);
				this._totalRowsDiv().text(totalRows);
				
				this._firstBtn().attr("disabled", pageNum == 1);
				this._prevBtn().attr("disabled", pageNum == 1);
				this._nextBtn().attr("disabled", pageNum == pageCount);
				this._lastBtn().attr("disabled", pageNum == pageCount);
			}
        },
        _disable : function()
        {
			this._pageNumInput().attr("disabled", true);
			this._firstBtn().attr("disabled", true);
			this._prevBtn().attr("disabled", true);
			this._nextBtn().attr("disabled", true);
			this._lastBtn().attr("disabled", true);
        },
        FirstClick : function(sender, e)
        {
			this._listView().ShowPage("first");
        },
        LastClick : function(sender, e)
        {
			this._listView().ShowPage("last");
        },
        PrevClick : function(sender, e)
        {
			this._listView().ShowPage("prev");
        },
        NextClick : function(sender, e)
        {
			this._listView().ShowPage("next");
        },
        _firstBtn : function() { return this._("firstBtn"); },
        _nextBtn : function() { return this._("nextBtn"); },
        _prevBtn : function() { return this._("prevBtn"); },
        _lastBtn : function() { return this._("lastBtn"); },
        _pageNumInput : function() { return this._("pageNumInput"); },
        _pageCountDiv : function() { return this._("pageCountValue"); },
        _totalRowsDiv : function() { return this._("totalRowsValue"); },
        PageNumKeyUp : function(sender, e)
        {
			var num = parseInt($(sender).val());
			if (num && num < 1 || num > this._listView().PageCount())
			{
				$(sender).val(this._listView().PageNumber());
			}
			
			return true;
			
        },
        PageNumKeyPress : function(sender, e)
        {
			var keyCode = DomHelper.eventKeyCode(e);
            
            if (keyCode == Environment.KeyCodes.Tab
                || keyCode == Environment.KeyCodes.Backspace
                || keyCode == Environment.KeyCodes.RightArrow
                || keyCode == Environment.KeyCodes.LeftArrow) 
                return true;
            
            if (keyCode == Environment.KeyCodes.Enter)
            {
				if ($(sender).val() != "")
				{
					var num = parseInt($(sender).val());
					if (num && num <= this._listView().PageCount())
					{
						this._listView().ShowPage(num);
					}
				}
            }
                
			var test = "0123456789";
			if (test.indexOf(String.fromCharCode(DomHelper.eventKeyCode(e))) > -1)
			{
				return true;
			}
			else
			{
				DomHelper.CancelEvent(e);
				return false;
			}
        }
    }
);

Reflective.Web.UI.Controls.ListViewFilterMenu = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Menu, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.ListViewFilterMenu, 
    Reflective.Web.UI.Menu);
    
Core.extend(Reflective.Web.UI.Controls.ListViewFilterMenu,
    {
        OnInit : function()
        {
		},
		OnItemClicked : function(args)
		{
			var item = this.GetItem(args.item.ServerId);
			console.log("Filter " + item._attr("filterId") + " will be invoked");
			this._listView().FilterID(item._attr("filterId"));
			this._listView()._filterDisplayBox().Value(item._attr("displayText"));
			this._listView().PageNumber(1);
			this._listView().Refresh();
		},
		_listView : function()
		{
			return window[this._attr("listViewId")];
		}
    }
);

Reflective.Web.UI.Controls.ListViewFilterDisplayBox = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.ListViewFilterDisplayBox, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.ListViewFilterDisplayBox,
    {
        OnInit : function()
        {
		},
		Value : function(value)
		{
			if (value == null)
				return this.$el().find("#value").html();
			else
				this.$el().find("#value").html(value);
		},
		_clearBtnClicked : function(e)
		{
			this.FireEvent("onclear");
		}
    }
);

Reflective.Web.UI.Controls.ListViewSearchBox = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
    this._searchExecuted = false;
}

Core.setInheritance(Reflective.Web.UI.Controls.ListViewSearchBox, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.ListViewSearchBox,
    {
        OnInit : function()
        {
			this._("textInput").val("");
		},
		_searchClicked : function(sender, e)
		{
			DomHelper.CancelEvent(e);
			DomHelper.CancelBubble(e);
			this.StartSearch();
		},
		_clearClicked : function(sender, e)
		{
			DomHelper.CancelEvent(e);
			DomHelper.CancelBubble(e);
			this._("textInput").val("");
			this.StartSearch();
		},
		_textKeyPress : function(sender, e)
		{
			if (e.keyCode == Environment.KeyCodes.Enter)
				this.StartSearch();
		},
		_textKeyUp : function(sender, e)
		{
		},
		_value : function()
		{
			return this._("textInput").val();
		},
		_clearBtn : function() { return this._("clearBtn"); },
		_searchBtn : function() { return this._("searchBtn"); },
		StartSearch : function()
		{
			this.FireEvent("onsearch", this._value());
		}
    }
);

Reflective.Web.UI.Controls.MultiDocumentPanel = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.AjaxEnabledControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.MultiDocumentPanel, 
    Reflective.Web.UI.AjaxEnabledControl);
    
Core.extend(Reflective.Web.UI.Controls.MultiDocumentPanel,
    {
        OnInit : function()
        {
        }
    }
);

Reflective.Web.UI.Controls.DocumentPanelArgs = function(panel)
{
	this.panel = panel;
	this.cancel = false;
}

Reflective.Web.UI.Controls.DocumentPanel = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.DocumentPanel, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.DocumentPanel,
    {
        OnInit : function()
        {
        }
    }
);


Reflective.Web.UI.Controls.MultiSectionForm = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormBase, clientId, serverId, rootElementId);
    this.CurrentSection = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.MultiSectionForm,
    Reflective.Web.UI.Controls.FormBase);


Core.extend(Reflective.Web.UI.Controls.MultiSectionForm,
    {
    	OnInit: function() 
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnInit");
    		console.log("panels: " + this._panels.count());
    	},
    	OnAllowSubmit : function(allow)
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnAllowSubmit", allow);
			alert("TODO: call OnAllowSubmit for each section.");	
    	},
    	OnAllowInput : function(allow)
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnAllowInput", allow);
    		alert("TODO: call OnAllowInput for each section.");
    	},
    	OnGetInput : function(inputId)
    	{
    		console.log("MultiSectionForm.OnGetInput('" + inputId + "');");
    		
    		var keys = this._panels.keys();
    		
    		for (var i = 0; i < keys.length; i++)
    		{
    			var panel = this._panels.get(keys[i]);
    			var input = panel.GetInput(inputId);
				if (input)
				{
					return input;
				}
    			
    		}
    		return null;
    	},
    	SubmitSection : function(section, e)
    	{
			this.CurrentSection = section;
			//this.Submit(e);		
			if (!this.OnValidate())
				DomHelper.CancelEvent(e);
			else
				section.Submit(e);				
    	},
    	OnGetValuesForSubmit : function(valueSet)
    	{
    		this.CurrentSection._inputs.foreach(
    			function(item)
    			{
    				console.log("Adding value for " + item.id);
    				item.GetValueForSubmit(valueSet);
    			}
    		);
    		valueSet.set("source_section", this.CurrentSection.ServerId);
    	},
    	OnValidate : function()
    	{
    		var args = new Reflective.Web.UI.Controls.MultiSectionFormValidationEventArgs(this.CurrentSection);
            this.FireEvent("onvalidate", args);
            return args.IsValid;
    	},
    	OnSubmitEnd : function(args)
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnSubmitEnd", args);
    		if (!args.IsError)
    		{
    			this.CurrentSection.SummaryText(args.Params.get("SummaryHtml"));
    			this.CurrentSection.Collapse();
    		}
    	},
    	_inputValueChanged : function(input)
    	{
    		this.OnInputValueChanged(input);
    	},
    	OnInputValueChanged : function(input)
    	{
    		this.FireEvent("onvaluechanged", input);
    	}
    }
);

Reflective.Web.UI.Controls.FormSection = function(clientId, serverId, rootElementId)
{
	this.Inherits(Reflective.Web.UI.Controls.FormLayoutPanel, clientId, serverId, rootElementId);
	this._inputs = new Reflective.Web.Hashtable();
	this._buttons = new Reflective.Web.Hashtable();
	this._submitBtn = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.FormSection, 
    Reflective.Web.UI.Controls.FormLayoutPanel);
    
Core.extend(Reflective.Web.UI.Controls.FormSection,
    {
		OnInit : function()
		{
			this.CallBase(Reflective.Web.UI.Controls.FormLayoutPanel, "OnInit");
			this._findInputs();
			this._findButtons();
			
			if (this._attr("submitOnChg"))
			{
				this.AllowSubmit(false);
			}
		},
		_formElement : function() { return this._("form"); },
		_iframe : function() { return this._("iframe"); },
		_findInputs : function()
		{
			console.log("FormSection._findInputs (" + this.ClientId + ")");
			var inputs = this.$el().find("[@isInput='1']");
			for (var i = 0; i < inputs.length; i++)
            {
                this.OnFoundInput(window[$(inputs[i]).attr("ClientId")]);
            }
            console.log(this._inputs.count() + " inputs found.");
		},
		OnFoundInput : function(input)
		{
			this._inputs.set(input.ServerId, input);
			input.BindEvent("onvaluechanged", this.id, "_inputValueChanged");
			input.BindEvent("onenterpressed", this.id, "_inputEnterPressed");
			
			console.log("input '" + input.ServerId + "' (" + input.InputType + ") found.");
		},
		_findButtons : function()
		{
			console.log("FormSection._findButtons");
			var buttons = this.$el().find("[@isButton='1']");
            for (var i = 0; i < buttons.length; i++)
            {
				var element = $(buttons[i]);
				this.OnFoundButton(window[element.attr("ClientId")], 
					element.attr("type"));
            }
            console.log(this._buttons.count() + " buttons found.");
		},
		OnFoundButton : function(button, type)
		{
			this._buttons.set(button.id, button);
			console.log("button " + button.id + " found.");
			
			if (type == "submit")
			{
				button.BindEvent("onclick", this.id, "_submitBtnClick");	
				this._submitBtn = button;
			}
			else if (type == "cancel")
			{
				button.BindEvent("onclick", this.id, "_cancelClick");
			}
		},
		_summaryDiv : function()
		{
			return $("#" + this._attr("summaryClientId"));
		},
		OnExpand : function()
		{
			var t = this;
			if (this._summaryDiv().length > 0)
			{
				this._summaryDiv().fadeOut(500, 
					function callback()
					{
						t.CallBase(Reflective.Web.UI.Controls.FormLayoutPanel, "OnExpand");
					}
				);
			}
			else
			{
				t.CallBase(Reflective.Web.UI.Controls.FormLayoutPanel, "OnExpand");
			}
			this._("toggleLink").text(this._attr("CollapseButtonText"));
			
		},
		OnCollapse : function()
		{
			this.CallBase(Reflective.Web.UI.Controls.FormLayoutPanel, "OnCollapse");
			if (this._summaryDiv().length > 0)
				this._summaryDiv().fadeIn(2000);
				
			this._("toggleLink").text(this._attr("ExpandButtonText"));
		},
		_inputEnterPressed : function(sender, e)
		{
			if (this._submitBtn.Enabled())
				this._form().SubmitSection(this, e);	
		},
    	_submitBtnClick: function(sender, e) 
    	{
    		//first cancel the submit event on the form 
    		DomHelper.CancelBubble(e);
    		DomHelper.CancelEvent(e);
    		//this._form().SubmitSection(this, e);
    	},
        _cancelClick : function(sender, e)
        {
			DomHelper.CancelEvent(e);
			DomHelper.CancelBubble(e);
            this.Cancel();
        },
        _inputValueChanged : function(sender)
        {
			this.OnInputValueChanged(sender);
			this._form()._inputValueChanged(sender);
        },
        OnInputValueChanged : function(input)
        {
			this.FireEvent("onvaluechanged", input);
			if (this._attr("submitOnChg"))
			{
				var allow = this.IsValid();
				console.log("Form is valid: " + allow);
				this.AllowSubmit(allow);
			}
        },
        SummaryText : function(text)
        {
			this._summaryDiv().html(text);
        },
        AllowSubmit : function(allow)
        {
			console.log("Section.AllowSubmit(" + allow + ");");
			this._submitBtn.SetEnabled(allow);
        },
        IsValid : function()
        {
			var inputs = this._inputs.values();
			for (var i = 0; i < inputs.length; i++)
			{
				var input = inputs[i];
				console.log("validating input " + input.id + ".");
				if (!input.IsValid())
				{
					console.log("input " + input.id + " does not validate.");
					return false;
				}
				else
					console.log("input " + input.id + " validates.");
			}
			
			return true;
        },
        Submit : function(e)
        {
			this._formElement().submit();
        }
	}
);

Reflective.Web.UI.Controls.MultiSectionFormValidationEventArgs = function(section)
{
    this.Inherits(Reflective.Web.UI.Controls.FormValidationEventArgs, null);
    this.Section = section;
}
Core.setInheritance(Reflective.Web.UI.Controls.MultiSectionFormValidationEventArgs,
    Reflective.Web.UI.Controls.FormValidationEventArgs);
    
Core.extend(Reflective.Web.UI.Controls.MultiSectionFormValidationEventArgs,
    {
        
    }
);



Reflective.Web.UI.Controls.RadioInput = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormInput, clientId, serverId, rootElementId);
    this.InputType = "radio";
    this._options = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.RadioInput, 
    Reflective.Web.UI.Controls.FormInput);
    
Core.extend(Reflective.Web.UI.Controls.RadioInput,
    {
        OnInit : function()
        {
			this.CallBase(Reflective.Web.UI.Controls.FormInput, "OnInit");
            this._refreshOptions();
        },
        _refreshOptions : function()
        {
            this._options = this.$el().find("[optionId]");
        },
        OnEnable : function()
        {
			this._options.attr("disabled", false);
			return true;
        },
        OnDisable : function()
        {
			this._options.attr("disabled", true);
			return true;
        },
        OnClick : function(e)
        {
            this.FireEvent("itemclicked", 
                $(DomHelper.EventSource(e)).attr("optionId"));
            
            this._checkIfChanged();
        },
        _getOptionName : function(optionId)
        {
            return $("#" + this.ClientId + " [optionId='" + optionId + "']").attr("name");
        },
        _getOption : function(optionId)
        {
            return $("#" + this.ClientId + " [optionId='" + optionId + "']");
        },
        OnGetValue : function()
        {
            for (var i = 0; i < this._options.length; i++)
            {   
                var opt = this._options[i];
                if (opt.checked)
                {
				    return $(opt).attr("value");
                }
            }
            return "";
        }
    }
);

Reflective.Web.UI.Controls.SearchInput = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormAutoLabelInput, clientId, serverId, rootElementId);
    this.InputType = "text";
    this._isSingleLine = true;
    this._waterMarkVisible = false;
}

Core.setInheritance(Reflective.Web.UI.Controls.SearchInput, 
    Reflective.Web.UI.Controls.FormAutoLabelInput);
    
Core.extend(Reflective.Web.UI.Controls.SearchInput,
    {
        OnInit : function()
        {
            this.CallBase(Reflective.Web.UI.Controls.FormAutoLabelInput, "OnInit");
        },
        _searchBox : function() { return this._("searchBox"); },
        _searchBtn : function() { return this._("searchBtn"); },
        _searchInput : function() { return this._("searchInput"); },
        _searchBtnClick : function(element, event)
        {
			if (this._searchBox().css("display") == "none")
				this.ShowSearchBox();
			else
				this.HideSearchBox();
        },
        ShowSearchBox : function()
        {
			this._searchBox().show("slide", {direction : "down" }, 1000);
			this._searchInput().focus();
        },
        HideSearchBox : function()
        {
			this._searchBox().hide("slide", {direction : "down" }, 1000);
        },
        Clear : function() { this.SetValue(""); },
        Select : function()
        {
            this.SetFocus(true);
        },
        OnSetFocus : function(value)
        {
			this._searchBtn().focus();
        }
    }
);


Reflective.Web.UI.Controls.ToolBar = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.AjaxEnabledControl, clientId, serverId, rootElementId);
    this._items = new Reflective.Web.Hashtable();
}

Core.setInheritance(Reflective.Web.UI.Controls.ToolBar, 
    Reflective.Web.UI.AjaxEnabledControl);
    
Core.extend(Reflective.Web.UI.Controls.ToolBar,
    {
        OnInit : function()
        {
			var items = this.$el().find("[toolBarId='" + this.id + "']");
			
        },
        _itemClick : function(args)
        {
			this.FireEvent("itemclicked", args);
        },
        GetItem : function(id)
        {
			if (!this._items.containskey(id))
			{
				var element = this.$el().find("[ServerId='" + id + "']");
				if (element)
					this._items.set(id, window[element.attr("ClientId")]);
			}
			return this._items.get(id);
        }
    }
);

Reflective.Web.UI.Controls.ToolBarItemEventArgs = function(item)
{
	this.item = item;
	this.cancel = false;
}

Reflective.Web.UI.Controls.ToolBarItem = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.ToolBarItem, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.ToolBarItem,
    {
        OnInit : function()
        {
        }
	}
);

Reflective.Web.UI.Controls.ToolBarButton = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.ToolBarItem, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.ToolBarButton, 
    Reflective.Web.UI.Controls.ToolBarItem);
    
Core.extend(Reflective.Web.UI.Controls.ToolBarButton,
    {
        OnInit : function()
        {
        },
        _toolBar : function() { return window[this._attr("toolBarId")]; },
        OnClick : function(e)
        {
			this._toolBar()._itemClick(new Reflective.Web.UI.Controls.ToolBarItemEventArgs(this));
        }
	}
);

Reflective.Web.UI.Controls.ToolBarDropDownButton = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.ToolBarButton, clientId, serverId, rootElementId);
    
    this._menuInit = false;
}

Core.setInheritance(Reflective.Web.UI.Controls.ToolBarDropDownButton, 
    Reflective.Web.UI.Controls.ToolBarButton);
    
Core.extend(Reflective.Web.UI.Controls.ToolBarDropDownButton,
    {
        OnInit : function()
        {
			window.Page.BindEvent("onmouseover", this.id + "._documentMouseOver");
			window.Page.BindEvent("onclick", this.id + "._documentClick");
        },
        _menu : function() { return window[this._attr("MenuClientId")]; },
        _documentMouseOver : function(e)
        {
			
        },
        _documentClick : function(e)
        {
			this.MenuVisible(false);
        },
        _toolBar : function() { return window[this._attr("toolBarId")]; },
        OnClick : function(e)
        {	
			DomHelper.CancelBubble(e);
			this.MenuVisible(!this.MenuVisible());
			return true;
        },
        MenuVisible : function(setVisible)
        {
			if (setVisible == null)
			{
				return this._menu().Visible();
			}
			else
			{
				if (setVisible)
				{
					var offset = this.$el().offset();
					offset.top += this.$el().outerHeight();
		          
					if (!this._menuInit) 
					{ 
						$(document.body).append(this._menu().$el());
						this._menu().BindEvent("itemclicked", this.id, "_itemClick");
					}
					this._menu().SetStyle("top", offset.top);
					this._menu().SetStyle("left", offset.left);
					this._menu().Show(true);
					
					this._menuInit = true;
				}
				else if (this.MenuVisible())
					this._menu().Hide();
			}
        },
        _itemClick : function(sender, args)
        {
			this.OnItemClick(args);
        },
        OnItemClick : function(args)
        {
			this.FireEvent("menuitemclicked", args);
        }
        
	}
);

Reflective.Web.UI.Controls.ToolBarDropDownMenuItem = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.MenuItem, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.ToolBarDropDownMenuItem, 
    Reflective.Web.UI.MenuItem);
    
Core.extend(Reflective.Web.UI.Controls.ToolBarDropDownMenuItem,
    {
        OnInit : function()
        {
			this.CallBase(Reflective.Web.UI.MenuItem, "OnInit");
        },
        _toolBar : function() { return window[this._attr("toolBarId")]; },
        _button : function() { return window[this._attr("buttonId")]; }
	}
);


Reflective.Web.UI.Controls.TreeControl = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.AjaxEnabledControl, clientId, serverId, rootElementId);
    this._expandingNode = null;
    this._nodes = new Reflective.Web.Hashtable();
    this._selectedNode = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.TreeControl, 
    Reflective.Web.UI.AjaxEnabledControl);
    
Core.extend(Reflective.Web.UI.Controls.TreeControl,
    {
        OnInit : function()
        {
        },
        OnClick : function(e)
        {
			this.SelectNode("");
			return true;
        },
        _getNode : function(nodeId)
        {
			if (!this._nodes.containskey(nodeId))
			{
				var nodeElement = this.findChildren("ServerId", nodeId);
				this._nodes.add(nodeId, new Reflective.Web.UI.Controls.TreeNode(nodeElement.attr("ClientId"), nodeId, nodeElement.attr("ClientId") + "_element"));
			}	
			return this._nodes.get(nodeId);
        },
        _nodeExpanderClick : function(nodeId, e)
        {
			DomHelper.CancelBubble(e);
			var node = this._getNode(nodeId); 
			console.log("node: " + node.id + " (expandable: " + node.Expandable() + ")");
			if (node.Expandable())
			{
				if (node.Expanded())
					node.Expanded(false);
				else
				{
					this.OnNodeExpanding(new Reflective.Web.UI.Controls.TreeNodeEventArgs(node));
				}
			}
        },
        SelectNode : function(nodeId)
        {
			if (this._selectedNode)
			{
				this._selectedNode.Selected(false);
			}
			
			if (nodeId)
			{
				this._selectedNode = this._getNode(nodeId);
				this._selectedNode.Selected(true);
				this.OnSelectionChanged();
			}
        },
        OnSelectionChanged : function()
        {
			this.FireEvent("selectionchanged");
        },
        SelectedNode : function() { return this._selectedNode; },
        _nodeClick : function(nodeId, e)
        {
			DomHelper.CancelBubble(e);
			
			this.OnNodeClick(new Reflective.Web.UI.Controls.TreeNodeEventArgs(this._getNode(nodeId)));
        },
        OnNodeClick : function(args)
        {
			console.log(args.node.id + " clicked.");
			this.FireEvent("nodeclicked", args);
			if (args.cancel) return;
			this.SelectNode(args.node.ServerId);
        },
        OnNodeExpanding : function(args)
        {
			this.FireEvent("nodeexpanding", args);
			
			if (args.cancel) return;
			
			if (this.UseAjax() && !args.node.HasChildren())
			{
				console.log("Node does not have children... going to expand via ajax now.");
				this.SetCallBackParam("nodeId", args.node.ServerId);
				this.SetCallBackParam("nodeTag", args.node.Tag());
				this.SetCallBackParam("nodeLevel", args.node.Level());
				this._expandingNode = args.node;
				this.FireServerEvent(this.NODE_EXPAND_EVENT);
			}
			else
			{
				args.node.Expanded(true);
			}
        },
        OnCallBackComplete : function(sender, args)
        {
			if (this._currentEventName == this.NODE_EXPAND_EVENT)
			{
				this._expandingNode.SetChildren(args.responseText);
				this._expandingNode.Expanded(true);
			}
        },
        _nodeExpanded : function(node)
        {
			this.OnNodeExpand(new Reflective.Web.UI.Controls.TreeNodeEventArgs(node));
        },
        OnNodeExpand : function(args)
        {
			this.FireEvent("nodeexpanded", args);
        },
        _nodeCollapsed : function(node)
        {
			this.OnNodeCollapse(new Reflective.Web.UI.Controls.TreeNodeEventArgs(node));
        },
        OnNodeCollapse : function(args)
        {
			this.FireEvent("nodecollapsed", args);
        },
        ExpandNode : function(node, expand)
        {
			if (node.Expandable())
			{
				node.Expanded(expand);
			}
        }
        
    }
);

Reflective.Web.UI.Controls.TreeNodeEventArgs = function(node)
{
	this.node = node;
	this.cancel = false;
}

Reflective.Web.UI.Controls.TreeNode = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.Controls.TreeNode, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(Reflective.Web.UI.Controls.TreeNode,
    {
        OnInit : function()
        {
        },
        _tree : function() { return window[this._attr("TreeId")]; },
        _nodeDiv : function() { return this._("node"); },
        Expandable : function() { return this._attr("Expandable"); },
        Tag : function() { return this._attr("Tag"); },
        HasChildren : function() { return this._("children").html() != ""; },
        Level : function() { return this._attr("Level"); },
        OnClick : function(e)
        {
			DomHelper.CancelBubble(e);
			this._tree()._nodeClick(this);
			return true;
        },
        Selected : function(value)
        {
			if (value == null)
			{
				return this._attr("selected") == "1";
			}
			else
			{
				this._attr("selected", value ? "1" : "");
				
				this._nodeDiv().attr("class", 
					value ? this._tree()._attr("NodeSelectedCssClass") : this._tree()._attr("NodeCssClass"));
			}
        },
        Expanded : function(value)
        {
			if (value == null)
			{
				return this._attr("Expanded");
			}
			else
			{
				if (value && !this.Expanded())
				{
					console.log("expanding " + this.id);
					this._("children").fadeIn();
					this._attr("Expanded", "1");
					this._tree()._nodeExpanded();
				}
				else if (!value && this.Expanded())
				{
					console.log("collapsing " + this.id);
					this._("children").fadeOut();
					this._attr("Expanded", "");
					this._tree()._nodeCollapsed();
				}
				this._syncState();
			}
        },
        _syncState : function()
        {
			if (this.Expanded())
			{
				this._("collapser").show();
				this._("expander").hide();
			}
			else
			{
				this._("collapser").hide();
				this._("expander").show();
			}
        },
        SetChildren : function(html)
        {
			this._("children").html(html);
        }
    }
);



//Reflective.Web.UI.Controls.Window = function(sClientId, sServerId, rootElementId)
//{
//    this.Inherits(Reflective.Web.UI.Controls.ContentBlock, sClientId, sServerId, rootElementId);
//    
//}

//Core.setInheritance(Reflective.Web.UI.Controls.Window, 
//    Reflective.Web.UI.Controls.ContentBlock);
//    
//Core.extend(
//    Reflective.Web.UI.Controls.Window, 
//    {
//        OnInit : function()
//        {
//            this.BindEvent("onshow", this.id, "AfterShow");
//            if (this._attr("Draggable"))
//            {
//                this.$el().draggable(
//                    { 
//                    handle : this._selectById(this._attr("TitleBarClientID")),
//                    opacity : 0.5,
//                    cursor : "move"
//                    }  
//                );
//            }
//            
//            this.CallBase(Reflective.Web.UI.Controls.ContentBlock, "OnInit");
//        },
//        
//        AfterShow : function(sender)
//        {
//            
//        },
//        ShowAt : function(x, y)
//        {
//            this.Show();
//            this.$el().css( { top : y, left : x } );
//        },

//        ShowCenter : function()
//        {
//            this.ShowAt(
//                (($(window).innerWidth() - this.$el().outerWidth()) / 2)  + $(document.body).scrollLeft(),
//                (($(window).innerHeight() - this.$el().outerHeight()) / 2)  + $(document.body).scrollTop()
//                );
//        }
//    }
//    
//);


//Reflective.Web.UI.Controls.IFrameWindow = function(sClientId, sServerId, rootElementId)
//{
//    this.Inherits(Reflective.Web.UI.Controls.Window, sClientId, sServerId, rootElementId);
//    
//}

//Core.setInheritance(Reflective.Web.UI.Controls.IFrameWindow, 
//    Reflective.Web.UI.Controls.Window);
//    
//Core.extend(
//    Reflective.Web.UI.Controls.IFrameWindow, 
//    {
//		OnInit : function()
//		{
//			this.CallBase(Reflective.Web.UI.Controls.Window, "OnInit");
//			this.BindEvent("visiblechanged", this.id, "_visibleChanged");
//		},
//		_visibleChanged : function(sender, visible)
//		{
//		}
//	}
//);
Reflective.Web.UI.Controls.Wizard = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormBase, clientId, serverId, rootElementId);
    this._nextBtn = null;
    this._prevBtn = null;
    this._cancelBtn = null;
    
    this._buttons = new Reflective.Web.Hashtable();
    this._submitBtns = new Array();
    
}

Core.setInheritance(Reflective.Web.UI.Controls.Wizard,
    Reflective.Web.UI.Controls.FormBase);
    

Core.extend(Reflective.Web.UI.Controls.Wizard,
    {
        OnInit : function()
        {
            this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnInit");
            
            this._setBtnState();
            
            this.BindEvent("pagechanged", this.id, "_setBtnState");
            var me = this;
            this._pageIds.foreach(
            
                function(pageId)
                {
                    var page = me.GetPage(pageId);
                    me._onPageCompleteChanged(page, page.IsComplete());
                    page.BindEvent("oncompletechanged", me.id, "_onPageCompleteChanged");
                }
            );            
        },
        OnFoundInput : function(inputElement)
        {
			this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnFoundInput", inputElement);
			
			if (inputElement.tagName.toUpperCase() == "BUTTON")
			{
				var type = $(inputElement).attr("type");
				var clientId = $(inputElement).attr("clientId");
			
				this._buttons.set(clientId, inputElement);
				
				if (type == "submit")
				{
					if (typeof (window[clientId]) != "undefined" &&
							window[clientId] != null)
    						window[clientId].BindEvent("onclick", this.id, "_submitBtnClick");	

					this._submitBtns.add(window[clientId]);
				}
				else if (type == "cancel")
				{
					window[clientId].BindEvent("onclick", this.id, "_cancelClick");
				}
				else
				{
					var wizardType = $(inputElement).attr("wizardType");
					if (wizardType == "next")
					{
						this._nextBtn = window[clientId];
						this._nextBtn.BindEvent("onclick", this.id, "_nextClick");
					}
					else if (wizardType == "prev")
					{
						this._prevBtn = window[clientId];
						this._prevBtn.BindEvent("onclick", this.id, "_prevClick");
					}
				}
			}
        },
        SubmitButtons : function() { return this._submitBtns; },
    	_submitBtnClick: function(sender, e) 
    	{
    		//first cancel the submit event on the form 
    		DomHelper.CancelBubble(e);
    		DomHelper.CancelEvent(e);
    		this.Submit(e);
    	},
        _cancelClick : function(sender, e)
        {
			DomHelper.CancelEvent(e);
			DomHelper.CancelBubble(e);
            this.Cancel();
        },
        _onPageCompleteChanged : function(page, isComplete)
        {
            this.EnableMenuItem(this.GetNextPageId(page.ServerId), isComplete);
            this._setBtnState();
        },
        _setBtnState : function()
        {
            if (this._nextBtn) 
            {
				this._nextBtn.SetEnabled(this._pageIndex < this.PageCount() - 1 && this.GetPage(this._pageId).IsComplete());
				this._prevBtn.SetEnabled(this._pageIndex > 0);
			}
			
            var nextId = this.GetNextPageId(this._pageId);
            
            var me = this;
            this._pageIds.foreach(
            
                function(pageId)
                {
                    var enable = false;
                    if (pageId == nextId)
                        enable = me.GetPage(me._pageId).IsComplete();
                    else
                        enable = me.GetPageIndex(pageId) <= me._pageIndex || me.GetPage(pageId).IsComplete();
                        
                    me.EnableMenuItem(pageId, enable);
                }
            );
            
            this.AllowSubmit(this.IsComplete());

        },
        IsComplete : function()
        {
            var isComplete = true;
            
            for (var i = 0; i < this._pageIds.length; i++)
            {
                if (!this.GetPage(this._pageIds[i]).IsComplete())
                    return false;
            }
            
            return true;
        },
        _nextClick : function(sender, e)
        {
            this._btnClicked(e);
            if (this.OnNext())
                this.ShowPage(this.GetNextPageId(this._pageId));
        },
        _prevClick : function(sender, e)
        {
            this._btnClicked(e);
            if (this.OnPrevious())
                this.ShowPage(this.GetPrevPageId(this._pageId));
        },
        _finishClick : function(sender, e)
        {
            this._btnClicked(e);
            if (this.OnFinish())
                this.Submit(e);
        },
        _btnClicked : function(e)
        {
            DomHelper.CancelBubble(e);
            DomHelper.CancelEvent(e);
        },
        _fireBtnEvent : function(eventName)
        {
            var args = new Reflective.Web.CancelEventArgs();
            this.FireEvent(eventName, args);
            if (args.Cancel)
                return false;
                
            return true;
        },
        OnFinish : function()
        {
            return this._fireBtnEvent("onfinish");
        },
        OnNext : function()
        {
            return this._fireBtnEvent("onnext");
        },
        OnPrevious : function()
        {
            return this._fireBtnEvent("onprevious");
        },
        AllowNext : function(allow)
        {
			if (!this._nextBtn) return;
			
            if (allow != null)
                this._nextBtn.SetEnabled(allow);
            else
                return this._nextBtn.Enabled();
        },
        AllowPrevious : function(allow)
        {
			if (!this._nextBtn) return;
			
            if (allow != null)
                this._prevBtn.SetEnabled(allow);
            else
                return this._prevBtn.Enabled();
            
        },
        OnEnterPressed : function(e)
        {
            DomHelper.CancelEvent(e);
            if (this._pageIndex == this.PageCount() - 1 && this.AllowSubmit())
                this.Submit(e);
            else if (this.AllowNext())
                this.ShowPage(this.GetNextPageId(this._pageId));
        },
        OnSubmitBegin : function()
        {
            
        },
        OnSubmitEnd : function()
        {
        },
        OnAllowSubmit : function(allow)
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnAllowSubmit", allow);
			this.SubmitButtons().foreach(
				function(btn)
				{
					console.log("Setting enabled for: " + btn.id + " (" + allow + ")");
					btn.SetEnabled(allow);
				}
			);
    	},
    	OnAllowInput : function(allow)
    	{
    		this.CallBase(Reflective.Web.UI.Controls.FormBase, "OnAllowInput", allow);
    		
    		if (!allow)
                this._saveBtnState();
            
            this._setBtnAllowInput(allow);
    	},
        _saveBtnState : function()
        {
            this._buttons.foreach(
                function(button)
                {
                    button._wasDisabled = !button.Enabled();
                }
            );  
        },
        _setBtnAllowInput : function(allow)
        {
            this._buttons.foreach(
                function(button)
                {
                    if (!button._wasDisabled)
                        button.SetEnabled(allow);
                }
            );  
        }
    }
);

Reflective.Web.UI.Controls.WizardPageEventArgs = function(pageId)
{
    this.pageId = pageId;
}
Reflective.Web.UI.Controls.WizardPage = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Controls.FormPage, clientId, serverId, rootElementId);
    this._wizardClientId = null;
    this._isComplete = false;
}

Core.setInheritance(Reflective.Web.UI.Controls.WizardPage,
    Reflective.Web.UI.Controls.FormPage);
    

Core.extend(Reflective.Web.UI.Controls.WizardPage,
    {
        
    }
);



Reflective.Web.UI.Controls.WizardUserControlPage = function(clientId, typeName)
{
    this.Inherits(Reflective.Web.UI.Controls.FormUserControlPage, clientId, typeName);
    this._wizardPageClientId = "";
    this.WizardPage = null;
}

Core.setInheritance(Reflective.Web.UI.Controls.WizardUserControlPage,
    Reflective.Web.UI.Controls.FormUserControlPage);
    
Core.extend(
    Reflective.Web.UI.Controls.WizardUserControlPage, 
    {
        
    }
    
);

