/*
 * 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;

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

    var keyDisp = {
        equals: '=',
        dash: '-',
        slash: '/',
        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 = 40;

    // 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 === '_') {
                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
                    });

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

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

        items.select('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();

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

        data = [];
        gkeys.forEach(function (k) {
            addItem('global', k, gmap.get(k));
        });
        addItem('separator');
        vkeys.forEach(function (k) {
            addItem('view', k, vmap.get(k));
        });

        function addItem(type, k, d) {
            var id = type + '-' + k,
                a = isA(d),
                desc = a && a[1];
            if (desc) {
                data.push(
                    {
                        id: id,
                        type: type,
                        key: mkKeyDisp(k),
                        desc: desc
                    }
                );
            } else if (type === 'separator') {
                data.push({
                    id: '_',
                    type: type
                });
            }
        }
    }

    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');

        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));
