﻿Type.registerNamespace("Telerik.Web.UI");

Telerik.Web.UI.EventMap = function ()
{
	this._owner = null;
	this._element = null;
	this._eventMap = {};
	this._onDomEventDelegate = null;
	this._browserHandlers = {};
}

Telerik.Web.UI.EventMap.prototype = 
{	
	initialize : function (owner, element)
	{
		this._owner = owner;
		if (!element)
			element = this._owner.get_element();
		this._element = element;
	},

	dispose : function ()
	{
		if (this._onDomEventDelegate)
		{
			for (var eventName in this._eventMap)
			{
				if (this._shouldUseEventCapture(eventName))
				{
					var browserHandler = this._browserHandlers[eventName];
					this._element.removeEventListener(eventName, browserHandler, true);
				}
				else
				{
					$removeHandler(this._element, eventName, this._onDomEventDelegate);
				}
			}
			
			this._onDomEventDelegate = null;
		}
	},
	
	// Public methods
	addHandlerForClassName : function (eventName, className, handler)
	{
		if (typeof(this._eventMap[eventName]) == "undefined")
		{
			this._eventMap[eventName] = {};
			
			if (this._shouldUseEventCapture(eventName))
			{
				var domEventHandler = this._getDomEventDelegate();
				var element = this._element;
				var browserHandler = function(e) { return domEventHandler.call(element, new Sys.UI.DomEvent(e)); }
				this._browserHandlers[eventName] = browserHandler;
				element.addEventListener(eventName, browserHandler, true);
			}
			else
			{
				$addHandler(this._element, eventName, this._getDomEventDelegate());
			}
		}
		
		var eventHandlers = this._eventMap[eventName];
		eventHandlers[className] = handler;
	},
	
	// Private methods
	_onDomEvent: function(e)
	{
		var dispatchees = this._eventMap[e.type];
		if (!dispatchees) 
			return;
		
		var target = e.target;
		while (target && target.nodeType !== 9) 
		{
			var className = target.className;
			var spaceIndex = className.indexOf(' ');
			
			if (spaceIndex >= 0) 
				className = className.substr(0, spaceIndex);
			
			var dispatchee = dispatchees[className];
			
			if (dispatchee) 
			{
				this._fillEventFields(e, target);
				if (dispatchee.call(this._owner, e) != true) 
				{
					if (!target.parentNode) 
					{
						// The target was removed from the DOM in the event handler.
						// Event propagation in this case causes "Unspecified error" in IE6.
						e.stopPropagation();
					}
					
					return;
				}
			}
			
			if (target == this._element) 
			{
				return;
			}
			
			target = target.parentNode;			
		}
	},
	
	_fillEventFields : function (e, currentTarget)
	{
		e.eventMapTarget = currentTarget;
		if (e.rawEvent.relatedTarget)
		{
			e.eventMapRelatedTarget = e.rawEvent.relatedTarget;
		}
		else
		{
			if (e.type == "mouseover")
			{
				e.eventMapRelatedTarget = e.rawEvent.fromElement;
			}
			else
			{	
				e.eventMapRelatedTarget = e.rawEvent.toElement;
			}
		}
		
		if (!e.eventMapRelatedTarget)
			return;
		
		try 
		{
			// Fix for FireFox "_moz_editor_bogus_node" problem.
			// Happens on mouseout and mouseover when the related target is an input element.
			// For some reason input elements have an "anonymous" div as a child:
			// <div class="anonymous-div" style="white-space: pre;" _moz_editor_bogus_node="TRUE" _moz_dirty="">
			// Accessing *any* attribute of such a node will throw "permission denied" error.
			var className = e.eventMapRelatedTarget.className;
		} 
		catch (ex) 
		{
			// Skip to the parent element.
			e.eventMapRelatedTarget = this._element;
		}		
	},
	
	_shouldUseEventCapture : function(eventName)
	{
		return (eventName == "blur" || eventName == "focus") && $telerik.isFirefox && Sys.Browser.version >= 3;
	},
	
	_getDomEventDelegate : function ()
	{
		if (!this._onDomEventDelegate)
		{
			this._onDomEventDelegate = Function.createDelegate(this, this._onDomEvent);
		}
		
		return this._onDomEventDelegate;
	}
}

Telerik.Web.UI.EventMap.registerClass('Telerik.Web.UI.EventMap');


if(typeof(Sys)!=='undefined')Sys.Application.notifyScriptLoaded();