/*
 * Copyright 2016-present 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 -- Topology View Module.
 Module that displays the details panel for selected nodes
 */

(function () {
    'use strict';

    // Injected Services
    var panel, gs, wss, flash, bs, fs, ns, ls;

    // Internal State
    var detailsPanel;

    // configuration
    var id = 'topo2-p-detail',
        devicePath = 'device',
        handlerMap = {
            'showDetails': showDetails
        };

    var coreButtons = {
        showDeviceView: {
            gid: 'switch',
            tt: 'Show Device View',
            path: 'device'
        },
        showFlowView: {
            gid: 'flowTable',
            tt: 'Show Flow View for this Device',
            path: 'flow'
        },
        showPortView: {
            gid: 'portTable',
            tt: 'Show Port View for this Device',
            path: 'port'
        },
        showGroupView: {
            gid: 'groupTable',
            tt: 'Show Group View for this Device',
            path: 'group'
        },
        showMeterView: {
            gid: 'meterTable',
            tt: 'Show Meter View for this Device',
            path: 'meter'
        }
    };

    function init(summaryPanel) {

        bindHandlers();
        detailsPanel = panel(summaryPanel);
    }

    function addBtnFooter() {
        detailsPanel.appendToFooter('hr');
        detailsPanel.appendToFooter('div').classed('actionBtns', true);
    }

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

    function installButtons(buttons, data, devId) {
        buttons.forEach(function (id) {
            var btn = coreButtons[id],
                gid = btn && btn.gid,
                tt = btn && btn.tt,
                path = btn && btn.path;

            if (btn) {
                addAction({
                    id: 'core-' + id,
                    gid: gid,
                    tt: tt,
                    cb: function () { ns.navTo(path, { devId: devId }); }
                });
            }
        });
    }

    function renderSingle(data) {

        detailsPanel.emptyRegions();

        var navFn = function () {
            ns.navTo(devicePath, { devId: data.id });
        };

        var svg = detailsPanel.appendToHeader('div')
                .classed('icon clickable', true)
                .append('svg'),
            title = detailsPanel.appendToHeader('h2')
                .on('click', navFn)
                .classed('clickable', true),
            table = detailsPanel.appendToBody('table'),
            tbody = table.append('tbody');

        gs.addGlyph(svg, (data.type || 'unknown'), 26);
        title.text(data.title);

        if (!data.props.Latitude) {
            var locationIndex = data.propOrder.indexOf('Latitude');
            data.propOrder.splice(locationIndex - 1, 3);
        }

        ls.listProps(tbody, data);
        addBtnFooter();
    }

    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 renderMulti(nodes) {
        detailsPanel.emptyRegions();

        var title = detailsPanel.appendToHeader('h3'),
            table = detailsPanel.appendToBody('table'),
            tbody = table.append('tbody');

        title.text('Selected Items');
        nodes.forEach(function (n, i) {
            addProp(tbody, i + 1, n.get('id'));
        });

        // addBtnFooter();
        show();
    }

    function bindHandlers() {
        wss.bindHandlers(handlerMap);
    }

    function updateDetails(id, nodeType) {
        wss.sendEvent('requestDetails', {
            id: id,
            class: nodeType
        });
    }

    function showDetails(data) {
        var buttons = fs.isA(data.buttons) || [];
        renderSingle(data);
        installButtons(buttons, data, data.id);
    }

    function toggle() {
        var on = detailsPanel.el.toggle(),
            verb = on ? 'Show' : 'Hide';
        flash.flash(verb + ' Details Panel');
    }

    function show() {
        detailsPanel.show();
    }

    function hide() {
        detailsPanel.el.hide();
    }

    function destroy() {
        wss.unbindHandlers(handlerMap);
        detailsPanel.destroy();
    }

    angular.module('ovTopo2')
    .factory('Topo2DeviceDetailsPanel', [
        'Topo2DetailsPanelService', 'GlyphService', 'WebSocketService', 'FlashService',
        'ButtonService', 'FnService', 'NavService', 'ListService',

        function (_ps_, _gs_, _wss_, _flash_, _bs_, _fs_, _ns_, _ls_) {

            panel = _ps_;
            gs = _gs_;
            wss = _wss_;
            flash = _flash_;
            bs = _bs_;
            fs = _fs_;
            ns = _ns_;
            ls = _ls_;

            return {
                init: init,
                updateDetails: updateDetails,
                showMulti: renderMulti,

                toggle: toggle,
                show: show,
                hide: hide,
                destroy: destroy,
                isVisible: function () { return detailsPanel.isVisible(); },
                getInstance: function () { return detailsPanel; }
            };
        }
    ]);
})();
