/*
 * Copyright 2015 Open Networking Laboratory
 *
 * 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 -- Topology Toolbar Module.
 Functions for creating and interacting with the toolbar.
 */

(function () {
    'use strict';

    // injected references
    var $log, fs, tbs, ps, tov, tds, api;

    // API:
    //  getActionEntry
    //  setUpKeys

    // internal state
    var toolbar, keyData, cachedState, thirdRow, ovRset, ovIndex;

    // constants
    var name = 'topo-tbar',
        cooktag = 'topo_prefs',
        soa = 'switchOverlayActions: ',
        selOver = 'Select overlay here &#x21e7;',
        defaultOverlay = 'traffic';


    // key to button mapping data
    var k2b = {
        O: { id: 'summary-tog', gid: 'summary', isel: true},
        I: { id: 'instance-tog', gid: 'uiAttached', isel: true },
        D: { id: 'details-tog', gid: 'details', isel: true },
        H: { id: 'hosts-tog', gid: 'endstation', isel: false },
        M: { id: 'offline-tog', gid: 'switch', isel: true },
        P: { id: 'ports-tog', gid: 'ports', isel: true },
        B: { id: 'bkgrnd-tog', gid: 'map', isel: false },
        S: { id: 'sprite-tog', gid: 'cloud', isel: false },

        // TODO: add reset-node-locations button to toolbar
        //X: { id: 'nodelock-tog', gid: 'lock', isel: false },
        Z: { id: 'oblique-tog', gid: 'oblique', isel: false },
        N: { id: 'filters-btn', gid: 'filters' },
        L: { id: 'cycleLabels-btn', gid: 'cycleLabels' },
        R: { id: 'resetZoom-btn', gid: 'resetZoom' },

        E: { id: 'eqMaster-btn', gid: 'eqMaster' }
    };

    var prohibited = [
        'T', 'backSlash', 'slash',
        'X' // needed until we re-instate X above.
    ];
    prohibited = prohibited.concat(d3.map(k2b).keys());


    // initial toggle state: default settings and tag to key mapping
    var defaultPrefsState = {
            insts: 1,
            summary: 1,
            detail: 1,
            hosts: 0,
            offdev: 1,
            dlbls: 0,
            porthl: 1,
            bg: 0,
            spr: 0,
            toolbar: 0
        },
        prefsMap = {
            summary: 'O',
            insts: 'I',
            detail: 'D',
            hosts: 'H',
            offdev: 'M',
            porthl: 'P',
            bg: 'B',
            spr: 'S'
            // NOTE: toolbar state is handled separately
        };

    function init(_api_) {
        api = _api_;

        // retrieve initial toggle button settings from user prefs
        setInitToggleState();
    }

    function topoDefPrefs() {
        return angular.extend({}, defaultPrefsState);
    }

    function setInitToggleState() {
        cachedState = ps.asNumbers(ps.getPrefs(cooktag, defaultPrefsState));
        $log.debug('TOOLBAR---- read prefs state:', cachedState);

        if (!cachedState) {
            cachedState = topoDefPrefs();
            ps.setPrefs(cooktag, cachedState);
            $log.debug('TOOLBAR---- Set default prefs state:', cachedState);
        }

        angular.forEach(prefsMap, function (v, k) {
            var cfg = k2b[v];
            cfg && (cfg.isel = !!cachedState[k]);
        });
    }

    function initKeyData() {
        // TODO: use angular forEach instead of d3.map
        keyData = d3.map(k2b);
        keyData.forEach(function(key, value) {
            var data = api.getActionEntry(key);
            value.cb = data[0];                     // on-click callback
            value.tt = data[1] + ' (' + key + ')';  // tooltip
        });
    }

    function addButton(key) {
        var v = keyData.get(key);
        v.btn = toolbar.addButton(v.id, v.gid, v.cb, v.tt);
    }

    function addToggle(key, suppressIfMobile) {
        var v = keyData.get(key);
        if (suppressIfMobile && fs.isMobile()) { return; }
        v.tog = toolbar.addToggle(v.id, v.gid, v.isel, v.cb, v.tt);
    }

    function addFirstRow() {
        addToggle('I');
        addToggle('O');
        addToggle('D');
        toolbar.addSeparator();

        addToggle('H');
        addToggle('M');
        addToggle('P', true);
        addToggle('B');
        addToggle('S', true);
    }

    function addSecondRow() {
        //addToggle('X');
        addToggle('Z');
        addButton('N');
        addButton('L');
        addButton('R');
        toolbar.addSeparator();
        addButton('E');
    }

    function addOverlays() {
        toolbar.addSeparator();

        // generate radio button set for overlays; start with 'none'
        var rset = [{
                gid: 'unknown',
                tooltip: 'No Overlay',
                cb: function () {
                    tov.tbSelection(null, switchOverlayActions);
                }
            }];
        ovIndex = tov.augmentRbset(rset, switchOverlayActions);
        ovRset = toolbar.addRadioSet('topo-overlays', rset);
    }

    // invoked by overlay service to switch out old buttons and switch in new
    function switchOverlayActions(oid, keyBindings) {
        var prohibits = [],
            kb = fs.isO(keyBindings) || {},
            order = fs.isA(kb._keyOrder) || [];

        if (keyBindings && !keyBindings._keyOrder) {
            $log.warn(soa + 'no _keyOrder property defined');
        } else {
            // sanity removal of reserved property names
            ['esc', '_keyListener', '_helpFormat'].forEach(function (k) {
                fs.removeFromArray(k, order);
            });
        }

        // ensure dialog has closed (if opened by outgoing overlay)
        tds.closeDialog();
        thirdRow.clear();

        if (!order.length) {
            thirdRow.setText(selOver);
            thirdRow.classed('right', true);
            api.setUpKeys(); // clear previous overlay key bindings

        } else {
            thirdRow.classed('right', false);
            angular.forEach(order, function (key) {
                var value, bid, gid, tt;

                if (prohibited.indexOf(key) > -1) {
                    prohibits.push(key);

                } else {
                    value = keyBindings[key];
                    bid = oid + '-' + key;
                    gid = tov.mkGlyphId(oid, value.gid);
                    tt = value.tt + ' (' + key + ')';
                    thirdRow.addButton(bid, gid, value.cb, tt);
                }
            });
            api.setUpKeys(keyBindings); // add overlay key bindings
        }

        if (prohibits.length) {
            $log.warn(soa + 'Prohibited key bindings ignored:', prohibits);
        }
    }

    function createToolbar() {
        initKeyData();
        toolbar = tbs.createToolbar(name);
        addFirstRow();
        toolbar.addRow();
        addSecondRow();
        addOverlays();
        thirdRow = toolbar.addRow();
        thirdRow.setText(selOver);
        thirdRow.classed('right', true);

        if (cachedState.toolbar) {
            toolbar.show();
        } else {
            toolbar.hide();
        }
    }

    function destroyToolbar() {
        tbs.destroyToolbar(name);
        tov.resetOnToolbarDestroy();
    }

    // allows us to ensure the button states track key strokes
    function keyListener(key) {
        var v = keyData.get(key);

        if (v) {
            // we have a valid button mapping
            if (v.tog) {
                // it's a toggle button
                v.tog.toggleNoCb();
            }
        }
    }

    function toggleToolbar() {
        toolbar.toggle();
        var prefs = ps.getPrefs(cooktag, defaultPrefsState);
        prefs.toolbar = !prefs.toolbar;
        ps.setPrefs('topo_prefs', prefs);
    }

    function setDefaultOverlay() {
        var idx = ovIndex[defaultOverlay] || 0;
        ovRset.selectedIndex(idx);
    }

    // an overlay was selected via Function-Key press
    function fnkey(idx) {
        if (idx < ovRset.size() && idx !== ovRset.selectedIndex()) {
            ovRset.selectedIndex(idx);
        }
    }

    angular.module('ovTopo')
        .factory('TopoToolbarService',
        ['$log', 'FnService', 'ToolbarService', 'PrefsService',
            'TopoOverlayService', 'TopoDialogService',

        function (_$log_, _fs_, _tbs_, _ps_, _tov_, _tds_) {
            $log = _$log_;
            fs = _fs_;
            tbs = _tbs_;
            ps = _ps_;
            tov = _tov_;
            tds = _tds_;

            return {
                init: init,
                createToolbar: createToolbar,
                destroyToolbar: destroyToolbar,
                keyListener: keyListener,
                toggleToolbar: toggleToolbar,
                setDefaultOverlay: setDefaultOverlay,
                defaultPrefs: defaultPrefsState,
                fnkey: fnkey
            };
        }]);
}());