
function core() 
{
    this._onloads = new Array();
    this._inheritanceObjects = new Array();
    
    var url = window.location.href;
    if (url.indexOf("?") > -1)
        url = url.substring(0, url.indexOf("?"));
        
    this.currentUrl = url;
}

core.prototype = 
{
    registerNamespace: function(namespaceName)
    {
        var nsParts = namespaceName.split(".");
        var ns = "";
        for (var i = 0; i < nsParts.length; i++)
        {
            var part = nsParts[i];
            if (ns == "")
                ns = part;
            else
                ns += "." + part;
            
            if (!window[ns])
            {
                var parent = "";
                if (ns.indexOf(".") > -1)
                    parent = ns.substring(0, ns.lastIndexOf("."));
                
                if (parent != "")
                {
                    var parentNs = window[parent];
                    parentNs.addChild(part);
                }
                else
                {
                    new Namespace(null, ns);
                }
            }
        }
        
    }, 
    
    setInheritance : function(type, base)
    {
        type.prototype = new base;
    },
        
    extend : function(typeToExtend, methods)
    {    
        for (var prop in methods)
        {
            typeToExtend.prototype[prop] = methods[prop];
        }
    },
    
    addOnLoad : function(fnOrString)
    {
        this._onloads[this._onloads.length] = fnOrString;
    },
    
    
    _onload : function()
    {
        if (!this._onloads) return;
        
        ////trace.writeHighest("Core._onload (" + this._onloads.length + " onload calls listed)");
        for (var i = 0; i < this._onloads.length; i++)
        {
            var item = this._onloads[i];
            if (typeof(item) == "string")
            {
                //alert("Calling function: " + item + "(); [" + i + "]");
                eval(item + "();");
            }
            else
                item();
        }
    }
}

var Core = new core();

function _onload()
{
    Core._onload();
}

window.onload = _onload;

function Namespace(parent, name)
{
    this._parent = parent;
    this.name = name;
    window[name] = this;
}

Namespace.prototype =
{
    addChild : function(name)
    {
        this[name] = new Namespace(this, this.name + "." + name);
    }
}

Core.registerNamespace("Reflective.Web");

Array.prototype.IsArray = true;
///<summary>Adds a contains method to the Array prototype.</summary>
///<param name="sItem">The item to look for.</param>
///<param name="bCaseSensitive">Whether to do a case-sensitive search or not. Default is true.</param>
///<returns>True if the item is contained in the array, false if it isn't.</returns>
Array.prototype.contains = function(sItem, bCaseSensitive)
{
    for (var i = 0; i < this.length; i++)
    {
        if (bCaseSensitive == null || bCaseSensitive)
        {
            if (this[i] == sItem) return true;
        }
        else
        {
            if (this[i].toUpperCase() == sItem.toUpperCase())
                return true;
        }
            
    }
    
    return false;
}

Array.prototype.indexOf = function(value)
{
    for (var i = 0; i < this.length; i++)
    {
        if (this[i] == value) return i;
    }
    return -1;
}

///<summary>Adds a remove method to the Array prototype.</summary>
///<param name="item">The item to remove.</param>
Array.prototype.remove = function(item)
{
    for (var i = 0; i < this.length; i++)
    {
        if (this[i] == item)
        {
            this.removeIndex(i);
        }
    }

}

Array.prototype.removeIndex = function(index)
{
    this.splice(index, 1);
}

///<summary>Adds a clear method to the Array prototype, which clears all elements from the Array.</summary>
Array.prototype.clear = function()
{
    this.length = 0;
}

Array.prototype.add = function(item)
{
    this[this.length] = item;
    return this.length - 1;
}

Array.prototype.CopyTo = function(array)
{
    for (var i = 0; i < this.length; i++)
        array[array.length] = this[i];
}

Array.prototype.RemoveByID = function()
{
    for (var i = 0; i < this.length; i++)
    {
        for (var x = 0; x < arguments.length; x++)
        {
            var id = this[i].ID;
            if (id == null) id = this[i].id;
            
            if (arguments[x] == id)
                this.splice(i, 1);
        }
    }
}

Array.prototype.FindByID = function()
{
    var ret = null;
    if (arguments.length > 1)
        ret = new Array();
    for (var i = 0; i < this.length; i++)
    {
        for (var x = 0; x < arguments.length; x++)
        {
            var id = this[i].ID;
            if (id == null) id = this[i].id;
            
            if (arguments[x] == id)
            {
                if (arguments.length > 1)
                    ret.add(this[i]);
                else
                    return this[i];
            }
        }
    }
    
    return ret;
}

///<summary>Inserts items into the array starting at the specified index</summary>
///<param name="index">The index at which to start inserting objects.</param>
///<param name="items">An array of items to insert</param>
///<example>
/// //Given that array1 is an array containing some elements...
/// array1.insert(4, [item1, item2, item3]);
/// array1.insert(0, [item5]);
///</example>
Array.prototype.insert = function(index, items)
{
    if (!items || items.length == 0) return;
    
    if (index == this.length)
    {
        this.append(items);
    }
    else
    {
        var keepitems = this.slice(index);
        this.splice(index, this.length - index);
        
        for (var i = 1; i < items.length; i++)
            this.add(this.items[i]);
            
        for (var i = 0; i < keepitems.length; i++)
            this.add(keepitems[i]);
    }
}

Array.prototype.append = function(array)
{
    if (array == null || array.length == 0) return;
    
    for (var i = 0; i < array.length; i++)
        this.add(array[i]);
}
Array.prototype.foreach = function(iterator)
{
    for (var i = 0; i < this.length; i++)
        iterator(this[i]);
}

Array.prototype.IsArray = true;

Array.Combine = function()
{
    var a = new Array();
    
    for (var x = 0; x < arguments.length; x++)
    {
        var array = arguments[x];
        if (array)
        {
            for (var i = 0; i < array.length; i++)
                a.add(array[i]);
        }   
        
    }
    return a;
}




window["ShowProgressModal"] = function(title, text, allowCancel)
{
    if (!window.ProgDialogDefined)
    {
        var h = "<table class=\"Dialog\" id=\"ProgDialog\" style=\"display:none;position:absolute;z-index:3001;\" border=\"0\" cellpadding=\"2\" cellspacing=\"0\">"
                + "<tr><td class=\"DialogTitle\" id=\"ProgDialogTitle\">" + title + "</td></tr>"
                + "<tr><td class=\"DialogBody\" id=\"ProgDialogBody\">"
                    + "<img src=\"" + Reflective.Web.UI.CurrentTheme.DefaultImages.ProgressImg.Src + "\"/><br/>"
                    + "<div id=\"ProgDialogText\">" + text + "</div>"
                + "</td></tr>"
             + "</table>";
             
        $(document.body).append(h);
        window.ProgDialogDefined = true;
    }
    
    window.ShowModal();
    
    var d = $("#ProgDialog");
    d.fadeIn();
    var x = (($(window).innerWidth() - d.outerWidth()) / 2)  + $(document.body).scrollLeft();
    var y = (($(window).innerHeight() - d.outerHeight()) / 2)  + $(document.body).scrollTop();
    d.css( { top : y, left : x } );
    
}

window["HideProgressModal"] = function()
{
    if (!window.ProgDialogDefined) return;
    
    window.HideModal();
    $("#ProgDialog").fadeOut();
}

window["ShowModal"] = function()
{
    if (!window.ModalDefined)
    {
        var h = "<div class=\"ModalDiv\" id=\"ModalDiv\" style=\"background-color: black; display:none; position:absolute; top: 0px; left: 0px; z-index:3000;\" onclick=\"DomHelper.CancelBubble(event);\"></div>";
        $(document.body).append(h);
        window.ModalDefined = true;
    }
    
    $("#ModalDiv").css( { width : $(window).innerWidth(), height : $(window).innerHeight(), opacity : 0.5 } );
    $("#ModalDiv").show();
    return 3000;
}

window["HideModal"] = function()
{
    if (!window.ModalDefined) return;
    $("#ModalDiv").fadeOut();
}

window.idCounter = 1;

window["NewId"] = function(baseName)
{
   window.idCounter++;
   return baseName ? baseName + "_" + window.idCounter : "object_" + window.idCounter;
}

String.Empty = "";

///<summary>Adds a ReplaceAll function to the String prototype.</summary>
///<param name="sWhatToReplace">What to replace in the string.</param>
///<param name="sReplaceWith">What to replace it with.</param>
///<returns>The string with the specified replacements.</returns>
String.prototype.ReplaceAll = function(sWhatToReplace, sReplaceWith)
{
    var reg = eval("/" + sWhatToReplace + "/g");
    return this.replace(reg, sReplaceWith);
}


String.prototype.IsNullOrEmpty = function()
{
    return (this == null || this == "");
}

String.prototype.StartsWith = function(string)
{
    if (this.length < string.length) return false;
    
    return (this.substring(0, string.length) == string);
}
String.prototype.Trim = function()
{
    var chr = this.substring(0, 1);
    var i = 0;
    var str = "";
    
    while (chr == " ")
    {
        i++;
        str = this.substring(i);
    }
    
    i = this.length - 1;
    chr = this.substring(i, 1);
    while (chr == " ")
    {
        str = this.substring(0, i);
        i--;
    }
    
    return str;
}

String.prototype.Contains = function(string)
{
    return this.indexOf(string) > -1;
}

String.prototype.IsNumeric = function()
{
    if (this.length == 0)
        return false;
        
    var nums = "0123456789";
    
    var start = 0;
    if (this.substring(0, 1) == "-")
        start = 1;
        
    for (var i = start; i < this.length; i++)
    {
        var c = this.substring(i, 1);
        var found = false;
        for (var x = 0; x < nums.length; x++)
        {
            if (nums.substring(x, 1) == c)
            {
                found = true;
                break;
            }
        }
        
        if (!found)
            return false;
    }
    
    return true;
}


String.Format = function(string)
{
    if (arguments.length < 2)
        return string;
    
    var ret = string;
    
    for (var i = 1; i < arguments.length; i++)
    {
        ret = ret.replace("{" + (i - 1) + "}", arguments[i]);
    }
    
    return ret;
}

if (typeof(console) == "undefined")
{
	//browser-safe firebug console wrapper...
	window.console =
	{
		log : function() {},	
		debug : function() {},
		error : function() {},
		warn : function() {},
		assert : function() {},
		info : function() {},
		dir : function() {},
		dirXml : function() {},
		trace : function() {},
		group : function() {},
		groupEnd : function() {},
		time : function() {},
		timeEnd : function() {},
		profile : function() {},
		profileEnd : function() {},
		count : function() {}
	};
}

Reflective.Web.ReflectiveObject = function(id)
{
    if (!id) return;
    
    console.log("Object " + id + " created...");
    this.ClientId = id;
    this.id = id;
    try
    {
		window[id] = this;
	}
	catch (e)
	{
		console.log("error with " + id + ": " + e.description);
	}
    
    this.eventListeners = null;
    Core.addOnLoad(this.id + ".Init");
}

Core.extend(
    Reflective.Web.ReflectiveObject,
    {
    
        Init : function()
        {
            trace.writeHighest("[Initializing " + this.id + "]");
            this.OnInit();
            trace.writeHighest("[Initialization complete]");
            this.FireEvent("initcomplete", this);
        },
        
        OnInit : function() {},
        CallBase : function(type, methodName, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
        {
            var fn = type.prototype[methodName];
            if (fn)
            {
                return fn.call(this, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
            }
            else
				return false;
        },
        Inherits : function(fn, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
        {
            if (fn.call)
            {
                fn.call(this, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9);
            }
        },

        Implements : function(sInterfaceName, arg0, arg1, arg2, arg3, arg4, arg5, arg6)
        {
            if (typeof(arg0) != "undefined")
            {
                eval("this." + sInterfaceName + " = " + sInterfaceName + ";");
                eval("this." + sInterfaceName + "(" + arg0 + "," + arg1 + "," + arg2 + "," + arg3 + "," + arg4 + "," + arg5 + "," + arg6 + ");");
            }
        },


        BindEvent : function(eventName, functionOrObjectId, methodName)
        {
            if (!functionOrObjectId) return;
            
            
            if (!this.eventListeners) this.eventListeners = new Reflective.Web.Hashtable();
            
            if (!this.eventListeners.get(eventName)) this.eventListeners.set(eventName, new Array());
            
            var handler = methodName ? functionOrObjectId + "." + methodName : functionOrObjectId;
            if (!this.eventListeners.get(eventName).contains(handler))
                this.eventListeners.get(eventName).add(handler);
            
            trace.writeHighest("event bound: " + this.id + "." + eventName + " " + handler);
        },


        FireEvent : function(eventName, args)
        {
            trace.writeHighest("firing event : " + this.id + "." + eventName);
            
            if (!this.eventListeners || !this.eventListeners.get(eventName)) return false;
            
            var sender = this;
            var listeners = this.eventListeners.get(eventName);
            listeners.foreach(
                function(item)
                {
                    if (typeof(item) == "string")
                    {
                        eval(item + "(sender, args);");
                    }
                    else
                    {
                        item(sender, args);
                    }
                }
            );
            return true;
        },

        BindToObjEvent : function(targetObject, eventName, myWindowId, myMethodName)
        {
            if (!eventName) return;
            
            targetObject.BindEvent(eventName, myWindowId + "." + myMethodName);
        },
        MapFunction : function(myFunction, objFunction)
        {
            objFunction = myFunction;
        },
        EventIsBound : function(eventName)
		{
			return this.eventListeners != null && this.eventListeners.containskey(eventName);
        }
    }
);
Reflective.Web.EventArgs = function(windowEvent)
{
    this.Inherits(Reflective.Web.ReflectiveObject);
    this.event = windowEvent;
}

Core.setInheritance(Reflective.Web.EventArgs, Reflective.Web.ReflectiveObject);

Reflective.Web.CancelEventArgs = function()
{
    this.Cancel = false;
}

Reflective.Web.ContinueEventArgs = function()
{
    this.Continue = true;
}



Reflective.Web.Hashtable = function(keysAndValues)
{
    this._keys = new Array();
    this._values = new Array();
    
    if (keysAndValues)
    {
		for (var i = 0; i < keysAndValues.length; i++)
		{
			this.add(keysAndValues[i][0], 
				keysAndValues[i][1]);
		}
    }
}

Core.extend(
    Reflective.Web.Hashtable,
    {
        keys : function() { return this._keys; } ,
        values : function() { return this._values; },
        count : function() { return this._keys.length; },
        toQueryString : function()
        {
            var t = this;
            var p = "";
            t.foreachKey(
                function(key)
                {
                    if (p != "") p += "&";
                    p += key + "=" + encodeURIComponent(t.get(key));
                }
            ); 
            
            return p; 
        },
        
        add : function(key, value)
        {
            if (this.containskey(key))
                throw "Key " + key + " already exists...";
            
            this._values[this._keys.add(key)] = value;
        },

        containskey : function(key)
        {
            return this._keys.indexOf(key) > -1;
        },

        containsvalue : function(value)
        {
            return this._values.indexOf(value) > -1;
        },

        set : function(key, value)
        {
            if (!this.containskey(key))
                this.add(key, value);
            else
                this._values[this._keys.indexOf(key)] = value;
        },

        remove : function(key)
        {
            var index = this._keys.indexOf(key);
            if (index > -1)
            {
                this._keys.remove(index);
                this._values.remove(index);
            }
        },

        get : function(key)
        {
            var index = this._keys.indexOf(key);
            if (index < 0 || index > this._values.length - 1) return null;
            
            return this._values[this._keys.indexOf(key)];
        },

        clear : function()
        {
            this._values.clear();
            this._keys.clear();
        },

        foreach : function(iterator)
        {
            for (var i = 0; i < this._keys.length; i++)
            {
				var returnValue = iterator(this.get(this._keys[i]));
				if (returnValue != null && returnValue == false)
					break;
            }
        },

        foreachKey : function(iterator)
        {
            for (var i = 0; i < this._keys.length; i++)
            {
				var returnValue = iterator(this._keys[i], this.get(this._keys[i]));
				if (returnValue != null && returnValue == false)
					break;
            }
        },

        copyTo : function(hashtable)
        {
            hashtable.clear();
            
            //alert("copying " + this._keys.length + " values to the hashtable.");
            for (var i = 0; i < this._keys.length; i++)
            {
                //alert(this._keys[i]);
                hashtable.add(this._keys[i], this.get(this._keys[i]));
            }
        },
        clone : function()
        {
            var h = new Reflective.Web.Hashtable();
            this.copyTo(h);
            return h;
        },
        join : function(rowSeparator, keyValueSeparator)
        {
            var s = "";
            var t = this;
            this.foreachKey(
                function(key)
                {
                    if (s != "")
                        s += rowSeparator;
                        
                    s += key + keyValueSeparator + (t.get(key) || "");
                }
            );
            
            return s;
        }
    }
);


Core.registerNamespace("Reflective.Web.UI");



Reflective.Web.UI.ReflectiveControl = function(sClientId, sServerId, sRootElementId)
{
    this.Inherits(Reflective.Web.ReflectiveObject, sClientId);
    
    this.ElementId = sRootElementId;
    this.ServerId = sServerId;
    this.RootElementId = sRootElementId;
    this._element = null;
    
}

Core.setInheritance(Reflective.Web.UI.ReflectiveControl, 
    Reflective.Web.ReflectiveObject);

Core.extend(
    Reflective.Web.UI.ReflectiveControl,
    { 

        NewInstance : function(sTypeName, sClientId, sServerId, sRootElementId)
        {
            var type = eval(sTypeName); 
            try
            {
				var instance = new type(sClientId, sServerId, sRootElementId);
				window[sClientId] = instance;
				window[sClientId]._init();
			}
			catch (e)
			{
				alert("Error creating instance of type: " + sTypeName + ": " + e.description);
				throw e;
			}
        },
        _init : function()
        {
			if (!this.Enabled())
				this.SetEnabled(false);
        },
        SetClass : function(className)
        {
            this.OnSetClass(className);
        },
        GetClass : function()
        {
            return this.OnGetClass();
        },
        OnSetClass : function(className)
        {
            this._attr("class", className);
        },
        OnGetClass : function()
        {
            return this._attr("class");
        },
        SetStyle : function(styleName, value)
        {
			this.OnSetStyle(styleName, value);
        },
        OnSetStyle : function(styleName, value)
        {
			this.$el().css(styleName, value);
        },
        GetStyle : function(styleName)
        {
			return this.OnGetStyle(styleName);
        },
        OnGetStyle : function(styleName)
        {
			return this.$el().css(styleName);
        },
        Enabled : function()
        {
            return this._attr("enabled") == "1";
        },
        SetEnabled : function(enabled)
        {
			console.log(this.id + ".SetEnabled(" + enabled + ")");
            if (enabled)
                this.Enable();
            else
                this.Disable();
        },
        Enable : function(suppressEvent)
        {
			console.log("ReflectiveControl.Enable(" + suppressEvent + ");");
            if (this.OnEnable()) 
            {
				console.log("CssClass = '" + this._attr("cssClass") + "'");
                this._attr("enabled", "1");
                if (this._attr("cssClassDisabled"))
                    this.SetClass(this._attr("cssClass"));

                if (!suppressEvent)
                    this.FireEvent("onenabled", this);
            }
        },
        
        OnEnable : function() { return true; },
        
        Disable : function(suppressEvent)
        {
			console.log("ReflectiveControl.Disable(" + suppressEvent + ");");
            if (this.OnDisable()) 
            {
                this._attr("enabled", "");
                
                console.log("setting class to: " + this._attr("cssClassDisabled"));
                if (this._attr("cssClassDisabled"))
                    this.SetClass(this._attr("cssClassDisabled"));
                    
                if (!suppressEvent) this.FireEvent("ondisabled", this);
            }
        },
        
        OnDisable : function() { return true; },
        
        Hide : function(fadeOut, delay)
        {
            trace.writeHigh(this.id + ".Hide();");
            if (this.OnHide(fadeOut, delay))
            {
                this._attr("visible", "");
                this.FireEvent("onhide", this);
            }
        },
        
        OnHide : function(fadeOut, delay)
        {
            if (!fadeOut)
                this.$el().hide();
            else
                this.$el().fadeOut(delay);
                
            this.FireEvent("visiblechanged", this, false);
            
            return true;
        },
        Show : function(fadeIn, delay)
        {
            trace.writeHigh(this.id + ".Show();");
            if (this.OnShow(fadeIn, delay ? delay : 500))
            {
                this._attr("visible", "1");
                this.FireEvent("onshow", this);
            }
        },
        
        OnShow : function(fadeIn, delay)
        {
            if (!fadeIn)
                this.$el().show();
            else
                this.$el().fadeIn(delay);
            
            this.FireEvent("visiblechanged", this, true);
            
            return true;
        },
        
        Visible : function()
        {
            return this._attr("visible");
        },
        
        SetVisible : function(visible, fade, delay)
        {
            if (visible)
                this.Show(fade, delay);
            else
                this.Hide(fade, delay);
        },
        
        SetFocus : function(focus)
        {
            this.OnSetFocus(focus);
        },
        OnSetFocus : function(value)
        {
			if (value)
                this.$el().focus();
            else
                this.$el().blur();
        },
        Click : function(evt)
        {
			console.log(this.id + ".Click");
            if (this.Enabled() && this.OnClick(evt))
                this.FireEvent("onclick", evt);
            
        },

        OnClick : function(evt) { return true; },
        
        Change : function(evt)
        {
			console.log(this.id + ".Change");
            if (this.Enabled() && this.OnChange(evt))
                this.FireEvent("onchange", evt);
            
        },

        OnChange : function(evt) { return true; },
        
        _doHover : function()
        {
            return this._attr("doHover") == "1";
        },
        
        MouseOver : function(evt)
        {
			if (this._doHover() && this.Enabled())
            {
                this._attr("class", this._attr("hoverClass"));
            }
            
            if (this.OnMouseOver(evt))
            {
                this.FireEvent("onmouseover", this, evt);
            }
        },

        OnMouseOver : function(evt) 
        { 
            return true; 
        },
        
        MouseOut : function(evt)
        {
            if (this._doHover() && this.Enabled())
            {
                this._attr("class", this._attr("cssClass"));
            }
            if (this.OnMouseOut(evt))
                this.FireEvent("onmouseout", evt);
        },

        OnMouseOut : function(evt) { return true; },
        
        Focus : function(evt)
        {
            if (this.OnFocus(evt))
                this.FireEvent("onfocus", evt);
            else
                DomHelper.CancelEvent(evt);
                
        },

        OnFocus : function(evt) { return true; },
        
        Blur : function(evt)
        {
            if (this.OnBlur(evt))
                this.FireEvent("onblur", evt);
            else
                DomHelper.CancelEvent(evt);
        },

        OnBlur : function(evt) { return true; },
        
        KeyUp : function(evt)
        {
            if (this.OnKeyUp(evt))
                this.FireEvent("onkeyup", evt);
            else
                DomHelper.CancelEvent(evt);
        },

        OnKeyUp : function(evt) { return true; },
        
        KeyDown : function(evt)
        {
            if (this.OnKeyDown(evt))
                this.FireEvent("onkeydown", evt);
            else
                DomHelper.CancelEvent(evt);
        },

        OnKeyDown : function(evt) { return true; },
        
        KeyPress : function(evt)
        {
            if (this.OnKeyPress(evt))
                this.FireEvent("onkeypress", evt);
            else
                DomHelper.CancelEvent(evt);
        },

        OnKeyPress : function(evt) { return true; },
        
        
        $el : function()
        {
            if (this._element && this._element.length > 0) return this._element;
            this._element = $("#" + this.RootElementId);
            return this._element;
        },

        _attr : function(name, value)
        {
            if (typeof(value) != "undefined")
                this.$el().attr(name, value);
            else
                return this.$el().attr(name);
        },
        GetAttribute : function(name)
        {
            return this._attr(name);
        },
        _selectById : function(elementId)
        {
            return $("#" + elementId);
        },
        _ : function(elementId)
        {
            return this._selectById(this.ClientId + "_" + elementId);
        },
        findChildren : function(attrName, value)
        {
			return this.$el().find("[" + attrName + "='" + value + "']");
        },
        GetHeight : function()
        {
            return this.OnGetHeight();
        },
        OnGetHeight : function()
        {
            return this.$el().outerHeight();
        },
        GetInnerHeight : function()
        {
            return this.OnGetInnerHeight();
        },
        OnGetInnerHeight : function()
        {
            return this.$el().innerHeight();
        },
        _showProgress : function(className, text, imgUrl)
        {
            var el = this.$el();
            if (!el.css("position") || el.css("position") == "static")
				el.css("position", "relative");
			
            var myHeight = this.GetInnerHeight();
            var w = el.innerWidth() - 5;
            className = className || this._attr("progCssClass");
            
            var div = "<div id=\"" + this.id + "_prog\" class=\"" + className + "\" style=\"display:none;position:absolute;top:0px;left:0px;width:" + w + "px;text-align:center\">";
            if (imgUrl)
                div += "<img src=\"" + imgUrl + "\" /><br/>";
            if (text)
                div += text;
                
            div += "</div>";
                
            el.append(div);
            
            var expandMyHeight = this._("prog").height() > myHeight;
            if (expandMyHeight)
            {
                this._attr("resetHeight", "1");
                el.css( { height : this._("prog").height() } );
            }
            var prog = this._("prog");
            prog.show();
            prog.css("padding-top", this._("prog").height() / 2);
            prog.css("opacity", 0.5);
            
            if (!expandMyHeight)
                prog.css( { height : (myHeight - 5) } );
        },
        _hideProgress : function()
        {
            if (this._("prog"))
                this._("prog").fadeOut();
                
            if (this._attr("resetHeight"))
            {
                this.$el().css( { height : "" } );
                this._attr("resetHeight", "");
            }
        }
    }
);

var reflectiveControl = new Reflective.Web.UI.ReflectiveControl();


function FireEvent(evt, clientId, methodName, arg1, arg2, arg3, arg4, arg5)
{
	var obj = window[clientId];
    if (obj)
    {
        try
        {
            eval("obj." + methodName + "(evt, arg1, arg2, arg3, arg4, arg5);");
        }
        catch (e) {}
    }
}


Reflective.Web.UI.AjaxEnabledControl = function(clientId, serverId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, clientId, serverId, rootElementId);
    this._params = new Reflective.Web.Hashtable();
    this._staticparams = new Reflective.Web.Hashtable();
    this._rq = null;
    this._currentEventName = "";
}

Core.setInheritance(Reflective.Web.UI.AjaxEnabledControl,
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.AjaxEnabledControl,
    {
        UseAjax : function() { return this._attr("UseAjax"); },
        _progDispType : function() { return this._attr("progDispType"); },
        _progDelay : function() { return this._attr("progDelay"); },
        _progressText : function() { return this._attr("progTxt") || "Loading.."; },
        _progImgUrl : function() { return this._attr("progImg"); },
        _progCssClass : function() { return this._attr("progCssClass"); },
        _callBackType : function() { return this._attr("CallBackType"); },
        _iframeId : function() { return this._attr("iframeId"); },
        FireServerEvent : function(eventName)
        {
            this.OnFireServerEvent(eventName);
        },
        OnFireServerEvent : function(eventName)
        {
            this.SetCallBackParam("_eventName", eventName);    
            this._currentEventName = eventName;
            this.CallBack("POST");
        },
        ShowProgress : function()
        {
            if (this._progDispType() != "None")
            {
                this.OnShowProgress(this._progCssClass(), this._progressText(), this._progImgUrl());
            }
        },
        OnShowProgress : function(className, text, imgUrl)
        {
            if (this._progDispType() == "Inline")
            {
                this._showProgress(className, text, imgUrl);
            }
            else
            {
                window.ShowProgressModal("Working...", text, false);
            }
        },
        HideProgress : function()
        {
            if (this._progDispType() == "None") return;
            
            if (this._progDispType() == "Inline")
            {
                this._hideProgress();
            }
            else
            {
                window.HideProgressModal();
            }
        },
        _request : function()
        {
            if (!this._rq)
            {
                var url = this._attr("CallBackUrl") || Core.currentUrl;
                this._rq = new Reflective.Web.HttpRequest(this.id + "_rq", url);
                this._rq.SetStaticParam("cb_sourceId", this.ServerId);
                this._rq.SetStaticParam("cb_sourceClientId", this.ClientId);
                this._rq.SetStaticParam("cb_source", this._attr("SourceUrl"));
                this._rq.SetStaticParam("cb_iframe", this._callBackType() == "IFrame" ? "1" : "");
                
                this._rq.BindEvent("oncomplete", this.id + ".CallBackComplete");
                this._rq.BindEvent("onabort", this.id + ".CallBackAbort");
                this._rq.BindEvent("onerror", this.id + ".CallBackError");
            
            }
            
            return this._rq;
        },
        
        ///<summary>Clears parameters from the bound callback object.</summary>
        ClearCallBackParams : function() 
        { 
            this._request().ClearParams(); 
        },
        ///<summary>Sets parameters on the callback object. These parameters will be transmitted in the request headers either via querystring or form post data.</summary>
        ///<param name="sKey">The key</param>
        ///<param name="sValue">The value</param>
        SetCallBackParam : function(key, value)
        {
            this.OnSetCallBackParam(key, value);
        },
        OnSetCallBackParam : function(key, value)
        {
			if (this._callBackType() == "Script")
				this._request().SetParam(key, value);
				
			this.FireEvent("onsetparam", new Reflective.Web.UI.AjaxCallBackParamArgs(key, value));
        },
        ///<summary>Gets a parameter that has already been set on the callback object.</summary>
        ///<param name="sKey">The key of the parameter</param>
        ///<returns>The value returned by the CallBackObject parameter.</returns>
        GetCallBackParam : function(sKey)
        {
            this._request().GetParam(sKey);
        },
        
        ///<summary>Sets static parameters on the callback object. These parameters will remain in the list of params even after calling the ClearParams method. They will be transmitted in the request headers either via querystring or form post data.</summary>
        ///<param name="sKey">The key</param>
        ///<param name="sValue">The value</param>
        SetStaticCallBackParam : function(sKey, sValue)
        {
            this._request().AddStaticParam(sKey, sValue);
        },
        
        CancelCallBack : function()
        {
            this._request().Abort();
        },
        ///<summary>Initiates the callback to the server.</summary>
        ///<param name="method">The RequestMethod to use (RequestMethod.Get or RequestMethod.Post).</param>
        CallBack : function(method)
        {
			console.log(this.id + ".CallBack");
            var args = new Reflective.Web.CancelEventArgs();
            this.FireEvent("onbeforecallback", args);
            if (args.Cancel)
                return;
            
            console.log("Calling back to: " + this._request().TargetUrl);
            
            this.ShowProgress();
            if (method.toLowerCase() == "post")
                this._request().Post();
            else
                this._request().Get();
        },
        
        ///<summary>Initiates a synchronous callback to the server.</summary>
        ///<param name="method">The RequestMethod to use (RequestMethod.Get or RequestMethod.Post).</param>
        SyncCallBack : function(method)
        {
            if (method.toLowerCase() == "post")
                return this._request().SyncPost();
            else
                return this._request().SyncGet();
        },
        
        CallBackComplete : function(sender, args)
        {
            this.HideProgress();
            if (args.responseType == Reflective.Web.CallBackResponseType.Redirect && args.redirecturl != "")
            {
                if (this.OnBeforeCallBackRedirect(sender, args))
                    window.location.href = args.redirecturl;
            }
            else
            {
				if (this._currentEventName)
					args.EventName = this._currentEventName;
					
                this.OnCallBackComplete(sender, args);
                this.FireEvent("oncallbackcomplete", this, args);
                this._currentEventName = "";
            }
        },
        CallBackError : function(sender, args)
        {
            this.HideProgress();
            this.OnCallBackError(sender, args);
            this.FireEvent("oncallbackerror", this, args);
        },
        CallBackAbort : function(sender, args)
        {
            this.HideProgress();
            this.OnCallBackAbort(sender, args);
            this.FireEvent("oncallbackabort", this, args);
        },
        ///<summary>Fires when the callback completes. You will need to override this method in your object to know when a callback has returned.</summary>
        ///<param name="sender">The callback object</param>
        ///<param name="args">A CallBackEventArgs instance.</param>
        OnCallBackComplete : function(sender, args) { throw "The AjaxEnabledControl must implement the OnCallBackComplete method."; },
        
        ///<summary>Fires when the callback aborts. You will need to override this method in your object to know when a callback has aborted.</summary>
        ///<param name="sender">The callback object</param>
        ///<param name="args">A CallBackEventArgs instance.</param>
        OnCallBackAbort  : function(sender, args) 
        {
			alert(args.responseText);
        },
        
        ///<summary>Fires when the callback fails for some reason. You will need to override this method in your object to know when a callback has failed.</summary>
        ///<param name="sender">The callback object</param>
        ///<param name="args">A CallBackEventArgs instance.</param>
        OnCallBackError : function(sender, args) { Alert.Show(args.Error.Message); },
        
        ///<summary>Fires when the callback response issues a redirect command. If you override this method, you must return true if you want the callback to do the redirect for you. Otherwise, if you 
        ///handle the redirect yourself, return false to prevent the callback from redirecting.</summary>
        ///<param name="sender">The callback object</param>
        ///<param name="args">A CallBackEventArgs instance.</param>
        ///<returns>True to allow the callback to redirect the page, otherwise return false to halt the redirect (you can always manually redirect using the args.redirecturl property).</returns>
        OnBeforeCallBackRedirect : function(sender, args) { return true; }
    }
);

Reflective.Web.UI.AjaxCallBackParamArgs = function(key, value)
{
	this.key = key;
	this.value = value;
}

var windowZIndex = 1000;

Reflective.Web.UI.Window = function(sClientId, sServerId, sRootElementId)
{
    if (!sClientId) return;
    
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, sRootElementId);
    this._buttons = new Reflective.Web.Hashtable();
    
    //this._settings = settings ? settings : {};
    this._btnClickFn = null;
    this._isModal = false;
    this._appended = false;
}

Core.setInheritance(Reflective.Web.UI.Window, Reflective.Web.UI.ReflectiveControl);

Core.extend(Reflective.Web.UI.Window,
    {
		OnInit : function()
		{
			
		},
		IsRendered : function()
		{
			return this.$el().length > 0;
		},
		IsModal : function(value)
		{
			if (value == null)
			{
				if (!this.IsRendered())
					return this._isModal;
				else
					return this._attr("isModal");
			}
			else
			{
				if (!this.IsRendered())
					this._isModal = value;
				else
					this._attr("isModal", value ? "1" : "");
			}
		},
        OnShow : function(fadeIn, delay)
        {
			if (this.IsModal())
				this._showModal();
			else
				this._show();
				
            return true;
        },
        _show : function(zIndex)
        {
			var myZIndex = zIndex;
            if (zIndex == null)
            {
                windowZIndex++;
                myZIndex = windowZIndex;
            }
            
			if (!this.IsRendered())
            {
			    $(document.body).append(this._html());
            }
            else if (!this._appended)
				$(document.body).append(this.$el());
            
            this._appended = true;
            
            this.$el().Draggable(
                {
                zIndex : myZIndex,
                handle : "#" + this.id + "_title",
                ghosting : false,
                opacity : 0.7
                }
            );
            this.$el().fadeIn();
            var x = (($(window).innerWidth() - this.$el().outerWidth()) / 2)  + $(document.body).scrollLeft();
            var y = (($(window).innerHeight() - this.$el().outerHeight()) / 2)  + $(document.body).scrollTop();
            
            this.$el().css( { zIndex : myZIndex, top : y, left : x } );
          
			this.OnAfterShow();
            return myZIndex;
        },
        OnAfterShow : function()
        {
        },
        _showModal : function()
        {
            this._show(window.ShowModal() + 1);
        },
        _getBody : function()
        {
            return this.OnGetBody();
        },
        OnGetBody : function() { return "no body"; },
        _html : function()
        {
            var html = "<span class=\"Window\" id=\"" + this.id + "_element\" style=\"position:absolute;display:none;\">"
                + "<div style=\"width:100%;\" id=\"" + this.id + "_title\" class=\"WindowTitle\">" + this.Title() + "</div>"
                + "<div id=\"" + this.id + "_body\" class=\"WindowBody\">"
                + this._getBody()
                + "</div>"
                + "<div class=\"WindowButtonRow\">";
                
                var id = this.id;
                var t = this;
                this._buttons.foreach(
                    function(btn)
                    {
                        html += "<button onclick=\"" + btn.onClickScript(t) + "\" id=\"" + id + "_" + btn.id + "\" class=\"WindowButton\">" + btn.text + "</button>"
                    }
                );
                    
                html += "</div></span>";
            
            return html;
        },
        Title : function(title)
        {
            if (title == null)
            {
				if (this.IsRendered())
					return this._titleElement().html;
				else
					return this._title;
            }
            else
            {
                this._title = title;
                if (this.IsRendered())
                    this._titleElement().html(title);
            }
        },
        _titleElement : function() { return $("#" + this.id + "_title"); },
        _btnClick : function(dialogResult)
        {
            if (dialogResult != Reflective.Web.UI.DialogResult.Cancel)
            {
                if (this._btnClickFn != null)
                {
                    this._btnClickFn(dialogResult);
                }
            }
            this.Close();
        },
        OnButtonClick : function(fnToCall)
        {
            this._btnClickFn = fnToCall;
        },
        Close : function() 
        { 
			var args = new Reflective.Web.CancelEventArgs();
			this.OnClosing(args);
			
			if (!args.Cancel)
				this.OnClose();
		},
		OnClosing : function(args)
		{
			this.FireEvent("onclosing", args);
		},
		OnClose : function(args)
		{
			this.Hide(); 
			window.HideModal(); 
			this.FireEvent("onclosed");
		},
        AddButton : function(id, text, result)
        {
            this._buttons.set(id, new Reflective.Web.UI.DialogButton(id, text, result));
        },
        ContainsButton : function(id) { return this._buttons.containskey(id); }
    }
);

Reflective.Web.UI.IFrameWindow = function(sClientId, sServerId, sRootElementId)
{
	this.Inherits(Reflective.Web.UI.Window, sClientId, sServerId, sRootElementId);
}
Core.setInheritance(Reflective.Web.UI.IFrameWindow, Reflective.Web.UI.Window);

Core.extend(Reflective.Web.UI.IFrameWindow,
    {
        OnGetBody : function()
        {
           return "<iframe src=\"" + this._contentUrl + "\" id=\"" + this.id + "_iframe\" frameborder=\"0\" border=\"0\" width=\"100%\"></iframe>";
        },
        _iframe : function() { return $("#" + this.id + "_iframe"); },
        OnAfterShow : function()
        {},
        ContentUrl : function(url)
        {
			if (url == null)
			{
				if (this.IsRendered())
					return this._attr("ContentUrl");
				else
					return this._contentUrl;
			}
			else
				this._contentUrl = url;
        },
        OnShow : function()
        {
			this.CallBase(Reflective.Web.UI.Window, "OnShow");
			var iframe = $g(this.id + "_iframe");
			
			//check if the page is a Reflective.Web.UI.Page, if so, tell it that a window contains it.
			if (iframe.Page)
			{
				iframe.Page.SetWindow(this);
			}
			
        }
    }
);

var IFrameWindow = 
{
	Show : function(id, title, contentUrl)
	{
		var w = new Reflective.Web.UI.IFrameWindow(id, id, id + "_element");
		w.Title(title);
		w.ContentUrl(contentUrl);
		w._show();
		return w;
	}
}

var DomHelper = new Object();

DomHelper.IsIE = (window.attachEvent);
DomHelper.BoundEventStrings = new Array();
DomHelper.elementIdIndex = 0;

DomHelper.GetUniqueElementId = function()
{
    return "domHelper_id_" + this.elementIdIndex;
    
    this.elementIdIndex++;    
}

DomHelper.GetEventWrapper = function(evt)
{
    return new this.Event(evt);
}
DomHelper.AttachEvent = function(element, eventname, fn)
{
    if (typeof(fn) == "string")
        fn = eval(fn);
        
    if (this.IsIE)
        element.attachEvent(eventname, fn);
    else
    {
        element.addEventListener(eventname.substring(2), fn, false);
    }
}

DomHelper.DetachEvent = function(element, eventname, fn)
{
    if (this.IsIE)
    {
        try
        {
            element.detachEvent(eventname, typeof(fn) == "string" ? eval(fn) : fn);
        }
        catch (e) {}
    }
}

DomHelper.CancelEvent = function(evt)
{
    var e = evt || event;
    if (this.IsIE)
        e.returnValue = false;
    else
    {
        e.cancelled = true;
        e.preventDefault();
    }
}

DomHelper.CancelBubble = function(evt)
{
	if (evt)
	{
		var e = evt || event;
		e = e._event || e;
	    
		if (this.IsIE)
			e.cancelBubble = true;
		else
			e.stopPropagation();
	}
}

DomHelper.EventCancelled = function(evt)
{
	if (evt)
	{
		var e = evt || event;
		e = e._event || e;
	    
		if (this.IsIE)
			return e.returnValue;
		else
			return e.cancelled;
    }
}
DomHelper.EventSource = function(evt)
{
    var e = evt || event;
    if (this.IsIE)
        return e.srcElement;
    else
        return e.target;
}

DomHelper.eventKeyCode = function(ev)
{
    return ev.which || ev.keyCode;
}
DomHelper.IsElement = function(obj)
{
    try
    {
        var s = obj.tagName;
        alert(s);
        return true;
    }
    catch (e)
    {
        return false;
    }
}
//<summary>Finds the element with the specified id in the document.</summary>
///<param name="sID">The id of the element.</param>
///<param name="parent">[Optional] A parent element to search inside.</param>
///<returns>The element or null if the element isn't found.</returns>
DomHelper.FindElement = function(sID, parent)
{
    var e = document.getElementById(sID);
    if (e == null && parent != null)
        return this._FindInternal(parent, sID);
    else
        return e;
}

//<summary>Internal recursive find method for domhelper.</summary>
///<param name="element">The element being searched.</param>
///<param name="sID">The id of the element to seek.</param>
///<returns>The element or null.</returns>
DomHelper._FindInternal = function(element, sID)
{
    
    if (element.id == sID)
        return element;
    else
    {
        if (element.tagName == "TABLE")
        {
            var cells = element.cells;
            if (this.EchoEnabled) alert("Table has " + cells.length + " cells.");
            for (var i = 0; i < cells.length; i++)
            {
                if (cells[i].id == sID)
                    return cells[i];
                    
                for (var x = 0; x < cells[i].children.length; x++)
                {
                    var c = this._FindInternal(cells[i].children[x], sID);
                    if (c != null)
                        return c;                        
                } 
            }
        }
        else
        {
            var children = element.children;
            for (var i = 0; i < children.length; i++)
            {
                var c = this._FindInternal(children[i], sID);
                if (c != null)
                    return c;
            }
        }
    }
    return null;
}


DomHelper.Event = function(evt)
{
    this._event = evt;
    this.type = evt.type.toLowerCase();
    if (DomHelper.IsIE)
        this.srcElement = evt.srcElement
    else
        this.srcElement = evt.target;   

}


DomHelper.Event.prototype.Cancel = function()
{
    if (DomHelper.IsIE)
        this._event.returnValue = false;
    else
        this._event.preventDefault();
}

DomHelper.Event.prototype.CancelBubble = function()
{
    if (DomHelper.IsIE)
        this._event.cancelBubble = true;
    else
        this._event.stopPropagation();
}

DomHelper._getEventBindingId = function(oObjectOrID)
{
	if (oObjectOrID == document.body)
	{
		return "document.body";
	}
    else if (typeof(oObjectOrID) == "object")
    {
        if (oObjectOrID.id)
            return oObjectOrID.id;
        else
        {
            var id = this.GetUniqueElementId();
            oObjectOrID.id = id;
            return id;
        }
    }
    else
        return oObjectOrID;
}

DomHelper.AttachEventString = function(oObjectOrID, sEventName, sFunctionString)
{
    
    var ev = sEventName.substr(2).toLowerCase();
    var id = this._getEventBindingId(oObjectOrID);
    
    console.log("creating string binding for event " + sEventName + " for object " + id);
    if (this.BoundEventStrings[ev] == null)
    {
        this.BoundEventStrings[ev] = new Array();
    }
    
    if (this.BoundEventStrings[ev][id] == null)
    {
        this.BoundEventStrings[ev][id] = new Array();
    }
    
    if (!this.BoundEventStrings[ev][id].contains(sFunctionString))
    {
        this.BoundEventStrings[ev][id].add(sFunctionString);
        if (id == "document.body")
        {
			this.AttachEvent(document.body, sEventName, HandleDocumentEventString);
        }
        else
        {
			this.AttachEvent(document.getElementById(id), sEventName, HandleBoundEventString);
        }
    }
    else
    {
        var o = document.getElementById(id);
        this.AttachEvent(o, sEventName, HandleBoundEventString);
    }
}

DomHelper.DetachEventString = function(oObjectOrID, sEventName, sFunctionString)
{
    var ev = sEventName.substr(2).toLowerCase();
    var id = this._getEventBindingId(oObjectOrID);
    if (this.BoundEventStrings[ev] != null)
    {
        if (this.BoundEventStrings[ev][id] != null)
        {
            if (this.BoundEventStrings[ev][id].contains(sFunctionString))
            {
                this.BoundEventStrings[ev][id].remove(sFunctionString);
                
                if (this.BoundEventStrings[ev][id].length == 0)
                {
                    this.BoundEventStrings[ev][id] = null;
                    var o = (id == "document.body") ? document.body : document.getElementById(id);
                    this.DetachEvent(o, sEventName, HandleBoundEventString);
                    
                }
            }
            
        }
    }
}

function HandleDocumentEventString(evt)
{
	var e = (evt) ? DomHelper.GetEventWrapper(evt):
		DomHelper.GetEventWrapper(event);
    
    if (DomHelper.BoundEventStrings[e.type] == null) return;
    
    var bindings = null;
    bindings = DomHelper.BoundEventStrings[e.type]["document.body"];
        
    if (bindings == null) return;
    var aEvents = bindings;
    for (var i = 0; i < aEvents.length; i++)
        try { eval(aEvents[i] + "(e)"); } catch (e) {}
}

function HandleBoundEventString(evt)
{
    var e;
    if (evt)
        e = DomHelper.GetEventWrapper(evt);
    else
        e = DomHelper.GetEventWrapper(event);
        
    if (DomHelper.BoundEventStrings[e.type] == null) return;
    var oSrc = e.srcElement == null ? window : e.srcElement;
    
    var sID = "";
    try
    {
        sID = oSrc.id;
    }
    catch (err) { sID = "document.body"; }
    
    var bindings = null;
    if (sID != "")
        bindings = DomHelper.BoundEventStrings[e.type][sID];
    
    if (bindings == null)
        bindings = DomHelper.BoundEventStrings[e.type][oSrc];
        
    if (bindings == null) return;
    var aEvents = bindings;
    for (var i = 0; i < aEvents.length; i++)
        try { eval(aEvents[i] + "(e)"); } catch (e) {}
        
}

function $g(id)
{
    return DomHelper.FindElement(id);
}


var Environment = new Object();

Environment.ApplicationRoot = "";
Environment.ScriptRoot = "";
Environment.Url = ""; //the full url (path + "?" + querystring)
Environment.UrlPath = ""; //the path portion of the url
Environment.QueryString = ""; //the querystring
Environment.IsSSL = false;

Environment.KeyCodes = new Object();

Environment.KeyCodes.UpArrow = 38;
Environment.KeyCodes.DownArrow = 40;
Environment.KeyCodes.LeftArrow = 37;
Environment.KeyCodes.RightArrow = 39;
Environment.KeyCodes.PageUp = 33;
Environment.KeyCodes.PageDown = 34;
Environment.KeyCodes.Home = 36;
Environment.KeyCodes.End = 35;
Environment.KeyCodes.Enter = 13;
Environment.KeyCodes.SpaceBar = 32;
Environment.KeyCodes.Tab = 9;
Environment.KeyCodes.Esc = 27;
Environment.KeyCodes.Shift = 16;
Environment.KeyCodes.Ctrl = 17;
Environment.KeyCodes.Alt = 18;
Environment.KeyCodes.CapsLock = 20;
Environment.KeyCodes.Backspace = 8;
Environment.KeyCodes.Delete = 46;
Environment.KeyCodes.Insert = 0x2D;
Environment.KeyCodes.Help = 0x2F;

Environment.KeyIsAlphaNumeric = function(keycode)
{
    return (keycode != Environment.KeyCodes.UpArrow &&
    keycode != Environment.KeyCodes.DownArrow  &&
    keycode != Environment.KeyCodes.LeftArrow  &&
    keycode != Environment.KeyCodes.RightArrow  &&
    keycode != Environment.KeyCodes.PageUp  &&
    keycode != Environment.KeyCodes.PageDown  &&
    keycode != Environment.KeyCodes.Home  &&
    keycode != Environment.KeyCodes.End  &&
    keycode != Environment.KeyCodes.Enter  &&
    keycode != Environment.KeyCodes.SpaceBar  &&
    keycode != Environment.KeyCodes.Tab  &&
    keycode != Environment.KeyCodes.Esc  &&
    keycode != Environment.KeyCodes.Shift  &&
    keycode != Environment.KeyCodes.Ctrl  &&
    keycode != Environment.KeyCodes.Alt  &&
    keycode != Environment.KeyCodes.CapsLock  &&
    keycode != Environment.KeyCodes.Backspace  &&
    keycode != Environment.KeyCodes.Delete &&
    keycode != Environment.KeyCodes.Insert &&
    keycode != Environment.KeyCodes.Help);
}



//function Url(startingUrl)
//{
//    this._url = null;
//    this._params = new Hashtable();
//    
//    this._initialize(startingUrl || Environment.Url);
//}

//Url.prototype._initialize = function(url)
//{
//    if (url.indexOf("?") == -1)
//    {
//        this._url = url;
//    }
//    else
//    {
//        this._url = url.substring(0, url.indexOf("?"));
//        
//        var query = url.substring(url.indexOf("?"));
//        if (query.length == 1)
//            return;
//            
//        query = query.substring(1);
//        
//        if (query.indexOf("&") == -1)
//        {
//            var parts = query.split("=");
//            this._params.add(parts[0], parts[1]);
//        }
//        else
//        {
//            var parts = query.split("&");
//            for (var i = 0; i < parts.length; i++)
//            {
//                var keyVal = parts[i].split("=");
//                this._params.set(keyVal[0], keyVal[1]);
//            }
//        }
//    }
//}

//Url.prototype.SetParam = function(key, value)
//{
//    this._params.set(key, value);
//}

//Url.prototype.ToString = function()
//{
//    var query = this._params.Join("&", "=");
//    return this._url + "?" + query;
//}

Reflective.Web.HttpRequest = function(id, targetUrl)
{
    this.Inherits(Reflective.Web.ReflectiveObject, id);
    this.TargetUrl = targetUrl;
    this.XmlHttp = null;
    this.Params = new Reflective.Web.Hashtable();
    this.StaticParams = new Reflective.Web.Hashtable();
    
    //add the callback trigger key
    this.SetStaticParam("_cb_", "1");
}

Core.setInheritance(Reflective.Web.HttpRequest, 
    Reflective.Web.ReflectiveObject);
    
Core.extend(
    Reflective.Web.HttpRequest,
    {
        ///<summary>Clears the current parameter list.</summary>
        ClearParams : function() { this.Params.clear(); },
        
        ///<summary>Used internally to create an instance of the XmlHttp object.</summary>
        ///<returns>An xmlhttp object instance.</returns>
        GetHttpObject : function()
        { 

            if (this.XmlHttp != null) return this.XmlHttp;
            
            if (window.XMLHttpRequest)
            {
                this.XmlHttp = new XMLHttpRequest();
                trace.writeMed("XmlHTTP object created.");
            }
            else if (window.ActiveXObject)
            {
                try
                {
                    this.XmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
                }
                catch (e)
                {
                    trace.writeLow("Error creating XmlHTTP object: " + e.description);
                    try
                    {
                        this.XmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                    }
                    catch (e2)
                    {
                        trace.writeLow("Error creating XmlHTTP object: " + e2.description);
                    }
                    
                }
            }
            else
            {
                trace.writeLow("XMLHttp unsupported.");
            }
            return this.XmlHttp;
        },
        
        //<summary>Sets the given parameter to the value specified. If the parameter doesn't exist, it is added.</summary>
        ///<param name="sKey">The key</param>
        ///<param name="sValue">The value</param>
        SetParam : function(sKey, sValue)
        {
            this.Params.set(sKey, sValue);
        },
        
        GetParam : function(sKey)
        {
            return this.Params.get(sKey);
        },
        ///<summary>Adds a parameter that will be sent with all requests made by this callback object.</summary>
        ///<param name="sKey">The key</param>
        ///<param name="sValue">The value</param>
        SetStaticParam : function(sKey, sValue)
        {
            this.StaticParams.set(sKey, sValue);
        },
        
        ///<summary>Fires off an asynchronous GET request.</summary>
        ///<param name="sTargetUrl">The URL to send the request to.</param>
        Get : function(sTargetUrl)
        {
            var x = this.GetHttpObject();
            if (x)
            {
                if (x.readyState == 4 || x.readyState == 0)
                {
                    var oThis = this;
                    if (sTargetUrl == null)
                        sTargetUrl = this.TargetUrl;
                        
                    x.open('GET', sTargetUrl + "?" + this.GetParamString(), true);
                    x.onreadystatechange = function()
                    {
                        oThis.ReadyStateChange();
                    }
                    x.send(null);
                }
            }
        },
        
        ///<summary>Fires off a synchronous GET request.</summary>
        ///<param name="sTargetUrl">The URL to send the request to.</param>
        SyncGet : function(sTargetUrl)
        {
            var x = this.GetHttpObject();
            if (x)
            {
                if (x.readyState == 4 || x.readyState == 0)
                {
                    if (sTargetUrl == null)
                        sTargetUrl = this.TargetUrl;
                        
                    x.open('GET', sTargetUrl + "?" + this.GetParamString(), false);
                    x.send(null);
                    return new Reflective.Web.CallBackEventArgs(this, x);
                }
            }
            return new Reflective.Web.CallBackEventArgs(this, null);
        },
        
        ///<summary>Fires off an asynchronous POST request.</summary>
        ///<param name="sTargetUrl">The URL to send the request to.</param>
        Post : function(sTargetUrl)
        {
            trace.writeMed("HttpRequest.Post() entered.");
            var x = this.GetHttpObject();
            if (x)
            {
                if (x.readyState == 4 || x.readyState == 0)
                {
                    var oThis = this;
                    if (sTargetUrl == null)
                        sTargetUrl = this.TargetUrl;
                    
                    trace.writeMed("Will callback to: " + sTargetUrl);
                    x.open('POST', sTargetUrl, true);
                    x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                    x.onreadystatechange = function()
                    {
                        oThis.ReadyStateChange();
                    }
                    var params = this.GetParamString();
                    trace.writeHigh("params: " + params);
                    x.send(params);
                    trace.writeMed("post sent");
                }
            }
            trace.writeMed("HttpRequest.Post() exited.");
        },
        
        ///<summary>Fires off a synchronous POST request.</summary>
        ///<param name="sTargetUrl">The URL to send the request to.</param>
        ///<returns>A CallBackEventArgs instance with the response data.</returns>
        SyncPost : function(sTargetUrl)
        {
            var x = this.GetHttpObject();
            if (x)
            {
                if (x.readyState == 4 || x.readyState == 0)
                {
                    var oThis = this;
                    if (sTargetUrl == null)
                        sTargetUrl = this.TargetUrl;
                        
                    x.open('POST', sTargetUrl, false);
                    x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
                    x.send(this.GetParamString());
                    return new Reflective.Web.CallBackEventArgs(this, x);
                }
            }
        },
        
        ///<summary>Gets a string representing the currently set parameters.</summary>
        ///<returns>A parameter string such as "key=value&key2=value2&key3=value3"</returns>
        GetParamString : function()
        {
            trace.writeMed("HttpRequest.GetParamString() entered.");
            trace.writeMed("StaticParams: " + this.StaticParams.count());
            trace.writeMed("Params: " + this.Params.count());
            var p = "";
            p = this.Params.toQueryString();
            
            trace.writeHigh("p = " + p);
            if (p != "" && this.StaticParams.count() > 0) p += "&";
            
            p += this.StaticParams.toQueryString();
            
            if (p != "") p += "&";
            
            var d = new Date();
            p += this.id + "_time=" + d.getTime();
            
            trace.writeHigh("p = " + p);
            trace.writeMed("HttpRequest.GetParamString() exiting.");
            return p;
        },
     

        ///<summary>Aborts the currently pending http request.</summary>
        Abort : function()
        {
            if (this.XmlHttp)
            {
            
                try
                {
                    this.XmlHttp.abort();
                } catch (e) {}
            }
        },
         
        ///<summary>Internal event handler that checks the state of the xmlhttp object.</summary>
        ReadyStateChange : function()
        {
            if( this.XmlHttp.readyState == 1 )
            {
                this.FireEvent("onloading");
            }
            else if( this.XmlHttp.readyState == 2 )
            {
                this.FireEvent("onloaded");
            }
            else if( this.XmlHttp.readyState == 3 )
            {
                this.FireEvent("oninteractive");
            }
            else if( this.XmlHttp.readyState == 4 )
            {
				if( this.XmlHttp.status == 0 )
                {
                    this.FireEvent("onabort", this);
                }
                else if (this.XmlHttp.status == 200)
                {
                    var args = new Reflective.Web.CallBackEventArgs(this, this.XmlHttp);
                    if (args.Error) //if the callbackobject.SendError method was called on the server, the callback will complete but the result should be notified as if an error
                        this.FireEvent("onerror", args);   
                    else
                        this.FireEvent("oncomplete", args);
                }
                else
                {
                    this.FireEvent("onerror", new Reflective.Web.CallBackEventArgs(this, this.XmlHttp));
                }
            }
        }
    }
);

Reflective.Web.CallBackError = function(iNum, sMessage)
{
    this.Number = iNum;
    this.Message = sMessage;
}

Reflective.Web.CallBackResponseType = new Object();
Reflective.Web.CallBackResponseType.NotSet = "NotSet";
Reflective.Web.CallBackResponseType.Success = "Success";
Reflective.Web.CallBackResponseType.Warning = "Warning";
Reflective.Web.CallBackResponseType.Error = "Error";
Reflective.Web.CallBackResponseType.Redirect = "Redirect";

Reflective.Web.CallBackEventArgs = function(callback, request)
{
    this.callback = callback;
    this.request = request;
    this.responseType = Reflective.Web.CallBackResponseType.NotSet;
    this.responseText = request.responseText;
    this.responseXML  = request.responseXML;
    this.responseParams = new Reflective.Web.Hashtable();
    this.redirecturl = "";
    var contentType = request.getResponseHeader("Content-Type");
    this.contentType = contentType ? contentType.split(";")[0] : "";
    
    this.Error = false;
    if (this.request.status >= 400)
    {
        this.Error = new Reflective.Web.CallBackError(request.status, request.statusText);
    }
    else
    {
        if (this.contentType == "text/ajaxoperationresult")
        {
			var response = eval("(" + this.responseText + ")");
            this.responseText = response.Message;
            this.responseType = response.ResultType;
            this.redirecturl = response.RedirectUrl;
            this.responseParams = response.Params;
            
//            for (var i = 0; i < params.length; i++)
//            {
//				this.responseParams.add(params[i][0], params[i][1]);
//            }
//            
            if (this.responseType == Reflective.Web.CallBackResponseType.Error)
                this.Error = new Reflective.Web.CallBackError(0, this.responseText);
                
        }
        
    }
    
    this.GetParam = function(key)
    {
        return this.responseParams.get(key);
    }
}



Reflective.Web.Url = function(urlString)
{
	
	this.params = new Reflective.Web.Hashtable();
	this._protocol = urlString.Contains("://") ? urlString.substring(0, urlString.indexOf("://") + 3) : "";
	
	this._host = "";
	if (!String.IsNullOrEmpty(this.protocol))
	{
		var host = urlString.substring(this.protocol.length);
		if (host.Contains("/"))
			host = this.host.substring(0, host.indexOf("/"));
		
		this._host = host;
		
	}
	
	if (urlString.Contains("?"))
		this.query(urlString.substring(urlString.indexOf("?")));
		
	if (urlString.StartsWith("/"))
		this._virtualPath = urlString.Contains("?") ? urlString.substring(0, urlString.IndexOf("?")) : urlString;
	else if (!String.IsNullOrEmpty(this.host))
	{
		this._virtualPath = urlString.substring(urlString.indexOf(this.host + this.host.length));
		if (this._virtualPath.Contains("?"))
			this._virtualPath = this._virtualPath.substring(0, this._virtualPath.indexOf("?"));
	}	
	
	
	
	var query = urlString.Contains("?") ? urlString.substring(urlString.indexOf("?")) : "";
	this.queryString(query);
	
		
}

Core.extend(Reflective.Web.Url,
	{
		SetParam : function(key, value)
		{
			this.params.set(key, value);
		},
		host : function(value)
		{
			if (value)
			{
				this._host = value;	
			}
			else
			{
				return this._host;
			}
			
		},
		virtualPath : function(value)
		{
			if (value)
				this._virtualPath = value;
			else
				return this._virtualPath;
		},
		protocol : function(value)
		{
			if (value)
				this._protocol = value;
			else
				return this._protocol;
		},
		queryString : function(value)
		{
			if (value)
			{
				this.params.Clear();
				if (!String.IsNullOrEmpty(value))
				{
					var queryString = value.StartsWith("?") ? value.substring(1) : value;
					var parts;
					if (queryString.Contains("&"))
						parts = queryString.split("&");
					else
						parts = [ queryString ];
					
					var params = this.params;	
					parts.foreach(
						function(part)
						{
							var pair = part.split("=");
							params.add(pair[0], pair[1]);
						}
					);
				}
			}
			else
			{
				var ret = String.Empty;
				var params = this.params;
				params.foreachKey(
					function(key)
					{
						if (!String.IsNullOrEmpty(ret)) ret += "&";
						ret += key + "=" + params.get(key);
							
					}
				);
				
				return String.IsNullOrEmpty(ret) ? ret : "?" + ret;
			}
		},
		Value : function()
		{
			var url = String.Empty;
			if (this.protocol())
				url += this.protocol() + this.host();
			
			if (this.virtualPath())
				url += this.virtualPath();
				
			return url + this.queryString();
		}
		
	}
);
	

Reflective.Web._validator = function()
{
}

Core.extend(Reflective.Web._validator, 
	{
		IsValidEmail : function(value)
		{
			 var filter=/^.+@.+\..{2,3}$/;
			 return filter.test(value);
		}
	}
);

window["Validator"] = new Reflective.Web._validator();





Reflective.Web.UI.AjaxPanel = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.AjaxEnabledControl, sClientId, sServerId, rootElementId);
    
}

Core.setInheritance(Reflective.Web.UI.AjaxPanel, 
    Reflective.Web.UI.AjaxEnabledControl);
    
Core.extend(
    Reflective.Web.UI.AjaxPanel, 
    {
        
        
        Refresh : function()
        {
            this.FireServerEvent("refresh");
        },
        OnCallBackComplete : function(sender, args)
        {
            this.$el().html(args.responseText);
        },
        
        OnCallBackError : function(sender, args)
        {
            if (args.Error.Number >= 500)
                this.$el().html(args.responseText);
            else
                alert(args.Error.Message);
        }
        
    }
    
);





Reflective.Web.UI.DialogButton = function(id, text, dialogResult)
{
    this.id = id;
    this.text = text;
    this.resultCode = dialogResult;
}
Core.extend(Reflective.Web.UI.DialogButton,
    {
        onClickScript : function(windowObj)
        {
            return windowObj.id + "._btnClick(" + this.resultCode + ");";
        }
    }
);

//A text-based window is one that allows content to be specified as text/html.
Reflective.Web.UI.TextBasedWindow = function(id, title)
{
    this.Inherits(Reflective.Web.UI.Window, id, id, id + "_element");
    if (id)
		this.Title(title);
		
    this._text = "";
    this._iconUrl = "";
}
Core.setInheritance(Reflective.Web.UI.TextBasedWindow, Reflective.Web.UI.Window);

Core.extend(Reflective.Web.UI.TextBasedWindow,
    {
        OnGetBody : function()
        {
           var body = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>";
           if (this.IconUrl())
                body += "<td class=\"WindowIcon\" id=\"" + this.id + "_icon\" align=\"center\" valign=\"top\"><img id=\"" + this.id + "_icon_img\" src=\"" + this.IconUrl() + "\" /></td>";
                
            body += "<td valign=\"top\" class=\"WindowText\" id=\"" + this.id + "_text\" align=\"left\">" + this.Text() + "</td>"
                + "</tr></table>";
            return body;
        },
        Text : function(text)
        {
            if (text == null)
                return this._text;
            else
            {
                this._text = text;
                if (this._rendered)
                    this._textElement().text(text);
            }
        },
        _textElement : function() { return $("#" + this.id + "_text"); } ,
        IconUrl : function(url)
        {
            if (url == null)
            {
                if (this._iconUrl == "")
                    this._iconUrl = CurrentTheme ? CurrentTheme.GetImageUrl("icon.info.gif") : "";
                return this._iconUrl;
            }
            else
            {
                this._iconUrl = url;
                if (this._rendered)
                    this._iconElement().attr("src", url);
            }
        },
        _iconElement : function() { return $("#" + this.id + "_icon_img"); }
    }
);

Reflective.Web.UI.DialogResult = new Object();
Reflective.Web.UI.DialogResult.OK = 1;
Reflective.Web.UI.DialogResult.Cancel = 2;
Reflective.Web.UI.DialogResult.Yes = 3;
Reflective.Web.UI.DialogResult.No = 4;
Reflective.Web.UI.DialogResult.Abort = 5;
Reflective.Web.UI.DialogResult.Retry = 6;
Reflective.Web.UI.DialogResult.Continue = 7;

Reflective.Web.UI.Alert = function()
{
    this.Inherits(Reflective.Web.UI.TextBasedWindow, "Alert", "Alert", "Alert_element");
}
Core.setInheritance(Reflective.Web.UI.Alert, Reflective.Web.UI.TextBasedWindow);

Core.extend(Reflective.Web.UI.Alert,
    {
        Show : function(message, title)
        {
			this.Title(title);
            this.IconUrl(CurrentTheme.GetImageUrl("icon.error.gif"));
            this.Text(message);
            
            if (!this.ContainsButton("ok"))
                this.AddButton("ok", "OK", Reflective.Web.UI.DialogResult.OK);
            this._showModal(); 
        }
    }
);

var Alert = new Reflective.Web.UI.Alert();

Reflective.Web.UI.YesNoDialog = function()
{
    this.Inherits(Reflective.Web.UI.TextBasedWindow, "YesNoDialog", "YesNoDialog", "YesNoDialog_element");    
}
Core.setInheritance(Reflective.Web.UI.YesNoDialog, Reflective.Web.UI.TextBasedWindow);

Core.extend(Reflective.Web.UI.YesNoDialog,
    {
        Show : function(message, title)
        {
            this.IconUrl(CurrentTheme.GetImageUrl("icon.info.gif"));
            this.Text(message);
            this.Title(title || "Question");
            
            if (!this.ContainsButton("yes"))
            {
                this.AddButton("yes", "Yes", Reflective.Web.UI.DialogResult.Yes);
                this.AddButton("No", "No", Reflective.Web.UI.DialogResult.No);
            }
            this._showModal(); 
        }
    }
);

var YesNoDialog = new Reflective.Web.UI.YesNoDialog();

Reflective.Web.UI.ClientCodeBehind = function(clientId, typeName)
{
    this.Inherits(Reflective.Web.ReflectiveObject, clientId);
    this.TypeName = typeName;
}

Core.setInheritance(Reflective.Web.UI.ClientCodeBehind,
    Reflective.Web.ReflectiveObject);
    
Core.extend(
    Reflective.Web.UI.ClientCodeBehind, 
    {
        Init : function() { this.OnInit(); },
        
        OnInit : function() {},
        
        _mapE : function(id, clientId)
        {
            this[id] = this._element(clientId);
        },
        _element : function(clientId)
        {
            return $("#" + clientId);
        },
        _doCallBack : function(params /*params is a Hashtable */)
        {
            var rq = new Reflective.Web.HttpRequest(this.id + "_rq", Core.currentUrl);
            
            params.copyTo(rq.Params);
            
            rq.SetParam("_pgCallback", "pg");
            
            rq.BindEvent("oncomplete", this.id + ".CallBackComplete");
            rq.BindEvent("onabort", this.id + ".CallBackAbort");
            rq.BindEvent("onerror", this.id + ".CallBackError"); 
            rq.Post(); 
        },
        
        CallBackComplete : function(sender, args)
        {
            this.OnCallBackComplete(sender, args);
        },
        
        OnCallBackComplete : function(sender, args) {},
        CallBackAbort : function(sender, args)
        {
            this.OnCallBackAbort(sender, args);
        },
        
        OnCallBackAbort : function(sender, args) {},
        CallBackError : function(sender, args)
        {
            this.OnCallBackError(sender, args);
        },
        
        OnCallBackError : function(sender, args) {}
        
    }
    
);


Reflective.Web.UI.BaseContentBlock = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
    this._moduleId = "";
}

Core.setInheritance(Reflective.Web.UI.BaseContentBlock, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.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.ContentBlock = function(sClientId, sServerId)
{
    this.Inherits(Reflective.Web.UI.BaseContentBlock, sClientId, sServerId);
    this._moduleId = "";
}

Core.setInheritance(Reflective.Web.UI.ContentBlock, 
    Reflective.Web.UI.BaseContentBlock);
    
Core.extend(
    Reflective.Web.UI.ContentBlock, 
    {
        OnInit : function()
        {
        },
        ModuleInstance : function() { return window[this._moduleId]; }
    }
    
);



Reflective.Web.UI.GraphicsObj = function() 
{
    this.ContentAreaHeight = -1;
    var posEnum = new Object();
    posEnum.TopLeft      = 1;
    posEnum.TopCenter    = 2;
    posEnum.TopRight     = 3;
    posEnum.MiddleLeft   = 4;
    posEnum.MiddleCenter = 5;
    posEnum.MiddleRight  = 6;
    posEnum.BottomLeft   = 7;
    posEnum.BottomCenter = 8;
    posEnum.BottomRight  = 9;
    
    this.ElementPosition = posEnum;
}

Reflective.Web.UI.GraphicsObj.prototype = 
{
    
    GetClientRectangle : function(node)
    {
        return new this.Rectangle(this.GetElementLeft(node), 
            this.GetElementTop(node), 
            node.offsetWidth, node.offsetHeight);
    },
    
    GetHorizontalPadding : function(element)
    {
        if (element.clientWidth > 0)
            return element.offsetWidth - element.clientWidth;
        else
            return 0;
    },
    
    GetVerticalPadding : function(element)
    {
        if (element.clientHeight > 0)
            return element.offsetHeight - element.clientHeight;
        else
            return 0;
    },
    
    MouseIsOverNode : function(e, node)
    {
        var x = e.clientX;
        var y = e.clientY;
        
        var r = this.GetClientRectangle(node);
        
        if (x >= r.Left && x <= r.Right && y <= r.Bottom && y >= r.Top)
            return true;
            
        return false;
    },
    
    GetElementTop : function(element)
    {
        var val = 0;
        var p = element;
        if (element.style.position == "absolute")
            return element.offsetTop;
        else
        {
            while (p)
            {
                var i = p.offsetTop;
                if (i)
                    val += i;
                    
                p = p.parentElement;
            }
        }
        return val;
    },
    
    GetElementLeft : function(element)
    {
        var val = 0;
        var p = element;
        
        if (element.style.position == "absolute")
            return element.offsetLeft;
        else
        {
            while (p.tagName != "BODY")
            {
                var i = p.offsetLeft;
                if (i)
                    val += i;
                    
                p = p.parentElement;
            }
        }
        return val;
    },
    
    SumAncestorProperties : function(node, sProperty)
    {
        var val = 0;
        var p = node;
        
        while (p)
        {
            var i = p[sProperty];
            if (i)
                val += i;
                
            p = p.parentElement;
        }
        
        return val;
    },
    
    GetBoundaryRectangle : function(element)
    {
        return new this.Rectangle(element.scrollLeft, element.scrollTop, element.scrollWidth, element.scrollHeight);
    },
    
    ///<summary>Moves an element to keep it inside of a boundary area.</summary>
    ///<param name="boundaryElement">The element used as the boundary.</param>
    ///<param name="element">The element to move.</param>
    ///<param name="doNotOverlapElement">Another element which the positioning should not allow the element to overlap with.</param>
    ///<returns></returns>
    KeepInBoundary : function(boundaryElement, element, doNotOverlapElement)
    {
    	
	    //  left, top are window relative
	    var boundary = this.GetClientRectangle(boundaryElement);
	    var source   = this.GetClientRectangle(element);
	    
	    
	    var iScrollBar = 0;
	    if (boundaryElement == document.body || boundaryElement.style.overflow == "scroll" || boundaryElement.style.overflow == "auto")
	        iScrollBar = 20;
	        
	    if (boundary.top <= source.top && boundary.left <= source.left && boundary.bottom >= source.bottom && boundary.right >= source.right)
	        return; //do nothing, the element is already inside the boundary....
	    
	    if (boundary.width < source.width)
	        element.style.width = boundary.width;
	    
	    if (boundary.height < source.height)
	        element.style.height = source.height;
	        
	    if (source.left < boundary.left)
	        element.style.left = ((boundary.left + document.body.scrollLeft) - iScrollBar) + this.GetHorizontalPadding(boundaryElement);
	        
	    if (source.right > boundary.right)
	        element.style.left = (source.left - (source.right - boundary.right) - document.body.scrollLeft - iScrollBar) - this.GetHorizontalPadding(boundaryElement);
	    
	    if (source.top < boundary.top)
	        element.style.top = boundary.top + document.body.scrollTop + this.GetVerticalPadding(boundaryElement);
	        
	    if (source.bottom > boundary.bottom)
	        element.style.top = (source.top - (source.bottom - boundary.bottom) + document.body.scrollTop) - this.GetVerticalPadding(boundaryElement);
	        
    },
    
    GetPositionLeft : function(parent, child, position)
    {
        if (position == this.ElementPosition.TopLeft ||
            position == this.ElementPosition.MiddleLeft ||
            position == this.ElementPosition.BottomLeft)
            return 0;
        else if (position == this.ElementPosition.TopCenter ||
            position == this.ElementPosition.MiddleCenter ||
            position == this.ElementPosition.BottomCenter)
            return (parent.clientWidth / 2) - (child.offsetWidth / 2);
        else if (position == this.ElementPosition.TopRight ||
            position == this.ElementPosition.MiddleRight ||
            position == this.ElementPosition.BottomRight)
            return parent.clientWidth - child.offsetWidth;  
    },
    
    GetPositionTop : function(parent, child, position)
    {
        if (position == this.ElementPosition.TopLeft ||
            position == this.ElementPosition.TopCenter ||
            position == this.ElementPosition.TopRight)
            return 0;
        else if (position == this.ElementPosition.MiddleLeft ||
            position == this.ElementPosition.MiddleCenter ||
            position == this.ElementPosition.MiddleRight)
            return (parent.clientHeight / 2);// - (child.offsetHeight / 2);
        else if (position == this.ElementPosition.BottomLeft ||
            position == this.ElementPosition.BottomCenter ||
            position == this.ElementPosition.BottomRight)
            return parent.clientHeight - child.offsetHeight;
    },
    
    GetChildElementPosition : function(parent, child, position)
    {
        return new this.Point(this.GetPositionLeft(parent, child, position), 
            this.GetPositionTop(parent, child, position));
    },
    
    PositionElement : function(child, parent, position)
    {
        var p = this.GetChildElementPosition(parent, child, position);
        child.style.top = p.y;
        child.style.left = p.x;
    },
    
    Point : function(iX, iY)
    {
        this.x = iX;
        this.y = iY;
    },
    
    Rectangle : function(iLeft, iTop, iWidth, iHeight)
    {
        this.left = iLeft;
        this.top  = iTop;
        this.width = iWidth;
        this.height = iHeight;
        
        this.right = iLeft + iWidth;
        this.bottom = iTop + iHeight;
        
        this.ToString = function() { return "left: " + this.left + "\r\ntop: " + this.top + "\r\nwidth: " + this.width + "\r\nheight: " + this.height
            + "\r\nright: " + this.right + "\r\nbottom: " + this.bottom; }
    },


    Size : function(w, h)
    {
        this.width = w;
        this.height = h;
    }
}

//make a singleton...
//var Reflective.Web.UI.Graphics = new Reflective.Web.UI.GraphicsObject();
Reflective.Web.UI.HyperLink = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
    this._moduleId = "";
}

Core.setInheritance(Reflective.Web.UI.HyperLink, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.HyperLink, 
    {
		OnInit : function()
		{
		}
    }
);

///<summary>Provides an interface for script objects to support callbacks. Handles all the callback logic internally.</summary>
Reflective.Web.UI.ISupportsCallBack = function()
{
    
    
}

var RequestMethod = new Object();
RequestMethod.Get = "GET";
RequestMethod.Post = "POST";




Reflective.Web.UI.MasterPage = function(id, strTypeName)
{
    this.Inherits(Reflective.Web.UI.ClientCodeBehind, id, strTypeName);
}

Core.setInheritance(Reflective.Web.UI.MasterPage,
    Reflective.Web.UI.ClientCodeBehind);
    
Core.extend(
    Reflective.Web.UI.MasterPage, 
    {
        OnInit : function() {}        
    }
    
);


Reflective.Web.UI.Menu = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
    this._parentItem = null;
    this.currentItem = null;
    this.selectedItemId = null;
    
    this._hideTimeoutId = 0;
    this._hiding = false;
    this._subMenuTimeoutId = 0;
    this._rootMenu = null;
    
    this._itemList = new Array();
}

Core.setInheritance(Reflective.Web.UI.Menu, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.Menu, 
    {
        OnInit : function()
        {
            window.Page.BindEvent("onmouseover", this.id + "._documentMouseOver");
            
            var items = this.$el().find("[MenuID = '" + this.id + "']");
            for (var i = 0; i < items.length; i++)
            {
				this._addItemPointer(window[$(items[i]).attr("ClientId")]);
            }
        },
        _documentMouseOver : function(e)
        {
            if (this._parentItem && this.Visible()
                && !this._hiding)
            {
                this._startHide();
            }
        },
        
        _setParentItem : function(item)
        {
            this._parentItem = item;
        },
        
        HideCurrentSubMenu : function()
        {
            if (this.currentItem)
                this.currentItem.HideSubMenu();
        },
        
        OnMouseOver : function(evt)
        {
            DomHelper.CancelBubble(evt);
            if (this._hideTimeoutId)
                this._cancelHide();
        },
        
        OnMouseOut : function()
        {
            if (this._parentItem)
                this._startHide();
        },
        
        
        _startHide : function() 
        { 
			if (this._parentItem)
				this._hideTimeoutId = window.setTimeout(this.id + ".Hide();", 1000); 
			else
				this._hideTimeoutId = window.setTimeout(this.id + ".HideCurrentSubMenu()", 1000);
		},
        
        _cancelHide : function() 
        { window.clearTimeout(this._hideTimeoutId); },
        
        _notifyItemClick : function(itemId, evt)
        {
			console.log("Menu item clicked: " + itemId);
			var args = new Reflective.Web.UI.MenuItemClickEventArgs(evt, window[itemId]);
            this.OnItemClicked(args);
        },
        OnItemClicked : function(args)
        {
			this.FireEvent("itemclicked", args);
        },
        RootMenu : function()
        {
            if (!this._rootMenu)
            {
                if (!this._parentItem)
                    this._rootMenu = this;
                else
                {
                    var m = this._parentItem.Menu();
                    
                    while (m)
                    {
                        if (!m._parentItem)
                            break;
                         
                        m = m._parentItem.Menu();
                    }
                    
                    this._rootMenu = m;
                }
            }
            
            return this._rootMenu;
        },
        
        _addItemPointer : function(item)
        {
			console.log("Menu " + this.id + " added pointer to item '" + item.id + "'.");
            this._itemList.add(item);
        },
        
        GetItems : function()
        {
            return this._itemList;
        },
        GetItem : function(id)
        {
			var foundItem = null;
            this._itemList.foreach(
            
                function(item)
                {
					console.log(item.ServerId + " :: " + id);
                    if (item.ServerId == id)
                    {
						foundItem = item;
						return false;
                    }
                }
            );
            return foundItem;
        },
        SelectItem : function(itemId)
        {
            if (this.currentItemId)
                this.GetItem(currentItemId).SetSelected(false);
                
            this.GetItem(itemId).SetSelected(true);
        }
        
    }
    
);

Reflective.Web.UI.MenuItem = function(sClientId, sServerId, sRootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, sRootElementId);
    
    this._menu = false;
    this._submenu = false;
}

Core.setInheritance(Reflective.Web.UI.MenuItem, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.MenuItem, 
    {
        OnInit : function()
        {
            //this.Menu()._addItemPointer(this);
        },
        SubMenu : function()
        {
            if (this._submenu == false)
            {
                var subMenuId = this._attr("SubMenuID");
                if (typeof(subMenuId) != "undefined" && subMenuId)
                {
                    this._submenu = window[subMenuId];
                    this._submenu._setParentItem(this);
                }
            }
            
            return this._submenu;
        },
        
        Menu : function()
        {
            return window[this._attr("MenuID")];
        },
        
        OnClick : function(evt)
        {
            this.Menu().RootMenu()._notifyItemClick(this.id, evt);
            return true;
        },
        
        OnMouseOver : function(evt) 
        { 
			if (this.SubMenu() && this.SubMenu().Visible())
                this.SubMenu()._cancelHide();
            else
            {
                if (this.Menu().currentItem && this.Menu().currentItem.ClientId != this.ClientId)
                {
                    this.Menu().HideCurrentSubMenu();
                }
                
                this.ShowSubMenu();
            }
            return true;
        },
        
        OnMouseOut : function(evt) 
        { 
            DomHelper.CancelBubble(evt);
            return true;
        },
        
        ShowSubMenu : function()
        {
            if (this.SubMenu() && !this.SubMenu().Visible())
            {
                
                this.Menu().currentItem = this;
                
                var offset = this.$el().offset();
                offset.top += this.$el().outerHeight();
                
                $(document.body).append(this.SubMenu().$el());
                this.SubMenu().$el().css(offset);
                this.SubMenu().Show();
            }
        },
        
        HideSubMenu : function()
        {
            if (this.SubMenu())
            {
                if (this.SubMenu().Visible()  && !this._suppressHideSubMenu)
                    this.SubMenu().Hide();
            }
        },
        
        OnEnable : function()
        {
            this._("enabledDiv").show();
            this._("disabledDiv").hide();
            return true;
        },
        
        OnDisable : function()
        {
            this._("enabledDiv").hide();
            this._("disabledDiv").show();            
            return true;
        },
        
        SetSelected : function(selected)
        {
            this.SetClass( selected ? this.Menu()._attr("ItemCssClassSelected")
                : this.Menu()._attr("ItemCssClass"));
        }
    }
    
);


Reflective.Web.UI.MenuItemClickEventArgs = function(evt, item)
{
    this.Inherits(Reflective.Web.EventArgs, evt);
    this.itemId = item.id;
    this.item = item;
    console.log("MenuClickEventArgs: " + this.itemId);
}

Core.setInheritance(Reflective.Web.UI.MenuItemClickEventArgs,
    Reflective.Web.EventArgs);
Reflective.Web.UI.NotificationPanel = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
    this._baseClass = "";
}

Core.setInheritance(Reflective.Web.UI.NotificationPanel, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.NotificationPanel, 
    {
        OnInit : function()
        {
            this._baseClass = this.GetClass();
        },
        _textDiv : function() { return this._("textDiv"); },
        _iconDiv : function() { return this._("iconDiv"); },
        _buttonDiv : function() { return this._("buttonDiv"); },
        SetText : function(text) { if (this._textDiv()) this._textDiv().html(text); },
        GetText : function() { return this._textDiv() ? this._textDiv().html() : ""; },
        _show : function(notificationType, text, hideDelay)
        {
            var className = "";
            if (notificationType == Reflective.Web.UI.NotificationType.Error)
                className = "Error";
            else if (notificationType == Reflective.Web.UI.NotificationType.Info)
                className = "Info";
            else if (notificationType == Reflective.Web.UI.NotificationType.Warning)
                className = "Warning";
            else if (notificationType == Reflective.Web.UI.NotificationType.Success)
                className = "Success";
                
            this.SetClass(this._baseClass + className);
            this._iconDiv().attr("class", this._baseClass + className + "Icon");
            this.SetText(text);
            
			this.Show(true, 400);
			if (hideDelay != null)
				window.setTimeout(this.id + ".Hide(true);", hideDelay + 400);
                
        },
        ShowInfo : function(text, hideDelay) 
        { 
			this._show(Reflective.Web.UI.NotificationType.Info, text, hideDelay); 
		},
        ShowError : function(text, hideDelay) 
        { 
			this._show(Reflective.Web.UI.NotificationType.Error, text, hideDelay); 
		},
        ShowWarning : function(text, hideDelay) 
        { 
			this._show(Reflective.Web.UI.NotificationType.Warning, text, hideDelay); 
		},
        ShowSuccess : function(text, hideDelay) 
        { 
			this._show(Reflective.Web.UI.NotificationType.Success, text, hideDelay); 
		}
     }
);

Reflective.Web.UI.NotificationType = new Object();
Reflective.Web.UI.NotificationType.Error = 1;
Reflective.Web.UI.NotificationType.Info = 2;
Reflective.Web.UI.NotificationType.Warning = 3;
Reflective.Web.UI.NotificationType.Success = 4;




Reflective.Web.UI.Page = function(id, strTypeName) 
{
    this.Inherits(Reflective.Web.UI.ClientCodeBehind, id, strTypeName);
    window.Page = id == null ? null : this;
    
    if (id != null)
    {
		console.log("Binding page document.body events for: " + this.id);
		DomHelper.AttachEventString(document.body, "onmousemove", this.id + ".MouseMove");
		DomHelper.AttachEventString(document.body, "onmouseover", this.id + ".MouseOver");
		DomHelper.AttachEventString(document.body, "onclick", this.id + ".Click");
    }
}

Core.setInheritance(Reflective.Web.UI.Page,
    Reflective.Web.UI.ClientCodeBehind);

Core.extend(Reflective.Web.UI.Page,
    {
    	OnInit : function() 
    	{ 
    		
    	},
    	TryNavigate : function(targetUrl, targetFrame) 
    	{
    		var args = new Reflective.Web.UI.PageNavigateArgs(targetUrl, targetFrame);
    		if (!this.OnBeforeNavigate(args)) //returns false if nothing is listening for this event
    			this.NavigateTo(targetUrl, targetFrame);
    		
    		//if something traps the event, don't navigate -- allow the evnet handler to do it.
    	},
    	NavigateTo : function(url, targetFrame)
    	{
    		if (targetFrame)
    		{
    			window.open(url, targetFrame);
    		}
    		else
    		{
    			window.location.href = url;
    		}
    	},
    	OnBeforeNavigate : function(pageNavigateArgs)
    	{
    		return this.FireEvent("onbeforenavigate", pageNavigateArgs);
    	},
    	MouseMove : function(evt)
    	{
    		this.OnMouseMove();
    	},
    	OnMouseMove : function(evt)
    	{
    		this.FireEvent("onmousemove", evt);
    	},
    	MouseOver : function(evt)
    	{
    		this.OnMouseOver(evt);
    	},
    	OnMouseOver : function(evt)
    	{
    		this.FireEvent("onmouseover", evt);
    	},
    	Click : function(evt)
    	{
    		this.OnClick(evt);
    	},
    	OnClick : function(evt)
    	{
    		this.FireEvent("onclick", evt);
    	},
    	ShowSuccess : function(text, hideDelay)
    	{
    		if (typeof(window.NotifyPanel) != "undefined")
    		{
    			window.NotifyPanel.ShowSuccess(text, hideDelay);
    		}
    	},
    	ShowError : function(text, hideDelay)
    	{
    		if (typeof(window.NotifyPanel) != "undefined")
    		{
    			window.NotifyPanel.ShowError(text, hideDelay);
    		}
    	},
    	SetWindow : function(windowObj)
    	{
    		this._windowObj = windowObj;
    		alert("Page is in window: " + windowObj.id);
    	}
    }
);

Reflective.Web.UI.PageNavigateArgs = function(targetUrl, targetFrame)
{
	this.TargetUrl = targetUrl;
	this.TargetFrame = targetFrame;
}
Reflective.Web.UI.ProgressPanel = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
}

Core.setInheritance(Reflective.Web.UI.ProgressPanel, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.ProgressPanel, 
    {
        OnInit : function()
        {
            this._baseClass = this.GetClass();
        },
        Start : function(text)
        {
            this.Show();
            this.SetText(text || this._attr("defaultText"));
        },
        SetText : function(text)
        {
            this._("text").html(text);
        }
     }
);

Reflective.Web.UI.TaskList = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.AjaxEnabledControl, sClientId, sServerId, rootElementId);
    
    this._taskStates = null;
}

Core.setInheritance(Reflective.Web.UI.TaskList, 
    Reflective.Web.UI.AjaxEnabledControl);
    
Core.extend(
    Reflective.Web.UI.TaskList, 
    {
        OnInit : function()
        {
            this._refreshStates(eval(this._attr("taskState")));
        },
        Refresh : function() 
        { 
            this.FireServerEvent("refresh");
        },
        OnCallBackComplete : function(sender, args)
        {
            this._refreshStates(eval(args.responseText));
            
            this.FireEvent("onrefreshcomplete");
        },
        TaskEnabled : function(taskId)
        {
            return this._taskStates.containskey(taskId)
                && this._taskStates.get(taskId);
        },
        _refreshStates : function(stateArray)
        {
            var states = new Reflective.Web.Hashtable();
            
            stateArray.foreach(
                function (item)
                {
                    states.add(item.id, item.enabled);
                }
            );
            
            this._taskStates = states;
        }
    }
    
);


Reflective.Web.UI.TaskMenu = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.Menu, sClientId, sServerId, rootElementId);
    this._taskList = null;
}

Core.setInheritance(Reflective.Web.UI.TaskMenu, 
    Reflective.Web.UI.Menu);
    
Core.extend(
    Reflective.Web.UI.TaskMenu, 
    {
        OnInit : function()
        {
            this._taskList = window[this._attr("taskListId")];
            this._taskList.BindEvent("onrefreshcomplete", this.id, "TaskListRefreshed");
        },
        TaskListRefreshed : function(sender, args)
        {
            var items = this.GetItems();
            var taskList = this._taskList;
            items.foreach(
                function(item)
                {
                    item.SetEnabled(taskList.TaskEnabled(item.GetAttribute("taskId")));
                }
            );
        }
    }
);
Reflective.Web.UI.ExecutionTaskModule = function(id, taskId, serverLocation)
{
    this.Inherits(Reflective.Web.UI.ClientCodeBehind, id);
    this._request = null;
    this.TaskID = taskId;
    this._virtualPath = serverLocation;
    
    this._params = new Reflective.Web.Hashtable();
}

Core.setInheritance(Reflective.Web.UI.ExecutionTaskModule,
    Reflective.Web.UI.ClientCodeBehind);
    
Core.extend(
    Reflective.Web.UI.ExecutionTaskModule, 
    {
        SetParam : function(key, value) { this._params.set(key, value); },
        ClearParams : function() { this._params.clear(); },
        Execute : function() { this.OnExecute(); },
        OnExecute : function() {},
        ServerExecute : function()
        {
            if (!this._request)
            {
                var urlStart = Environment.ApplicationRoot;
                if (Environment.ApplicationRoot != "/")
                    urlStart = Environment.ApplicationRoot + "/";
                    
                this._request = new Reflective.Web.UI.HttpRequest(this.id + "_rq", urlStart + "Reflective.Web/TaskHandler.aspx");
                this._request.AddStaticParam("taskPath", this._virtualPath);
                
                this._request.BindEvent("oncomplete", this.id, "ServerExecuteComplete");
                this._request.BindEvent("onerror", this.id, "ServerExecuteError");
            }
            this._request.ClearParams();
            
            if (!this.OnBeforeServerExecute())
                return;
            
            this._params.copyTo(this._request.Params);
            this._request.Post();
        },
        OnBeforeServerExecute : function() { return true; },
        ServerExecuteComplete : function(sender, args) { OnServerExecuteComplete(sender, args); },
        ServerExecuteError : function(sender, args) { OnServerExecuteError(sender, args); },
        OnServerExecuteComplete : function(sender, args) { },
        OnServerExecuteError : function(sender, args) { }
        
        
        
    }
    
);

Reflective.Web.UI.Theme = function(name, root)
{
    this.Name = name;
    this.Root = root;
}

Core.extend(
    Reflective.Web.UI.Theme, 
    {
        GetImageUrl : function(imageName) 
        { 
            return this.Root + "/images/" + imageName;
        }
    }
    
);

Reflective.Web.UI.TraceLevel = { None : 0, Error : 1, Low : 2, Med : 3, High : 4, All : 5 }

var traceLevel = Reflective.Web.UI.TraceLevel;

Reflective.Web.UI.TraceWindow = function(sClientId, sServerId, rootElementId)
{
    this.Inherits(Reflective.Web.UI.ReflectiveControl, sClientId, sServerId, rootElementId);
    this._enabled = false;
    this._currentLevel = traceLevel.None;
    window["trace"] = this;
    
    if (sClientId)
    {
        this._currentLevel = parseInt(this._attr("TraceLevelValue"));
        this.$el().html("<div id=\"" + this.ClientId + "lines\"></div><div id=\"" + this.ClientId + "scrollTo\"></div>");
        this.writeLow("Tracing initialized for page at url: " + Core.currentUrl);
    }
}

Core.setInheritance(Reflective.Web.UI.TraceWindow, 
    Reflective.Web.UI.ReflectiveControl);
    
Core.extend(
    Reflective.Web.UI.TraceWindow, 
    {
        write : function(line, level)
        {
            if (!this.ClientId) return;
            var l = level || traceLevel.Low;
            
            if (l <= this._currentLevel)
            {
                $("#" + this.ClientId + "lines").append("<div>" + line + "</div>");
                //this.$el().scrollTo("#" + this.ClientId + "scrollTo", { speed : 2500 });
            }
        },
        
        writeError : function(line)
        {
            this.write(line, traceLevel.Error);
        },
        
        writeLow : function(line)
        {
            this.write(line, traceLevel.Low);
        },
        
        writeMed : function(line)
        {
            this.write(line, traceLevel.Med);
        },
        
        writeHigh : function(line)
        {
            this.write(line, traceLevel.High);
        },
        
        writeHighest : function(line)
        {
            this.write(line, traceLevel.All);
        }
    }
    
);


var trace = new Reflective.Web.UI.TraceWindow();

Reflective.Web.UI.UserControl = function(id, strTypeName)
{
    this.Inherits(Reflective.Web.UI.ClientCodeBehind, id, strTypeName);
}

Core.setInheritance(Reflective.Web.UI.UserControl,
    Reflective.Web.UI.ClientCodeBehind);
    
Core.extend(
    Reflective.Web.UI.UserControl, 
    {
        OnInit : function() {}        
    }
    
);

