﻿document.CreateElementExt = function(elementType, attributes, styles, html)
{
	var result = this.createElement(elementType);
	if (attributes)
	{
		for(var key in attributes)
		{
			switch (key.toLowerCase())
			{
				case "class":
					result.className = attributes[key];
					break;
					
				case "id":
					result.id = attributes[key];
					break;
				
				case "checked":
					result.checked = attributes[key];
					break;
					
				default:
					result.setAttribute(key, attributes[key]);
					break;
			}
		}
	}
	if (styles)
	{
		for(var key in styles)
		{
			if (result.style.setProperty)
			{
				result.style.setProperty(key, styles[key], "");
			}
			else
			{
				result.style[key] = styles[key];
			}
		}
	}
	if (html)
	{
		result.innerHTML = html;
	}
	return result;
};

document.RetrieveEvent = function()
{
	if (document.all)
	{
		var e = window.event;
		e.preventDefault = function(){this.returnValue = false;this.cancelBubble = true;};
		e.target = e.srcElement;
		return e;
	}
	for (var fct = document.RetrieveEvent.caller, i = 0; fct && i < 10; fct = fct.caller, i++)
	{
		if ((fct.arguments.length > 0) && (fct.arguments[0] instanceof window.Event))
		{
			return fct.arguments[0];
		}
	}
	return null;
};

document.AddCssClass = function(element, cssClass)
{
	if (!element)
	{
		throw "Value cannot be null. Parameter name: element .";
	}
	if (!cssClass)
	{
		throw "Value cannot be null. Parameter name: cssClass .";
	}
	element.className += " " + cssClass;
	window.__NeedRefresh = true;
};

document.RemoveCssClass = function(element, cssClass)
{
	if (!element)
	{
		throw "Value cannot be null. Parameter name: element .";
	}
	if (!cssClass)
	{
		throw "Value cannot be null. Parameter name: cssClass .";
	}
	var removeExpression = new RegExp("(" + cssClass + ")", "g");
	var css              = element.className.replace(removeExpression, "");
	element.className    = css.Trim();
	window.__NeedRefresh = true;
};

document.Ie7FixCss = function(element)
{
	if (element.attachEvent)
	{
		element.onmousemove = document.Ie7FixCss.Fix;
	}
};

document.Ie7FixCss.Fix = function()
{
	if (window.__NeedRefresh)
	{
		this.className += "";
		window.__NeedRefresh = false;
	}
};

document.AddEventListener = function(element, eventName, delegate)
{
	var shortEventName = eventName.replace(/^on/, "");
	if (element.addEventListener)
	{
		element.addEventListener(shortEventName, delegate, false);
	}
	else
	{
		element.attachEvent(eventName, delegate)
	}
	EventCache.add(element, shortEventName, delegate, false);
};


document.RemoveEventListener = function(element, eventName, delegate)
{
	if (element.removeEventListener)
	{
		eventName = eventName.replace(/^on/, "");
		element.removeEventListener(eventName, delegate, false);
	}
	else
	{
		element.detachEvent(eventName, delegate)
	}
};

document.GetElementPosition = function(element) 
{
    var result = {Left:0, Top:0, Width:0, Height:0}
    if (element.offsetParent) 
    {
        result.Left = element.offsetLeft;
        result.Top  = element.offsetTop;
        var parent  = element.offsetParent;
        while (parent) 
        {
            result.Left += parent.offsetLeft;
            result.Top  += parent.offsetTop;
            var parentTagName = parent.tagName.toLowerCase();
            if ((parentTagName != "table") &&
                (parentTagName != "body" ) && 
                (parentTagName != "html" ) && 
                (parentTagName != "div"  ) && 
                parent.clientTop && 
                parent.clientLeft) 
            {
                result.Left += parent.clientLeft;
                result.Top  += parent.clientTop;
            }
            parent = parent.offsetParent;
        }
    }
    else if (element.left && element.top) 
    {
        result.Left = element.left;
        result.Top  = element.top;
    }
    else 
    {
        if (element.x) 
        {
            result.Left = element.x;
        }
        if (element.y) 
        {
            result.Top = element.y;
        }
    }
    if (element.offsetWidth && element.offsetHeight) 
    {
        result.Width  = element.offsetWidth;
        result.Height = element.offsetHeight;
    }
    else if (element.style && element.style.pixelWidth && element.style.pixelHeight) 
    {
        result.Width  = element.style.pixelWidth;
        result.Height = element.style.pixelHeight;
    }
    return result;
};

document.DisableSelection = function(element)
{
	if (document.all)
	{
		element.onselectstart = function(){return false;};
	}
	else
	{
		element.style.setProperty("-moz-user-select", "none", null);
	}
};

document.CancelBubble = function()
{
	document.RetrieveEvent().cancelBubble = true;
};

document.EnsureElementId = function(element)
{
	if (!element || element.id)
	{//Nothing to do.
		return;
	}
	var counter  = document.EnsureElementId.Counter;
	var template = document.EnsureElementId.Template;
	while (document.getElementById(template + counter))
	{
		counter++;
	}
	element.id = template + counter;
	document.EnsureElementId.Counter = counter + 1;
}
document.EnsureElementId.Counter  = 0;
document.EnsureElementId.Template = "AutoID";
document.Collapse = function (group, scroll, handler)
{
	if (group._AnimationId)
	{
		return;
	}
	document.EnsureElementId(group);
	document.EnsureElementId(scroll);

	if (handler)
	{
		group._AnimationHandler = handler;
	}
	group._AnimationId    = setTimeout(String.Format("document._AnimateCollapse(document.getElementById({0:json}), document.getElementById({1:json}))", group.id, scroll.id), 35);
};

document._AnimateCollapse = function (group, scroll)
{
	var height = parseInt(group.style.height.replace("px", ""));
	if (isNaN(height))
	{
		height = scroll.offsetHeight;
	}

	if (height > scroll.offsetHeight)
	{
		height = scroll.offsetHeight;
	}

	var step = Math.abs((scroll.offsetHeight - height) / 3);
	if (step < 2)
	{
		step = 2;
	}

	height -= step;

	scroll.style.top  = (height - scroll.offsetHeight) + "px";
	if (height > 0)
	{
		group.style.height = height + "px";
		group._AnimationId = setTimeout(String.Format("document._AnimateCollapse(document.getElementById({0:json}), document.getElementById({1:json}))", group.id, scroll.id), 35);
	}
	else
	{
		group._AnimationId  = null;
		group.style.height  = "";
		group.style.display = "none";
		var handler = group._AnimationHandler;
		if (handler)
		{
			group._AnimationHandler = null;
			handler();
		}
	}
};

document.Expand = function (group, scroll, handler)
{
	if (group._AnimationId)
	{
		return;
	}
	document.EnsureElementId(group);
	document.EnsureElementId(scroll);
	
	scroll.style.position = "absolute";
	group.style.height    = "0px";
	group.style.display   = "";
	if (handler)
	{
		group._AnimationHandler = handler;
	}
	group._AnimationId    = setTimeout(String.Format("document._AnimateExpand(document.getElementById({0:json}), document.getElementById({1:json}))", group.id, scroll.id), 35);
};

document._AnimateExpand = function(group, scroll)
{
	var height = parseInt(group.style.height.replace("px", ""));
	if (isNaN(height))
	{
		height = 0;
	}

	var step = Math.abs((scroll.offsetHeight - Math.abs(scroll.offsetHeight - height)) / 3);
	if (step < 2)
	{
		step = 2;
	}

	height += step;
	if (height > scroll.offsetHeight)
	{
		height = scroll.offsetHeight;
	}

	scroll.style.top   = (height - scroll.offsetHeight) + "px";
	group.style.height = height + "px";
	if (height < scroll.offsetHeight)
	{
		group._AnimationId    = setTimeout(String.Format("document._AnimateExpand(document.getElementById({0:json}), document.getElementById({1:json}))", group.id, scroll.id), 35);
	}
	else
	{
		group._AnimationId = null;
		var handler = group._AnimationHandler;
		if (handler)
		{
			group._AnimationHandler = null;
			handler();
		}
	}
};

/*	Event Cache uses an anonymous function to create a hidden scope chain.
	This is to prevent scoping issues. */
var EventCache = function(){
	var listEvents = [];
	
	return {
		listEvents : listEvents,
	
		add : function(node, sEventName, fHandler, bCapture){
			listEvents.push(arguments);
		},
	
		flush : function(){
			var i, item;
			for(i = listEvents.length - 1; i >= 0; i = i - 1){
				item = listEvents[i];
				
				if(item[0].removeEventListener){
					item[0].removeEventListener(item[1], item[2], item[3]);
				};
				
				/* From this point on we need the event names to be prefixed with 'on" */
				if(item[1].substring(0, 2) != "on"){
					item[1] = "on" + item[1];
				};
				
				if(item[0].detachEvent){
					item[0].detachEvent(item[1], item[2]);
				};
				
				item[0][item[1]] = null;
			};
		}
	};
}();

document.AddEventListener(window, "onunload", EventCache.flush);

if (!document.Events)
{
	document.Events = 
	{
		OnSubmit: new Delegate(new Function())
	};

	document.forms[0].submitEvents = document.forms[0].submit;
	document.forms[0].submit = function()
	{
		document.Events.OnSubmit();	
		this.submitEvents();
	};
}