// vim: et:ts=4:sw=4:sts=4:ft=js
/***
    Ox.Keyboard
***/

(function() {

    var buffer = '', resetTimeout, triggerTimeout;

    /*
    Ox.UI.ready(function() {
        // fixme: how to do this better?
        // in firefox on mac, keypress doesn't fire for up/down
        // if the cursor is at the start/end of an input element
        // on linux, it doesn't seem to fire if the input element has focus
        if ($.browser.mozilla) {
            Ox.UI.$document.keypress(keypress);
            Ox.UI.$document.keydown(function(event) {
                var $element = $('input:focus');
                if ($element.length) {
                    if (
                        (
                            Ox.KEYS[event.keyCode] == 'up' &&
                            $element[0].selectionStart + $element[0].selectionEnd == 0
                        ) || (
                            Ox.KEYS[event.keyCode] == 'down' &&
                            $element[0].selectionStart == $element.val().length &&
                            $element[0].selectionEnd == $element.val().length
                        )
                    ) {
                        keypress(event);
                    }
                }
            });
        } else {
            Ox.UI.$document.keydown(keypress);
        }
    });
    */

    Ox.UI.ready(function() {
        Ox.UI.$document.keydown(keydown)
    });

    function keydown(event) {

        var focused = Ox.Focus.focused(),
            key,
            keyName = Ox.KEYS[event.keyCode] || '',
            keyNames = keyName ? [keyName] : [],
            keyBasename = keyName.split('.')[0],
            ret = true;

        Ox.forEach(Ox.MODIFIER_KEYS, function(v, k) {
            // avoid pushing modifier twice
            // using event.originalEvent since jquery always sets event.metaKey to event.ctrlKey
            if (event.originalEvent[k] && keyBasename != v) {
                keyNames.splice(-1, 0, v);
            }
        });
        key = keyNames.join('_');
        if (focused !== null) {
            Ox.UI.elements[focused].triggerEvent('key_' + key);
            // prevent Chrome from scrolling, or going back in history
            if (
                [
                    'backspace', 'down', 'left', 'right', 'space', 'up'
                ].indexOf(key) > -1 &&
                !Ox.UI.elements[focused].hasClass('OxInput') &&
                !Ox.UI.elements[focused].hasClass('OxAutocompleteMenu')
            ) {
                ret = false;
            }
            // prevent cursor in input field from moving to start or end
            if (
                ['down', 'up'].indexOf(key) > -1 &&
                Ox.UI.elements[focused].hasClass('OxAutocompleteMenu')
            ) {
                ret = false;
            }
        }

        if (/^[\w\d](\.numpad)?$|^space$/.test(key)) {
            // don't register leading spaces or trailing double spaces
            if (!(keyName == 'space' && (buffer == '' || / $/.test(buffer)))) {
                buffer += keyName == 'space' ? ' ' : keyBasename;
                // clear the trigger timeout only if the key went into the buffer
                clearTimeout(triggerTimeout);
                triggerTimeout = setTimeout(function() {
                    focused !== null && Ox.UI.elements[focused].triggerEvent('keys', {
                        keys: buffer
                    });
                }, 25);
                // fixme: used to be 250, but seemed too much.
                // if it stays at 25, we may not need a timeout at all
            }
        }
        // clear the reset timeout even if the key didn't go into the buffer
        clearTimeout(resetTimeout);
        resetTimeout = setTimeout(function() {
            buffer = '';
        }, 1000);

        Ox.print(ret)
        return ret;

    }

})();