var FormHandler = new Class({
	Implements: Options,
	keyMap: Class.Empty,
	
	options: {
		keyMap: Class.empty
	},
	
	initialize: function(options)
	{
		$(window).addEvent('keydown', this.handleKeys.bind(this) );

		if (Browser.Engine.trident)
			$(document).addEvent('keydown', this.handleKeys.bind(this) );

		this.setOptions(options);

		this.bindKeymap();
	},

	bindKeymap: function()
	{
		if ( this.options.keyMap !== Class.empty )
		{
			this.keyMap = [];

			for (var key in this.options.keyMap)
			{
				var mapElement = key;
				var containerElement = '';
				if (key.test(/^[a-z0-9_,]+:/i))
				{
					var parts = key.split(':');
					mapElement = parts[1].trim();
					containerElement = parts[0].trim();
				}

				var keySets = mapElement.split(',');
				keySets.each(function(keySet) {
					keySet = keySet.trim();
					var parts = keySet.split("+");
					if ( parts.length )
						this.keyMap.include( new CHotkeySelector( containerElement, parts.getLast(), parts.erase( parts.getLast() ), this.options.keyMap[key] ));
				}, this);
			}
		}
	},

	handleKeys: function(event)
	{
		var event = new Event(event);

		if ( this.keyMap !== Class.Empty )
		{
			this.keyMap.each(function(selector){
				if ( selector.key == event.key )
				{
					if (!selector.containerElement || selector.containerElement.hasChild(event.target))
					{
						var modifierFound = true;

						selector.modifiers.each(function(modifier){
							if ( modifier == 'alt' && !event.alt ) modifierFound = false;
							if ( modifier == 'meta' && !event.meta ) modifierFound = false;
							if ( modifier == 'control' && !event.control ) modifierFound = false;
							if ( modifier == 'shift' && !event.shift ) modifierFound = false;
						})

						if ( modifierFound )
						{
							event.stop();
							event.preventDefault();
							selector.fn(event);
							return;
						}
					}
				}
			});
		}
	}
});

var CHotkeySelector = new Class({
	containerElement: null,
	key: null,
	modifiers: null,
	fn: Class.Empty,

	initialize: function( containerId, key, modifiers, fn )
	{
		this.key = key;
		this.modifiers = modifiers;
		this.fn = fn;

		if ( $type(containerId) == 'string' && containerId.length )
			this.containerElement = $(containerId);
	}
});