/*
 * 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 layer filtering Module.
 Provides functionality to visually differentiate between the packet and
 optical layers of the topology.
 */

(function () {
    'use strict';

    // injected refs
    var $log, fs, flash, tps, tts;

    // api to topoForce
    var api;
    /*
     node()     // get ref to D3 selection of nodes
     link()     // get ref to D3 selection of links
     */

    var smax = 'suppressedmax';

    // which "layer" a particular item "belongs to"
    var layerLookup = {
            host: {
                endstation: 'pkt', // default, if host event does not define type
                router:     'pkt',
                bgpSpeaker: 'pkt'
            },
            device: {
                switch: 'pkt',
                roadm: 'opt'
            },
            link: {
                hostLink: 'pkt',
                direct: 'pkt',
                indirect: '',
                tunnel: '',
                optical: 'opt'
            }
        },
        // order of layer cycling in button
        dispatch = [
            {
                type: 'all',
                action: function () { suppressLayers(false); },
                msg: 'All Layers Shown'
            },
            {
                type: 'pkt',
                action: function () { showLayer('pkt'); },
                msg: 'Packet Layer Shown'
            },
            {
                type: 'opt',
                action: function () { showLayer('opt'); },
                msg: 'Optical Layer Shown'
            }
        ],
        layer = 0;

    function clickAction() {
        layer = (layer + 1) % dispatch.length;
        dispatch[layer].action();
        flash.flash(dispatch[layer].msg);
    }

    function selected() {
        return dispatch[layer].type;
    }

    function inLayer(d, layer) {
        var type = d.class === 'link' ? d.type() : d.type,
            look = layerLookup[d.class],
            lyr = look && look[type];
        return lyr === layer;
    }

    function unsuppressLayer(which) {
        api.node().each(function (d) {
            var node = d.el;
            if (inLayer(d, which)) {
                node.classed(smax, false);
            }
        });

        api.link().each(function (d) {
            var link = d.el;
            if (inLayer(d, which)) {
                link.classed(smax, false);
            }
        });
    }

    function suppressLayers(b) {
        api.node().classed(smax, b);
        api.link().classed(smax, b);
    }

    function showLayer(which) {
        suppressLayers(true);
        unsuppressLayer(which);
    }

    // === -----------------------------------------------------
    // === MODULE DEFINITION ===

    angular.module('ovTopo')
        .factory('TopoFilterService',
        ['$log', 'FnService',
            'FlashService',
            'TopoPanelService',
            'TopoTrafficService',

            function (_$log_, _fs_, _flash_, _tps_, _tts_) {
                $log = _$log_;
                fs = _fs_;
                flash = _flash_;
                tps = _tps_;
                tts = _tts_;

                function initFilter(_api_) {
                    api = _api_;
                }

                return {
                    initFilter: initFilter,

                    clickAction: clickAction,
                    selected: selected,
                    inLayer: inLayer
                };
            }]);
}());
