/*
 * Copyright 2014-present Open Networking Foundation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 ONOS GUI -- Util -- Key Handler Service
 */
(function () {
    'use strict';

    // references to injected services
    var $log, fs, ts, ns, ee, qhs, ls;

    // internal state
    var enabled = true,
        globalEnabled = true,
        keyHandler = {
            globalKeys: {},
            maskedKeys: {},
            dialogKeys: {},
            viewKeys: {},
            viewFn: null,
            viewGestures: [],
        },
        seq = {},
        matching = false,
        matched = '',
        lookup;

    function matchSeq(key) {
        if (!matching && key === 'shift-shift') {
            matching = true;
            return true;
        }
        if (matching) {
            matched += key;
            lookup = fs.trieLookup(seq, matched);
            if (lookup === -1) {
                return true;
            }
            matching = false;
            matched = '';
            if (!lookup) {
                return;
            }
            ee.cluck(lookup);
            return true;
        }
    }

    function whatKey(code) {
        switch (code) {
            case 8: return 'delete';
            case 9: return 'tab';
            case 13: return 'enter';
            case 16: return 'shift';
            case 27: return 'esc';
            case 32: return 'space';
            case 37: return 'leftArrow';
            case 38: return 'upArrow';
            case 39: return 'rightArrow';
            case 40: return 'downArrow';
            case 186: return 'semicolon';
            case 187: return 'equals';
            case 188: return 'comma';
            case 189: return 'dash';
            case 190: return 'dot';
            case 191: return 'slash';
            case 192: return 'backQuote';
            case 219: return 'openBracket';
            case 220: return 'backSlash';
            case 221: return 'closeBracket';
            case 222: return 'quote';
            default:
                if ((code >= 48 && code <= 57) ||
                    (code >= 65 && code <= 90)) {
                    return String.fromCharCode(code);
                } else if (code >= 112 && code <= 123) {
                    return 'F' + (code - 111);
                }
                return null;
        }
    }

    var textFieldDoesNotBlock = {
        enter: 1,
        esc: 1,
    };

    function textFieldInput() {
        var t = d3.event.target.tagName.toLowerCase();
        return t === 'input' || t === 'textarea';
    }

    function keyIn() {
        var event = d3.event,
            keyCode = event.keyCode,
            key = whatKey(keyCode),
            textBlockable = !textFieldDoesNotBlock[key],
            modifiers = [];

        event.metaKey && modifiers.push('cmd');
        event.altKey && modifiers.push('alt');
        event.shiftKey && modifiers.push('shift');

        if (!key) {
            return;
        }

        modifiers.push(key);
        key = modifiers.join('-');

        if (textBlockable && textFieldInput()) {
            return;
        }

        var kh = keyHandler,
            gk = kh.globalKeys[key],
            gcb = fs.isF(gk) || (fs.isA(gk) && fs.isF(gk[0])),
            dk = kh.dialogKeys[key],
            dcb = fs.isF(dk),
            vk = kh.viewKeys[key],
            kl = fs.isF(kh.viewKeys._keyListener),
            vcb = fs.isF(vk) || (fs.isA(vk) && fs.isF(vk[0])) || fs.isF(kh.viewFn),
            token = 'keyev'; // indicate this was a key-pressed event

        event.stopPropagation();

        if (enabled) {
            if (matchSeq(key)) return;

            // global callback?
            if (gcb && gcb(token, key, keyCode, event)) {
                // if the event was 'handled', we are done
                return;
            }
            // dialog callback?
            if (dcb) {
                dcb(token, key, keyCode, event);
                // assume dialog handled the event
                return;
            }
            // otherwise, let the view callback have a shot
            if (vcb) {
                vcb(token, key, keyCode, event);
            }
            if (kl) {
                kl(key);
            }
        }
    }

    // functions to obtain localized strings deferred from the setup of the
    //  global key data structures.
    function qhlion() {
        return ls.bundle('core.fw.QuickHelp');
    }
    function qhlion_show_hide() {
        return qhlion()('qh_hint_show_hide_qh');
    }

    function qhlion_hint_esc() {
        return qhlion()('qh_hint_esc');
    }

    function qhlion_hint_t() {
        return qhlion()('qh_hint_t');
    }

    function setupGlobalKeys() {
        angular.extend(keyHandler, {
            globalKeys: {
                backSlash: [quickHelp, qhlion_show_hide],
                slash: [quickHelp, qhlion_show_hide],
                esc: [escapeKey, qhlion_hint_esc],
                T: [toggleTheme, qhlion_hint_t],
            },
            globalFormat: ['backSlash', 'slash', 'esc', 'T'],

            // Masked keys are global key handlers that always return true.
            // That is, the view will never see the event for that key.
            maskedKeys: {
                slash: 1,
                backSlash: 1,
                T: 1,
            },
        });
    }

    function quickHelp(view, key, code, ev) {
        if (!globalEnabled) {
            return false;
        }
        qhs.showQuickHelp(keyHandler);
        return true;
    }

    // returns true if we 'consumed' the ESC keypress, false otherwise
    function escapeKey(view, key, code, ev) {
        return ns.hideIfShown() || qhs.hideQuickHelp();
    }

    function toggleTheme(view, key, code, ev) {
        if (!globalEnabled) {
            return false;
        }
        ts.toggleTheme();
        return true;
    }

    function filterMaskedKeys(map, caller, remove) {
        var masked = [],
            msgs = [];

        d3.map(map).keys().forEach(function (key) {
            if (keyHandler.maskedKeys[key]) {
                masked.push(key);
                msgs.push(caller, ': Key "' + key + '" is reserved');
            }
        });

        if (msgs.length) {
            $log.warn(msgs.join('\n'));
        }

        if (remove) {
            masked.forEach(function (k) {
                delete map[k];
            });
        }
        return masked;
    }

    function unexParam(fname, x) {
        $log.warn(fname, ': unexpected parameter-- ', x);
    }

    function setKeyBindings(keyArg) {
        var fname = 'setKeyBindings()',
            kFunc = fs.isF(keyArg),
            kMap = fs.isO(keyArg);

        if (kFunc) {
            // set general key handler callback
            keyHandler.viewFn = kFunc;
        } else if (kMap) {
            filterMaskedKeys(kMap, fname, true);
            keyHandler.viewKeys = kMap;
        } else {
            unexParam(fname, keyArg);
        }
    }

    function getKeyBindings() {
        var gkeys = d3.map(keyHandler.globalKeys).keys(),
            masked = d3.map(keyHandler.maskedKeys).keys(),
            vkeys = d3.map(keyHandler.viewKeys).keys(),
            vfn = !!fs.isF(keyHandler.viewFn);

        return {
            globalKeys: gkeys,
            maskedKeys: masked,
            viewKeys: vkeys,
            viewFunction: vfn,
        };
    }

    function unbindKeys() {
        keyHandler.viewKeys = {};
        keyHandler.viewFn = null;
        keyHandler.viewGestures = [];
    }

    function bindDialogKeys(map) {
        var fname = 'bindDialogKeys()',
            kMap = fs.isO(map);

        if (kMap) {
            filterMaskedKeys(map, fname, true);
            keyHandler.dialogKeys = kMap;
        } else {
            unexParam(fname, map);
        }
    }

    function unbindDialogKeys() {
        keyHandler.dialogKeys = {};
    }

    function checkNotGlobal(o) {
        var oops = [];
        if (fs.isO(o)) {
            angular.forEach(o, function (val, key) {
                if (keyHandler.globalKeys[key]) {
                    oops.push(key);
                }
            });
            if (oops.length) {
                $log.warn('Ignoring reserved global key(s):', oops.join(','));
                oops.forEach(function (key) {
                    delete o[key];
                });
            }
        }
    }

    angular.module('onosUtil')
    .factory('KeyService',
        ['$log', 'FnService', 'ThemeService', 'NavService',
            'EeService', 'LionService',

        function (_$log_, _fs_, _ts_, _ns_, _ee_, _ls_) {
            $log = _$log_;
            fs = _fs_;
            ts = _ts_;
            ns = _ns_;
            ee = _ee_;
            ls = _ls_;

            return {
                bindQhs: function (_qhs_) {
                    qhs = _qhs_;
                },
                installOn: function (elem) {
                    elem.on('keydown', keyIn);
                    setupGlobalKeys();
                },
                keyBindings: function (x) {
                    if (x === undefined) {
                        return getKeyBindings();
                    } else {
                        setKeyBindings(x);
                    }
                },
                unbindKeys: unbindKeys,
                dialogKeys: function (x) {
                    if (x === undefined) {
                        unbindDialogKeys();
                    } else {
                        bindDialogKeys(x);
                    }
                },
                addSeq: function (word, data) {
                    fs.addToTrie(seq, word, data);
                },
                remSeq: function (word) {
                    fs.removeFromTrie(seq, word);
                },
                gestureNotes: function (g) {
                    if (g === undefined) {
                        return keyHandler.viewGestures;
                    } else {
                        keyHandler.viewGestures = fs.isA(g) || [];
                    }
                },
                enableKeys: function (b) {
                    enabled = b;
                },
                enableGlobalKeys: function (b) {
                    globalEnabled = b;
                },
                checkNotGlobal: checkNotGlobal,
            };
    }]);

}());
