/*
 * Copyright 2014 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 -- Quick Help Layer

 Defines the key-map layer for the UI. Used to give user a list of
 key bindings; both global, and for the current view.

 @author Simon Hunt
 */

(function (onos){
    'use strict';

    // API's
    var api = onos.api;

    // Config variables
    var w = '100%',
        h = '80%',
        fade = 500,
        vb = '-200 0 400 400';

    // State variables
    var data = [];

    // DOM elements and the like
    var qhdiv = d3.select('#quickhelp'),
        svg = qhdiv.select('svg'),
        pane,
        rect,
        items,
        keyAgg;

    // General functions
    function isA(a) {
        return $.isArray(a) ? a : null;
    }

    var keyDisp = {
        equals: '=',
        dash: '-',
        slash: '/',
        backQuote: '`',
        leftArrow: 'L-arrow',
        upArrow: 'U-arrow',
        rightArrow: 'R-arrow',
        downArrow: 'D-arrow'
    };

    function cap(s) {
        return s.replace(/^[a-z]/, function (m) { return m.toUpperCase(); });
    }

    function mkKeyDisp(id) {
        var v = keyDisp[id] || id;
        return cap(v);
    }

    // layout configuration
    var pad = 8,
        offy = 45,
        dy = 14,
        offDesc = 8;

    // D3 magic
    function updateKeyItems() {
        var keyItems = items.selectAll('.keyItem')
            .data(data);

        var entering = keyItems.enter()
            .append('g')
            .attr({
                id: function (d) { return d.id; },
                class: 'keyItem'
            });

        entering.each(function (d, i) {
            var el = d3.select(this),
                y = offy + dy * i;

            if (d.id[0] === '_') {
                el.append('line')
                    .attr({ x1: 0, y1: y, x2: 1, y2: y});
            } else {
                el.append('text')
                    .text(d.key)
                    .attr({
                        class: 'key',
                        x: 0,
                        y: y
                    });
                // NOTE: used for sizing column width...
                keyAgg.append('text').text(d.key).attr('class', 'key');

                el.append('text')
                    .text(d.desc)
                    .attr({
                        class: 'desc',
                        x: offDesc,
                        y: y
                    });
            }
        });

        var kbox = keyAgg.node().getBBox();
        items.selectAll('.desc').attr('x', kbox.width + offDesc);

        var box = items.node().getBBox(),
            paneW = box.width + pad * 2,
            paneH = box.height + offy;

        items.selectAll('line').attr('x2', box.width);
        items.attr('transform', translate(-paneW/2, -pad));
        rect.attr({
            width: paneW,
            height: paneH,
            transform: translate(-paneW/2-pad, 0)
        });
    }

    function translate(x, y) {
        return 'translate(' + x + ',' + y + ')';
    }

    function aggregateData(bindings) {
        var gmap = d3.map(bindings.globalKeys),
            vmap = d3.map(bindings.viewKeys),
            gkeys = gmap.keys(),
            vkeys = vmap.keys(),
            vgest = bindings.viewGestures,
            sep = 0;

        gkeys.sort();
        vkeys.sort();

        data = [];
        gkeys.forEach(function (k) {
            addItem('glob', k, gmap.get(k));
        });
        addItem('sep');
        vkeys.forEach(function (k) {
            addItem('view', k, vmap.get(k));
        });
        addItem('sep');
        vgest.forEach(function (g) {
            if (g.length === 2) {
                addItem('gest', g[0], g[1]);
            }
        });


        function addItem(type, k, d) {
            var id = type + '-' + k,
                a = isA(d),
                desc = a && a[1];

            if (type === 'sep') {
                data.push({
                    id: '_' + sep++,
                    type: type
                });
            } else if (type === 'gest') {
                data.push({
                    id: id,
                    type: type,
                    key: k,
                    desc: d
                });
            } else if (desc) {
                data.push(
                    {
                        id: id,
                        type: type,
                        key: mkKeyDisp(k),
                        desc: desc
                    }
                );
            }
        }
    }

    function popBind(bindings) {
        pane = svg.append('g')
            .attr({
                class: 'help',
                opacity: 0
            });

        rect = pane.append('rect')
            .attr('rx', 8);

        pane.append('text')
            .text('Quick Help')
            .attr({
                class: 'title',
                dy: '1.2em',
                transform: translate(-pad,0)
            });

        items = pane.append('g');
        keyAgg = pane.append('g').style('visibility', 'hidden');

        aggregateData(bindings);
        updateKeyItems();

        _fade(1);
    }

    function fadeBindings() {
        _fade(0);
    }

    function _fade(o) {
        svg.selectAll('g.help')
            .transition()
            .duration(fade)
            .attr('opacity', o);
    }

    function addSvg() {
        svg = qhdiv.append('svg')
            .attr({
                width: w,
                height: h,
                viewBox: vb
            });
    }

    function removeSvg() {
        svg.transition()
            .delay(fade + 20)
            .remove();
    }

    function showQuickHelp(bindings) {
        svg = qhdiv.select('svg');
        if (svg.empty()) {
            addSvg();
            popBind(bindings);
        } else {
            hideQuickHelp();
        }
    }

    function hideQuickHelp() {
        svg = qhdiv.select('svg');
        if (!svg.empty()) {
            fadeBindings();
            removeSvg();
            return true;
        }
        return false;
    }

    onos.ui.addLib('quickHelp', {
        show: showQuickHelp,
        hide: hideQuickHelp
    });
}(ONOS));
