﻿// Utilizes prototype lib for hashtables

/**
 * Initializes the shortcut manager
 */
ShortcutManager = function() {
	this.shortcuts = new Hash();
	this.specialkeys = new Hash(
		{ 	
			27:'esc',9:'tab',32:'space',13:'return',8:'backspace',

			145:'scroll_lock',20:'caps_lock',144:'num_lock',19:'pause',
			
			45:'insert',36:'home',46:'delete',35:'end',
			33:'page_up',34:'page_down',

			37:'left',38:'up',39:'right',40:'down',

			112:'f1',113:'f2',114:'f3',115:'f4',116:'f5',117:'f6',118:'f7',119:'f8',120:'f9',121:'f10',122:'f11',123:'f12'
		}
	);
}

/**
 * Utility method for ensuring that the modifier-keys are always in C-A-S order
 */
ShortcutManager.prototype.NormalizeShortcut = function(shortcut) {
	var ctrlkey	= false;
	var altkey = false;
	var shiftkey = false;
	
	var keys = shortcut.split("+");
	
	for ( var i = 0; i < keys.length; i++ ) {
		if ( keys[i].toLowerCase() == "ctrl" ) { ctrlkey = true; }
		if ( keys[i].toLowerCase() == "alt" ) { altkey = true; }
		if ( keys[i].toLowerCase() == "shift" ) { shiftkey = true; }
	}

	shortcut = (( ctrlkey ) ? "ctrl+" : "") +
			   (( altkey ) ? "alt+" : "") +
			   (( shiftkey ) ? "shift+" : "") +
			   keys[keys.length - 1].toLowerCase();

	return shortcut;
}

/**
 * Adds a shortcut
 *
 * @param shortcut		String describing the shortcut. Modifier-keys are seperated by '+' -
 *						"ctrl+alt+s" is an example. Existing shortcuts will be overwritten.
 * @param handler		Handlerfunction to be called for handling shortcut.
 *					    Handler must return a bool - true if event should be swallowed, false otherwise
 * @param propagate		Optional bool indicating if event-propagation should happen
 */
ShortcutManager.prototype.RegisterShortcut = function(shortcut, handler, propagate) {
	var nShortcut = this.NormalizeShortcut(shortcut);
	this.ClearShortcut(nShortcut);
	this.shortcuts.set(nShortcut, { fn : handler, prop : propagate });
}

/**
 * Removes a shortcut. No function will be executed for the shortcut after removal.
 *
 * @param shortcut		Shortcut to remove
 */
ShortcutManager.prototype.ClearShortcut = function(shortcut) {
	if ( this.shortcuts.keys().indexOf(shortcut) != -1 ) {
		this.shortcuts[shortcut].fn = null;
	}
	this.shortcuts.unset(this.NormalizeShortcut(shortcut));
}

/**
 * Process a keypress. If a shortcut matching the keypress is found, the handler
 * for that shortcut will be executed
 *
 * @param e				Current event-object
 *
 * @returns bool		True if shortcut was handled, otherwise false
 */
ShortcutManager.prototype.ProcessKeypress = function(e) {
	e = ( e == null ) ? event : e;

	// VIA-1946: disable F11 full screen
	if (122 == e.keyCode) {
	    e.keyCode = 0;
	    return true;
	}
	
	var shortcut = (( e.ctrlKey ) ? "ctrl+" : "") +
				   (( e.altKey ) ? "alt+" : "") +
			       (( e.shiftKey ) ? "shift+" : "");

	var keycode = ( e.keyCode != null ) ? e.keyCode : e.charCode;

	// translate keycode to string
	// CORE-4833: cast keycode to string when performing lookup in specialkeys
	if ( this.specialkeys.keys().indexOf(keycode.toString()) != -1 ) {
		shortcut += this.specialkeys.values()[this.specialkeys.keys().indexOf(keycode.toString())];
//		shortcut += this.specialkeys[keycode.toString()];	
	}
	else {
		shortcut += String.fromCharCode(keycode).toLowerCase();
	}
		
	var scObj = this.shortcuts.get(shortcut);
	if ( typeof (scObj) != 'undefined' ) {
		// call handler
		if ( scObj.fn(e) ) {
			if ( !scObj.propagate ) {
				if ( e.stopPropagation ) {
					e.stopPropagation();
					e.preventDefault();
				}
				else {
					e.cancelBubble = true;
					e.returnValue = false;
				}
			}
		
			return true;
		}
	}
	
	return false;
}

