/*
 * 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: '=',
        dash: '-',
        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
            };
        }]);

}());
