/*
 * 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 Force Module.
 Visualization of the topology in an SVG layer, using a D3 Force Layout.
 */

(function () {
    'use strict';

    // injected refs
    var $log, wss;

    // selected DOM refs
    var topdiv;

    // ========================== Helper Functions

    function init() {
        topdiv = d3.select('#topoXtmp');
        $log.debug('Initialize topo force layout');
    }

    function destroy() {
        $log.debug('Destroy topo force layout');
    }

    function rmP(div) {
        div.selectAll('p').remove();
    }

    function navRequest(rid) {
        wss.sendEvent('topo2navRegion', {
            rid: rid
        });
    }

    function doTmpInstances(data) {
        var idiv = topdiv.select('.instances').select('div');
        data.members.forEach(function (m) {
            idiv.append('div').text(m.id);
        });
    }

    function doTmpCurrentLayout(data) {
        var ldDiv = topdiv.select('.layoutData'),
            bcs = ldDiv.select('.l_crumbs');

        function setSpan(v, val) {
            var cls = '.l_' + v,
                span = ldDiv.select(cls).select('span'),
                value = val || data[v];
            span.html(value);
        }

        setSpan('id');
        setSpan('parent');
        setSpan('region');
        setSpan('regionName');

        addCrumbNav(bcs, data.crumbs, data.region);
    }

    function addCrumbNav(span, array, id) {
        var rev = [];

        span.selectAll('span').remove();

        array.forEach(function (a) {
            rev.unshift(a.id);
        });

        rev.forEach(function (rid, idx) {
            if (idx) {
                span.append('span').text(' +++ ');
            }
            if (rid != id) {
                addNavigable(span, 'span', rid);
            } else {
                span.append('span').text(rid);
            }
        });
    }

    function addNavigable(span, what, rid) {
        span.append(what).classed('nav-me', true)
            .text(rid)
            .on('click', function () { navRequest(rid); });
    }

    function doTmpCurrentRegion(data) {
        var span = topdiv.select('.thisRegion').select('span');
        var div;
        span.text(data.id);

        div = topdiv.select('.subRegions').select('div');
        rmP(div);
        data.subregions.forEach(function (r) {
            addNavigable(div, 'p', r.id);
        });

        div = topdiv.select('.devices').select('div');
        rmP(div);
        data.layerOrder.forEach(function (tag, idx) {
            var devs = data.devices[idx];
            devs.forEach(function (d) {
                div.append('p')
                    .text('[' + tag + '] ' + d.id);
            });

        });

        div = topdiv.select('.hosts').select('div');
        rmP(div);
        data.layerOrder.forEach(function (tag, idx) {
            var hosts = data.hosts[idx];
            hosts.forEach(function (h) {
                div.append('p')
                    .text('[' + tag + '] ' + h.id);
            });
        });

        div = topdiv.select('.links').select('div');
        rmP(div);
        data.links.forEach(function (lnk) {
            div.append('p')
                .text(lnk.id);
        });
    }

    function doTmpPeerRegions(data) {

    }

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

    function allInstances(data) {
        $log.debug('>> topo2AllInstances event:', data);
        doTmpInstances(data);
    }

    function currentLayout(data) {
        $log.debug('>> topo2CurrentLayout event:', data);
        doTmpCurrentLayout(data);
    }

    function currentRegion(data) {
        $log.debug('>> topo2CurrentRegion event:', data);
        doTmpCurrentRegion(data);
    }

    function peerRegions(data) {
        $log.debug('>> topo2PeerRegions event:', data);
        doTmpPeerRegions(data);
    }

    function startDone(data) {
        $log.debug('>> topo2StartDone event:', data);
    }
    
    // ========================== Main Service Definition

    angular.module('ovTopoX')
    .factory('TopoXForceService',
        ['$log', 'WebSocketService',

        function (_$log_, _wss_) {
            $log = _$log_;
            wss = _wss_;
            
            return {
                init: init,
                destroy: destroy,
                topo2AllInstances: allInstances,
                topo2CurrentLayout: currentLayout,
                topo2CurrentRegion: currentRegion,
                topo2PeerRegions: peerRegions,
                topo2StartDone: startDone
            };
        }]);
}());
