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

 Provides a mechanism to display key bindings and mouse gesture notes.
 */
(function () {
    'use strict';

    // injected references
    var $log, fs, sus;

    // configuration
    var defaultSettings = {
            fade: 500
        },
        w = '100%',
        h = '80%',
        vbox = '-200 0 400 400',
        pad = 10,
        offy = 45,
        sepYDelta = 20,
        colXDelta = 16,
        yTextSpc = 12,
        offDesc = 8;

    // internal state
    var settings,
        data = [],
        yCount;

    // DOM elements
    var qhdiv, svg, pane, rect, items;

    // key-logical-name to key-display lookup..
    var keyDisp = {
        equals: '=',
        slash: '/',
        backSlash: '\\',
        backQuote: '`',
        leftArrow: 'L-arrow',
        upArrow: 'U-arrow',
        rightArrow: 'R-arrow',
        downArrow: 'D-arrow'
    };

    // ===========================================
    // === Function Definitions ===

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

    function addSeparator(el, i) {
        var y = sepYDelta/2 - 5;
        el.append('line')
            .attr({ 'class': 'qhrowsep', x1: 0, y1: y, x2: 0, y2: y });
    }

    function addContent(el, data, ri) {
        var xCount = 0,
            clsPfx = 'qh-r' + ri + '-c';

        function addColumn(el, c, i) {
            var cls = clsPfx + i,
                oy = 0,
                aggKey = el.append('g').attr('visibility', 'hidden'),
                gcol = el.append('g').attr({
                    'class': cls,
                    transform: sus.translate(xCount, 0)
                });

            c.forEach(function (j) {
                var k = j[0],
                    v = j[1];

                if (k !== '-') {
                    aggKey.append('text').text(k);

                    gcol.append('text').text(k)
                        .attr({
                            'class': 'key',
                            y: oy
                        });
                    gcol.append('text').text(v)
                        .attr({
                            'class': 'desc',
                            y: oy
                        });
                }

                oy += yTextSpc;
            });

            // adjust position of descriptions, based on widest key
            var kbox = aggKey.node().getBBox(),
                ox = kbox.width + offDesc;
            gcol.selectAll('.desc').attr('x', ox);
            aggKey.remove();

            // now update x-offset for next column
            var bbox = gcol.node().getBBox();
            xCount += bbox.width + colXDelta;
        }

        data.forEach(function (d, i) {
            addColumn(el, d, i);
        });

        // finally, return the height of the row..
        return el.node().getBBox().height;
    }

    function updateKeyItems() {
        var rows = items.selectAll('.qhRow').data(data);

        yCount = offy;

        var entering = rows.enter()
            .append('g')
            .attr({
                'class': 'qhrow'
            });

        entering.each(function (r, i) {
            var el = d3.select(this),
                sep = r.type === 'sep',
                dy;

            el.attr('transform', sus.translate(0, yCount));

            if (sep) {
                addSeparator(el, i);
                yCount += sepYDelta;
            } else {
                dy = addContent(el, r.data, i);
                yCount += dy;
            }
        });

        // size the backing rectangle
        var ibox = items.node().getBBox(),
            paneW = ibox.width + pad * 2,
            paneH = ibox.height + offy;

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

    }

    function checkFmt(fmt) {
        // should be a single array of keys,
        // or array of arrays of keys (one per column).
        // return null if there is a problem.
        var a = fs.isA(fmt),
            n = a && a.length,
            ns = 0,
            na = 0;

        if (n) {
            // it is an array which has some content
            a.forEach(function (d) {
                fs.isA(d) && na++;
                fs.isS(d) && ns++;
            });
            if (na === n || ns === n) {
                // all arrays or all strings...
                return a;
            }
        }
        return null;
    }

    function buildBlock(map, fmt) {
        var b = [];
        fmt.forEach(function (k) {
            var v = map.get(k),
                a = fs.isA(v),
                d = (a && a[1]);

            // '-' marks a separator; d is the description
            if (k === '-' || d) {
                b.push([mkKeyDisp(k), d]);
            }
        });
        return b;
    }

    function emptyRow() {
        return { type: 'row', data: [] };
    }

    function mkArrRow(fmt) {
        var d = emptyRow();
        d.data.push(fmt);
        return d;
    }

    function mkColumnarRow(map, fmt) {
        var d = emptyRow();
        fmt.forEach(function (a) {
            d.data.push(buildBlock(map, a));
        });
        return d;
    }

    function mkMapRow(map, fmt) {
        var d = emptyRow();
        d.data.push(buildBlock(map, fmt));
        return d;
    }

    function addRow(row) {
        var d = row || { type: 'sep' };
        data.push(d);
    }

    function aggregateData(bindings) {
        var hf = '_helpFormat',
            gmap = d3.map(bindings.globalKeys),
            gfmt = bindings.globalFormat,
            vmap = d3.map(bindings.viewKeys),
            vgest = bindings.viewGestures,
            vfmt, vkeys;

        // filter out help format entry
        vfmt = checkFmt(vmap.get(hf));
        vmap.remove(hf);

        // if bad (or no) format, fallback to sorted keys
        if (!vfmt) {
            vkeys = vmap.keys();
            vfmt = vkeys.sort();
        }

        data = [];

        addRow(mkMapRow(gmap, gfmt));
        addRow();
        addRow(fs.isA(vfmt[0]) ? mkColumnarRow(vmap, vfmt) : mkMapRow(vmap, vfmt));
        addRow();
        addRow(mkArrRow(vgest));
    }


    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: sus.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(settings.fade)
            .attr('opacity', o);
    }

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

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


    // ===========================================
    // === Module Definition ===

    angular.module('onosLayer')
    .factory('QuickHelpService',
        ['$log', 'FnService', 'SvgUtilService',

        function (_$log_, _fs_, _sus_) {
            $log = _$log_;
            fs = _fs_;
            sus = _sus_;

            function initQuickHelp(opts) {
                settings = angular.extend({}, defaultSettings, opts);
                qhdiv = d3.select('#quickhelp');
            }

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

            return {
                initQuickHelp: initQuickHelp,
                showQuickHelp: showQuickHelp,
                hideQuickHelp: hideQuickHelp
            };
        }]);

}());
