var Cast = require('../util/cast');

var Keyboard = function (runtime) {
    /**
     * List of currently pressed keys.
     * @type{Array.<number>}
     */
    this._keysPressed = [];
    /**
     * Reference to the owning Runtime.
     * Can be used, for example, to activate hats.
     * @type{!Runtime}
     */
    this.runtime = runtime;
};

/**
 * Convert a Scratch key name to a DOM keyCode.
 * @param {Any} keyName Scratch key argument.
 * @return {number} Key code corresponding to a DOM event.
 * @private
 */
Keyboard.prototype._scratchKeyToKeyCode = function (keyName) {
    if (typeof keyName === 'number') {
        // Key codes placed in with number blocks.
        return keyName;
    }
    var keyString = Cast.toString(keyName);
    switch (keyString) {
    case 'space': return 32;
    case 'left arrow': return 37;
    case 'up arrow': return 38;
    case 'right arrow': return 39;
    case 'down arrow': return 40;
    // @todo: Consider adding other special keys here.
    }
    // Keys reported by DOM keyCode are upper case.
    return keyString.toUpperCase().charCodeAt(0);
};

/**
 * Convert a DOM keyCode into a Scratch key name.
 * @param  {number} keyCode Key code from DOM event.
 * @return {Any} Scratch key argument.
 * @private
 */
Keyboard.prototype._keyCodeToScratchKey = function (keyCode) {
    if (keyCode >= 48 && keyCode <= 90) {
        // Standard letter.
        return String.fromCharCode(keyCode).toLowerCase();
    }
    switch (keyCode) {
    case 32: return 'space';
    case 37: return 'left arrow';
    case 38: return 'up arrow';
    case 39: return 'right arrow';
    case 40: return 'down arrow';
    }
    return null;
};

/**
 * Keyboard DOM event handler.
 * @param  {object} data Data from DOM event.
 */
Keyboard.prototype.postData = function (data) {
    if (data.keyCode) {
        var index = this._keysPressed.indexOf(data.keyCode);
        if (data.isDown) {
            // If not already present, add to the list.
            if (index < 0) {
                this._keysPressed.push(data.keyCode);
            }
            // Always trigger hats, even if it was already pressed.
            this.runtime.startHats('event_whenkeypressed', {
                KEY_OPTION: this._keyCodeToScratchKey(data.keyCode)
            });
            this.runtime.startHats('event_whenkeypressed', {
                KEY_OPTION: 'any'
            });
        } else if (index > -1) {
            // If already present, remove from the list.
            this._keysPressed.splice(index, 1);
        }
    }
};

/**
 * Get key down state for a specified Scratch key name.
 * @param  {Any} key Scratch key argument.
 * @return {boolean} Is the specified key down?
 */
Keyboard.prototype.getKeyIsDown = function (key) {
    if (key === 'any') {
        return this._keysPressed.length > 0;
    }
    var keyCode = this._scratchKeyToKeyCode(key);
    return this._keysPressed.indexOf(keyCode) > -1;
};

module.exports = Keyboard;

@@ -1664,12 +1664,10 @@
 urn 
-null
+''
 ;%0A%7D;

Switch from return null to return empty string in keyCodeToScratchKey