/*
 * 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 -- Topology Instances Module.
 Defines modeling of ONOS instances.
 */

(function () {
    'use strict';

    // injected refs
    var $log, ps, sus, gs;

    // configuration
    var instCfg = {
            rectPad: 8,
            nodeOx: 9,
            nodeOy: 9,
            nodeDim: 40,
            birdOx: 19,
            birdOy: 21,
            birdDim: 21,
            uiDy: 45,
            titleDy: 30,
            textYOff: 20,
            textYSpc: 15
        },
        showLogicErrors = true,
        idIns = 'topo-p-instance',
        instOpts = {
            edge: 'left',
            width: 20
        };

    // internal state
    var onosInstances,
        onosOrder,
        oiShowMaster,
        oiBox;


    // ==========================
    // *** ADD INSTANCE ***

    function addInstance(data) {
        var id = data.id;

        if (onosInstances[id]) {
            updateInstance(data);
            return;
        }
        onosInstances[id] = data;
        onosOrder.push(data);
        updateInstances();
    }

    function updateInstance(data) {
        var id = data.id,
            d = onosInstances[id];
        if (d) {
            angular.extend(d, data);
            updateInstances();
        } else {
            logicError('updateInstance: lookup fail: ID = "' + id + '"');
        }
    }

    function computeDim(self) {
        var css = window.getComputedStyle(self);
        return {
            w: sus.stripPx(css.width),
            h: sus.stripPx(css.height)
        };
    }

    function clickInst(d) {
        var el = d3.select(this),
            aff = el.classed('affinity');
        if (!aff) {
            setAffinity(el, d);
        } else {
            cancelAffinity();
        }
    }

    function setAffinity(el, d) {
        d3.selectAll('.onosInst')
            .classed('mastership', true)
            .classed('affinity', false);
        el.classed('affinity', true);

        // TODO: suppress the layers and highlight only specific nodes...
        //suppressLayers(true);
        //node.each(function (n) {
        //    if (n.master === d.id) {
        //        n.el.classed('suppressed', false);
        //    }
        //});
        oiShowMaster = true;
    }

    function cancelAffinity() {
        d3.selectAll('.onosInst')
            .classed('mastership affinity', false);

        // TODO: restore layer state
        //restoreLayerState();
        oiShowMaster = false;
    }

    function instRectAttr(dim) {
        var pad = instCfg.rectPad;
        return {
            x: pad,
            y: pad,
            width: dim.w - pad*2,
            height: dim.h - pad*2,
            rx: 6
        };
    }

    function viewBox(dim) {
        return '0 0 ' + dim.w + ' ' + dim.h;
    }

    function attachUiBadge(svg) {
        gs.addGlyph(svg, 'uiAttached', 30, true, [12, instCfg.uiDy])
            .classed('badgeIcon uiBadge', true);
    }

    function instColor(id, online) {
        // TODO: fix this..
        //return cat7.get(id, !online, network.view.getTheme());
        return '#3E5780';
    }

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

    function updateInstances() {
        var onoses = oiBox.el().selectAll('.onosInst')
                .data(onosOrder, function (d) { return d.id; }),
            instDim = {w:0,h:0},
            c = instCfg;

        function nSw(n) {
            return '# Switches: ' + n;
        }

        // operate on existing onos instances if necessary
        onoses.each(function (d) {
            var el = d3.select(this),
                svg = el.select('svg');
            instDim = computeDim(this);

            // update online state
            el.classed('online', d.online);

            // update ui-attached state
            svg.select('use.uiBadge').remove();
            if (d.uiAttached) {
                attachUiBadge(svg);
            }

            function updAttr(id, value) {
                svg.select('text.instLabel.'+id).text(value);
            }

            updAttr('ip', d.ip);
            updAttr('ns', nSw(d.switches));
        });


        // operate on new onos instances
        var entering = onoses.enter()
            .append('div')
            .attr('class', 'onosInst')
            .classed('online', function (d) { return d.online; })
            .on('click', clickInst);

        entering.each(function (d) {
            var el = d3.select(this),
                rectAttr,
                svg;
            instDim = computeDim(this);
            rectAttr = instRectAttr(instDim);

            svg = el.append('svg').attr({
                width: instDim.w,
                height: instDim.h,
                viewBox: viewBox(instDim)
            });

            svg.append('rect').attr(rectAttr);

            gs.addGlyph(svg, 'bird', 28, true, [14, 14])
                .classed('badgeIcon', true);

            if (d.uiAttached) {
                attachUiBadge(svg);
            }

            var left = c.nodeOx + c.nodeDim,
                len = rectAttr.width - left,
                hlen = len / 2,
                midline = hlen + left;

            // title
            svg.append('text')
                .attr({
                    class: 'instTitle',
                    x: midline,
                    y: c.titleDy
                })
                .text(d.id);

            // a couple of attributes
            var ty = c.titleDy + c.textYOff;

            function addAttr(id, label) {
                svg.append('text').attr({
                    class: 'instLabel ' + id,
                    x: midline,
                    y: ty
                }).text(label);
                ty += c.textYSpc;
            }

            addAttr('ip', d.ip);
            addAttr('ns', nSw(d.switches));
        });

        // operate on existing + new onoses here
        // set the affinity colors...
        onoses.each(function (d) {
            var el = d3.select(this),
                rect = el.select('svg').select('rect'),
                col = instColor(d.id, d.online);
            rect.style('fill', col);
        });

        // adjust the panel size appropriately...
        oiBox.width(instDim.w * onosOrder.length);
        oiBox.height(instDim.h);

        // remove any outgoing instances
        onoses.exit().remove();
    }


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

    function logicError(msg) {
        if (showLogicErrors) {
            $log.warn('TopoInstService: ' + msg);
        }
    }

    function initInst() {
        oiBox = ps.createPanel(idIns, instOpts);
        oiBox.show();

        onosInstances = {};
        onosOrder = [];
        oiShowMaster = false;
    }

    function destroyInst() {
        ps.destroyPanel(idIns);
        oiBox = null;
    }

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

    angular.module('ovTopo')
    .factory('TopoInstService',
        ['$log', 'PanelService', 'SvgUtilService', 'GlyphService',

        function (_$log_, _ps_, _sus_, _gs_) {
            $log = _$log_;
            ps = _ps_;
            sus = _sus_;
            gs = _gs_;

            return {
                initInst: initInst,
                destroyInst: destroyInst,
                addInstance: addInstance
            };
        }]);
}());
