/*
 * 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, $loc, wss;

    var t2is, t2rs, t2ls, t2vs, t2bcs, t2ss, t2bgs, t2tbs;
    var svg, forceG, uplink, dim, opts, zoomer;

    // D3 Selections
    var node;

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

    function init(_svg_, _forceG_, _uplink_, _dim_, _zoomer_, _opts_) {

        svg = _svg_;
        uplink = _uplink_;
        dim = _dim_;
        zoomer = _zoomer_;
        opts = _opts_;


        t2bgs.init();
        t2bgs.region = t2rs;
        t2ls.init(svg, uplink, dim, zoomer, opts);
        t2bcs.addLayout(t2ls);
        t2ss.init(svg, zoomer);
        t2ss.region = t2rs;
        t2rs.layout = t2ls;
        t2tbs.init();
        navToBookmarkedRegion($loc.search().regionId);
    }

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

    function navToBookmarkedRegion(regionId) {
        $log.debug('navToBookmarkedRegion:', regionId);
        if (regionId) {
            wss.sendEvent('topo2navRegion', {
                rid: regionId
            });

            t2ls.createForceElements();
            t2ls.transitionDownRegion();
        }
    }

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

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

    function currentLayout(data) {
        $log.debug('>> topo2CurrentLayout event:', data);
        t2rs.clear();
        t2bcs.addBreadcrumb(data.crumbs);
        t2bgs.addLayout(data);
    }

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

    function topo2PeerRegions(data) {
        $log.debug('>> topo2PeerRegions event:', data);
        t2rs.loaded('peers', data.peers);
    }

    function modelEvent(data) {
        // $log.debug('>> topo2UiModelEvent event:', data);

        // TODO: Interpret the event and update our topo model state (if needed)
        // To Decide: Can we assume that the server will only send events
        //    related to objects that we are currently showing?
        //    (e.g. filtered by subregion contents?)
        t2rs.update(data);
    }

    function showMastership(masterId) {
        if (masterId) {
            showMastershipFor(masterId);
        } else {
            restoreLayerState();
        }
    }

    function restoreLayerState() {
        // NOTE: this level of indirection required, for when we have
        //          the layer filter functionality re-implemented
        suppressLayers(false);
    }

    // ========================== Main Service Definition

    function showMastershipFor(id) {
        suppressLayers(true);
        node.each(function (n) {
            if (n.master === id) {
                n.el.classed('suppressedmax', false);
            }
        });
    }

    function supAmt(less) {
        return less ? 'suppressed' : 'suppressedmax';
    }

    function suppressLayers(b, less) {
        var cls = supAmt(less);
        node.classed(cls, b);
        // link.classed(cls, b);
    }

    function newDim(_dim_) {
        dim = _dim_;
        t2vs.newDim(dim);
    }

    // ========================== Main Service Definition

    function update(elements) {
        angular.forEach(elements, function (el) {
            el.update();
        });
    }

    function updateNodes() {
        update(t2rs.regionNodes());
    }

    function updateLinks() {
        update(t2rs.regionLinks());
    }

    function resetNodeLocation() {

        var hovered = t2rs.filterRegionNodes(function (model) {
            return model.get('hovered');
        });

        angular.forEach(hovered, function (model) {
            model.resetPosition();
        });
    }

    function unpin() {

        var hovered = t2rs.filterRegionNodes(function (model) {
            return model.get('hovered');
        });

        angular.forEach(hovered, function (model) {
            model.fix(false);
        });

        t2ls.start();
    }

    angular.module('ovTopo2')
    .factory('Topo2ForceService', [
        '$log', '$location', 'WebSocketService', 'Topo2InstanceService',
        'Topo2RegionService', 'Topo2LayoutService', 'Topo2ViewService',
        'Topo2BreadcrumbService', 'Topo2ZoomService', 'Topo2SelectService',
        'Topo2BackgroundService', 'Topo2ToolbarService',
        function (_$log_, _$loc_, _wss_, _t2is_, _t2rs_, _t2ls_,
            _t2vs_, _t2bcs_, zoomService, _t2ss_, _t2bgs_, _t2tbs_) {

            $log = _$log_;
            $loc = _$loc_;
            wss = _wss_;
            t2is = _t2is_;
            t2rs = _t2rs_;
            t2ls = _t2ls_;
            t2vs = _t2vs_;
            t2bcs = _t2bcs_;
            t2ss = _t2ss_;
            t2bgs = _t2bgs_;
            t2tbs = _t2tbs_;

            var onZoom = function () {
                if (!t2rs.isLoadComplete()) {
                    return;
                }

                var nodes = [].concat(
                        t2rs.regionNodes(),
                        t2rs.regionLinks()
                    );

                angular.forEach(nodes, function (node) {
                    node.setScale();
                });
            };

            zoomService.addZoomEventListener(onZoom);

            return {

                init: init,
                newDim: newDim,

                destroy: destroy,
                topo2AllInstances: allInstances,
                topo2CurrentLayout: currentLayout,
                topo2CurrentRegion: currentRegion,

                topo2UiModelEvent: modelEvent,

                showMastership: showMastership,
                topo2PeerRegions: topo2PeerRegions,

                updateNodes: updateNodes,
                updateLinks: updateLinks,
                resetNodeLocation: resetNodeLocation,
                unpin: unpin
            };
        }]);
})();
