/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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 Panel Module.
 Defines functions for manipulating the summary, detail, and instance panels.
 */

(function () {
    'use strict';

    // injected refs
    var $log, $window, $rootScope, fs, ps, gs, flash, wss, bns, mast, ns;

    // function to be replaced by the localization bundle function
    var topoLion = function (x) {
        return '#tps#' + x + '#';
    };

    // constants
    var pCls = 'topo-p',
        idSum = 'topo-p-summary',
        idDet = 'topo-p-detail',
        panelOpts = {
            width: 260, // summary and detail panel width
        },
        sumMax = 226, // summary panel max height
        padTop = 16, // summary panel padding below masthead
        padding = 16, // panel internal padding
        padFudge = padTop + 2 * padding;

    // internal state
    var useDetails = true, // should we show details if we have 'em?
        haveDetails = false, // do we have details that we could show?
        sumFromTop, // summary panel distance from top of screen
        unbindWatch;

    // panels
    var summary, detail;

    // === -----------------------------------------------------
    // Panel API
    function createTopoPanel(id, opts) {
        var p = ps.createPanel(id, opts),
            pid = id,
            header, body, footer;
        p.classed(pCls, true);

        function panel() {
            return p;
        }

        function hAppend(x) {
            return header.append(x);
        }

        function bAppend(x) {
            return body.append(x);
        }

        function fAppend(x) {
            return footer.append(x);
        }

        function setup() {
            p.empty();

            p.append('div').classed('header', true);
            p.append('div').classed('body', true);
            p.append('div').classed('footer', true);

            header = p.el().select('.header');
            body = p.el().select('.body');
            footer = p.el().select('.footer');
        }

        function destroy() {
            ps.destroyPanel(pid);
        }

        // fromTop is how many pixels from the top of the page the panel is
        // max is the max height of the panel in pixels
        //    only adjusts if the body content would be 10px or larger
        function adjustHeight(fromTop, max) {
            var totalPHeight, avSpace,
                overflow = 0;

            if (!fromTop) {
                $log.warn('adjustHeight: height from top of page not given');
                return null;
            } else if (!body || !p) {
                // panel contents are not defined
                // this may happen when window is resizing but panel has
                //   been cleared or removed
                return null;
            }

            p.el().style('top', fromTop + 'px');
            p.el().style('height', null);
            body.style('height', null);

            totalPHeight = fromTop + p.height();
            avSpace = fs.windowSize(padFudge).height;

            if (totalPHeight >= avSpace) {
                overflow = totalPHeight - avSpace;
            }

            function _adjustBody(height) {
                if (height < 10) {
                    return false;
                } else {
                    body.style('height', height + 'px');
                }
                return true;
            }

            if (!_adjustBody(fs.noPxStyle(body, 'height') - overflow)) {
                return p.height();
            }

            if (max && p.height() > max) {
                _adjustBody(fs.noPxStyle(body, 'height') - (p.height() - max));
            }
            return p.height();
        }

        return {
            panel: panel,
            setup: setup,
            destroy: destroy,
            appendHeader: hAppend,
            appendBody: bAppend,
            appendFooter: fAppend,
            adjustHeight: adjustHeight,
        };
    }

    // === -----------------------------------------------------
    // Utility functions

    function addSep(tbody) {
        tbody.append('tr').append('td').attr('colspan', 2).append('hr');
    }

    function addBtnFooter(sepAlreadyThere) {
        if (!sepAlreadyThere) {
            detail.appendFooter('hr');
        }
        detail.appendFooter('div').classed('actionBtns', true);
    }

    function addProp(tbody, label, value) {
        var tr = tbody.append('tr'),
            lab;
        if (typeof label === 'string') {
            lab = label.replace(/_/g, ' ');
        } else {
            lab = label;
        }

        function addCell(cls, txt) {
            tr.append('td').attr('class', cls).text(txt);
        }

        addCell('label', lab + ' :');
        addCell('value', value);
    }

    function listProps(tbody, data) {
        var sepLast = false;

        // note: track whether we end with a separator or not...
        data.propOrder.forEach(function (p) {
            if (p === '-') {
                addSep(tbody);
                sepLast = true;
            } else {
                addProp(tbody, data.propLabels[p], data.propValues[p]);
                sepLast = false;
            }
        });
        return sepLast;
    }

    function watchWindow() {
        unbindWatch = $rootScope.$watchCollection(
            function () {
                return {
                    h: $window.innerHeight,
                    w: $window.innerWidth,
                };
            }, function () {
                var h = summary.adjustHeight(sumFromTop, sumMax),
                    ss = summary.panel().isVisible(),
                    dtop = h && ss ? sumFromTop + h + padFudge : 0,
                    dy = dtop || ss ? detail.ypos.current : sumFromTop;
                detail.adjustHeight(dy);
            }
        );
    }

    // === -----------------------------------------------------
    //  Functions for populating the summary panel

    function populateSummary(data) {
        summary.setup();

        var svg = summary.appendHeader('div')
                .classed('icon', true)
                .append('svg'),
            title = summary.appendHeader('h2'),
            table = summary.appendBody('table'),
            tbody = table.append('tbody'),
            glyphId = data.glyphId || 'bird';

        gs.addGlyph(svg, glyphId, 24, 0, [1, 1]);

        title.text(data.title);
        listProps(tbody, data);
    }

    // === -----------------------------------------------------
    //  Functions for populating the detail panel

    var navPathIdKey = {
        device: 'devId',
        host: 'hostId',
    };

    function displaySingle(data) {
        var sepLast;

        detail.setup();

        // TODO: remove
        $log.debug('>> Display Single Item Details', data);

        var svg = detail.appendHeader('div')
                .classed('icon clickable', true)
                .append('svg'),
            title = detail.appendHeader('h2')
                .classed('clickable', true),
            table = detail.appendBody('table'),
            tbody = table.append('tbody'),
            navFn,
            navPath;

        gs.addGlyph(svg, (data.glyphId || 'm_unknown'), 26);
        title.text(data.title);

        // add navigation hot-link if defined
        navPath = data.navPath;
        if (navPath) {
            navFn = function () {
                var arg = {};
                arg[navPathIdKey[navPath]] = data.id;
                ns.navTo(navPath, arg);
            };

            svg.on('click', navFn);
            title.on('click', navFn);
        }

        sepLast = listProps(tbody, data);
        addBtnFooter(sepLast);
    }

    function displayMulti(ids) {
        detail.setup();

        var title = detail.appendHeader('h3'),
            table = detail.appendBody('table'),
            tbody = table.append('tbody');

        title.text(topoLion('title_selected_items'));
        ids.forEach(function (d, i) {
            addProp(tbody, i + 1, d);
        });
        addBtnFooter();
    }

    function addAction(o) {
        var btnDiv = d3.select('#' + idDet)
            .select('.actionBtns')
            .append('div')
            .classed('actionBtn', true);
        bns.button(btnDiv, idDet + '-' + o.id, o.gid, o.cb, o.tt);
    }

    var friendlyIndex = {
        device: 1,
        host: 0,
    };

    function friendly(d) {
        var i = friendlyIndex[d.class] || 0;
        return (d.labels && d.labels[i]) || '';
    }

    function linkSummary(d) {
        var o = d && d.online ? 'online' : 'offline';
        return d ? d.type + ' / ' + o : '-';
    }

    // provided to change presentation of internal type name
    var linkTypePres = {
        hostLink: 'edge link',
    };

    function linkType(d) {
        return linkTypePres[d.type()] || d.type();
    }

    function linkExpected(d) {
        return d.expected();
    }

    // TODO: implement server-side processing of link details
    var coreOrder = [
            'Type', 'Expected', '-',
            'A_type', 'A_id', 'A_label', 'A_port', '-',
            'B_type', 'B_id', 'B_label', 'B_port',
        ],
        edgeOrder = [
            'Type', '-',
            'A_type', 'A_id', 'A_label', '-',
            'B_type', 'B_id', 'B_label', 'B_port',
        ];

    // FIXME: DEPRECATED (no longer called)
    function displayLink(data, modifyCb) {
        detail.setup();

        var svg = detail.appendHeader('div')
                .classed('icon', true)
                .append('svg'),
            title = detail.appendHeader('h2'),
            table = detail.appendBody('table'),
            tbody = table.append('tbody'),
            edgeLink = data.type() === 'hostLink',
            order = edgeLink ? edgeOrder : coreOrder;

        gs.addGlyph(svg, 'ports', 26);
        title.text('Link');

        var linkData = {
            propOrder: order.slice(0), // makes a copy of the array
            props: {
                Type: linkType(data),
                Expected: linkExpected(data),

                A_type: data.source.class,
                A_id: data.source.id,
                A_label: friendly(data.source),
                A_port: data.srcPort,

                B_type: data.target.class,
                B_id: data.target.id,
                B_label: friendly(data.target),
                B_port: data.tgtPort,
            },
        };
        listProps(tbody, modifyCb(linkData, data.extra));

        if (!edgeLink) {
            addSep(tbody);
            addProp(tbody, 'A &rarr; B', linkSummary(data.fromSource));
            addProp(tbody, 'B &rarr; A', linkSummary(data.fromTarget));
        }
    }

    function displayNothing() {
        haveDetails = false;
        hideDetailPanel();
    }

    function displaySomething() {
        haveDetails = true;
        if (useDetails) {
            showDetailPanel();
        }
    }

    // === -----------------------------------------------------
    //  Event Handlers

    function showSummary(data) {
        populateSummary(data);
        showSummaryPanel();
    }

    function toggleSummary(x) {
        var kev = (x === 'keyev'),
            on = kev ? !summary.panel().isVisible() : !!x,
            verb = on ? topoLion('show') : topoLion('hide'),
            sumpan = topoLion('fl_panel_summary');

        if (on) {
            // ask server to start sending summary data.
            wss.sendEvent('requestSummary');
            // note: the summary panel will appear, once data arrives
        } else {
            hideSummaryPanel();
        }
        flash.flash(verb + ' ' + sumpan);
        return on;
    }

    // === -----------------------------------------------------
    // === LOGIC For showing/hiding summary and detail panels...

    function showSummaryPanel() {
        function _show() {
            summary.panel().show();
            summary.adjustHeight(sumFromTop, sumMax);
        }

        if (detail.panel().isVisible()) {
            detail.down(_show);
        } else {
            _show();
        }
    }

    function hideSummaryPanel() {
        // instruct server to stop sending summary data
        wss.sendEvent('cancelSummary');
        summary.panel().hide(detail.up);
    }

    function showDetailPanel() {
        if (summary.panel().isVisible()) {
            detail.down(detail.panel().show);
        } else {
            detail.up(detail.panel().show);
        }
    }

    function hideDetailPanel() {
        detail.panel().hide();
    }

    // ==========================

    function augmentDetailPanel() {
        var d = detail,
            downPos = sumFromTop + sumMax + padFudge;
        d.ypos = { up: sumFromTop, down: downPos, current: downPos };

        d._move = function (y, cb) {
            var yp = d.ypos,
                endCb;

            if (fs.isF(cb)) {
                endCb = function () {
                    cb();
                    d.adjustHeight(d.ypos.current);
                };
            } else {
                endCb = function () {
                    d.adjustHeight(d.ypos.current);
                };
            }
            if (yp.current !== y) {
                yp.current = y;
                d.panel().el().transition().duration(300)
                    .each('end', endCb)
                    .style('top', yp.current + 'px');
            } else {
                endCb();
            }
        };

        d.down = function (cb) { d._move(d.ypos.down, cb); };
        d.up = function (cb) { d._move(d.ypos.up, cb); };
    }

    function toggleUseDetailsFlag(x) {
        var kev = (x === 'keyev'),
            verb;

        useDetails = kev ? !useDetails : !!x;
        verb = useDetails ? 'Enable' : 'Disable'; // TODO: Lion

        if (useDetails) {
            if (haveDetails) {
                showDetailPanel();
            }
        } else {
            hideDetailPanel();
        }
        flash.flash(verb + ' details panel'); // TODO: Lion
        return useDetails;
    }

    // ==========================

    function initPanels() {
        sumFromTop = mast.mastHeight() + padTop;
        summary = createTopoPanel(idSum, panelOpts);
        detail = createTopoPanel(idDet, panelOpts);

        augmentDetailPanel();
        watchWindow();
    }

    function destroyPanels() {
        summary.destroy();
        summary = null;

        detail.destroy();
        detail = null;
        haveDetails = false;
        unbindWatch();
    }

    // ==========================

    angular.module('ovTopo')
    .factory('TopoPanelService',
        ['$log', '$window', '$rootScope', 'FnService', 'PanelService', 'GlyphService',
            'FlashService', 'WebSocketService', 'ButtonService', 'MastService',
            'NavService',

        function (_$log_, _$window_, _$rootScope_,
                  _fs_, _ps_, _gs_, _flash_, _wss_, _bns_, _mast_, _ns_) {
            $log = _$log_;
            $window = _$window_;
            $rootScope = _$rootScope_;
            fs = _fs_;
            ps = _ps_;
            gs = _gs_;
            flash = _flash_;
            wss = _wss_;
            bns = _bns_;
            mast = _mast_;
            ns = _ns_;

            return {
                initPanels: initPanels,
                destroyPanels: destroyPanels,
                createTopoPanel: createTopoPanel,

                showSummary: showSummary,
                toggleSummary: toggleSummary,
                hideSummary: hideSummaryPanel,

                toggleUseDetailsFlag: toggleUseDetailsFlag,
                displaySingle: displaySingle,
                displayMulti: displayMulti,
                displayLink: displayLink,
                displayNothing: displayNothing,
                displaySomething: displaySomething,
                addAction: addAction,

                detailVisible: function () { return detail.panel().isVisible(); },
                summaryVisible: function () { return summary.panel().isVisible(); },

                setLionBundle: function (bundle) { topoLion = bundle; },
            };
        }]);
}());
