/*!
 * jQuery UI Hotkey @VERSION
 * http://jqueryui.com
 *
 * Copyright 2013 jQuery Foundation and other contributors
 * Released under the MIT license.
 * http://jquery.org/license
 *
 * Depends:
 *  jquery.ui.core.js
 *  jquery.ui.widget.js
 */

(function( $, undefined ) {

var VK_BACK    = 0x08;
var VK_TAB     = 0x09;
var VK_SHIFT   = 0x10;
var VK_CONTROL = 0x11;
var VK_MENU    = 0x12;

var VK_ESCAPE  = 0x1B;
var VK_DELETE  = 0x2E;

var HOTKEYF_SHIFT   = 0x01;
var HOTKEYF_CONTROL = 0x02;
var HOTKEYF_ALT     = 0x04;

var VK_CODE = new Array(
    '', '', '', 'Scroll Lock', '', '', '', '', 'Backspace', 'Tab', '', '', 'Num 5', 'Enter', '', '',
    '', '', '', '', 'Caps Lock', '', '', '', '', '', '', 'Esc', '', '', '', '',
    'Space', 'Page Up', 'Page Down', 'End', 'Home', 'Left', 'Up', 'Right', 'Down', '', '', '', '', 'Insert', 'Delete', '',
    '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '', '', '', '', '', '',
    '', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '', '', '', '', '',
    'Num 0', 'Num 1', 'Num 2', 'Num 3', 'Num 4', 'Num 5', 'Num 6', 'Num 7', 'Num 8', 'Num 9', 'Num *', 'Num +', '', 'Num -', 'Num Del', 'Num /',
    'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16',
    'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', '', '', '', '', '', '', '', '',
    'Num Lock', 'Scroll Lock', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', '', '', '', '', '', '', '', ';', '=', ',', '-', '.', '/',
    '`', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', '', '', '', '', '', '', '', '', '[', '\\', ']', '\'', '',
    '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', '',
    '', '', '', '', '', '', '', '', '', '', '', '', '', '', '', ''
    );

$.widget( "ui.hotkey", {
    version: "@VERSION",
    options: {
        disabled: false,
        keyCode:   0,  /* Virtual key code of the keyboard shortcut. For a list of standard virtual key codes, see Winuser.h. */
        modifiers: 0,   /* A bitwise combination (OR) of flags that indicate the modifier keys in the keyboard shortcut. */
        rules:     0
    },
    _create: function() {
        var that = this,
            options = this.options;
        if (!this._isReadableChar(options.keyCode)) {
            options.keyCode = 0;
        }
        options.modifiers &= 0x07; // HOTKEYF_SHIFT | HOTKEYF_CONTROL | HOTKEYF_ALT

        this.element.val( this._getReadableString() );
        this.element.bind( "keydown" + this.eventNamespace, function(event) {
            var modifiers = 0,
                keyCode = 0;
			if(keyCode != VK_SHIFT && keyCode != VK_CONTROL && keyCode != VK_MENU)
				keyCode = event.keyCode;
            modifiers = 0;
            if (!keyCode || keyCode == VK_TAB) {
                return;
            }
            if (event.ctrlKey) {
                modifiers |= HOTKEYF_CONTROL;
            }
            if (event.shiftKey) {
                modifiers |= HOTKEYF_SHIFT;
            }
            if (event.altKey) {
                modifiers |= HOTKEYF_ALT;
            }
            if (keyCode == VK_BACK || keyCode == VK_ESCAPE || keyCode == VK_DELETE) {
                keyCode = 0;
                modifiers = 0;
            }
            that._setValue(event, modifiers, keyCode);
            event.preventDefault();
            event.stopImmediatePropagation();
        });
        this.element.bind( "keyup" + this.eventNamespace, function (event) {
            var keyCode = event.keyCode;
            if ((keyCode == VK_SHIFT || keyCode == VK_CONTROL || keyCode == VK_MENU)
                && that.options.keyCode == 0) {
                that._setValue(event, 0, 0);
            }
        }); 
        this.element.bind( "blur" + this.eventNamespace, function(event) {
            if (that.options.keyCode == 0) {
                that._setValue(event, 0, 0);
            }
			that.element.val( that._getReadableString() );
        });
        this.element.bind( "focus" + this.eventNamespace, function(event) {
            event.preventDefault();
            event.stopImmediatePropagation();
        });
    },
	_getReadableStringEx : function(modifiers,keyCode){
        var str = "";
        if (modifiers&0x02) {
            str += "Ctrl + ";
        }
        if (modifiers&0x01) {
            str += "Shift + ";
        }
        if (modifiers&0x04) {
            str += "Alt + ";
        }
        if (keyCode) {
            str += VK_CODE[keyCode];
        }
        return str == "" ? "无" : str;		
	},
    _getReadableString : function() {
		return this._getReadableStringEx(this.options.modifiers,this.options.keyCode);
    },
    _setValue: function(event, modifiers, keyCode) {
        modifiers = modifiers | this.options.rules;
        if (!this._isReadableChar(keyCode)) {
            keyCode = 0;
        }
		if(modifiers!=0 && keyCode==0){
			this.element.val(this._getReadableStringEx(modifiers,keyCode));
			return;
		}
        var allowed = this._trigger("changing", event, { modifiers : modifiers, keyCode: keyCode});
        if (allowed !== false) {
			this.options.modifiers = modifiers;
			this.options.keyCode = keyCode;
			this.element.val( this._getReadableString() );
			this._trigger("changed", event, { modifiers : modifiers, keyCode: keyCode });
        }
        this.element.val( this._getReadableString() );
    },
    _isReadableChar: function (keyCode) {
        if (keyCode < 0 || keyCode > 255) {
            return false;
        }
        return VK_CODE[keyCode] != "";
    },
	SetHotKey:function(modifiers, keyCode){
        modifiers = modifiers | this.options.rules;
        if (!this._isReadableChar(keyCode)) {
            keyCode = 0;
        }
		this.options.modifiers = modifiers;
		this.options.keyCode = keyCode;
		this.element.val( this._getReadableString() );
	}
});
}( jQuery ) );
