/*
* 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 (2) View Module

 NOTE: currently under development to support Regions.
 */

(function () {
    'use strict';

    // references to injected services
    var $scope, $log, fs, mast, ks, wss,
        gs, sus, ps, t2es, t2fs, t2is, t2bcs, t2kcs, t2ms, t2mcs, t2zs;

    // DOM elements
    var ovtopo2, svg, defs, zoomLayer, forceG;

    // Internal state
    var zoomer,
        currentLayoutId = 'root';  // NOTE: see UiTopoLayoutId.DEFAULT_STR


    // --- Glyphs, Icons, and the like -----------------------------------

    function setUpDefs() {
        defs = svg.append('defs');
        gs.loadDefs(defs);

        // TODO: consider using something other than the "glow" styles
        sus.loadGlowDefs(defs);
    }

    // callback invoked when the SVG view has been resized..
    function svgResized(s) {
        $log.debug('topo2 view resized', s);
        t2fs.newDim([s.width, s.height]);
    }

    function setUpKeys(overlayKeys) {
        $log.debug('topo2: set up keys....');
    }

    // --- Pan and Zoom --------------------------------------------------

    // zoom enabled predicate. ev is a D3 source event.
    function zoomEnabled(ev) {
        return fs.isMobile() || (ev.metaKey || ev.altKey);
    }

    function zoomCallback() {
        var sc = zoomer.scale(),
            tr = zoomer.translate(),
            metaUi = isNaN(sc) ? {
                useCfg: 1
            } : {
                scale: sc,
                offsetX: tr[0],
                offsetY: tr[1]
            };

        // Allow map service to react to change in zoom parameters
        t2ms.zoomCallback(sc, tr);

        // Note: Meta data stored in the context of the current layout,
        //       automatically, by the server

        wss.sendEvent('updateMeta2', {
            id: 'layoutZoom',
            memento: metaUi
        });
    }

    function setUpZoom() {
        zoomLayer = svg.append('g').attr('id', 'topo2-zoomlayer');

        zoomer = t2zs.createZoomer({
            svg: svg,
            zoomLayer: zoomLayer,
            zoomEnabled: zoomEnabled,
            zoomCallback: zoomCallback
        });
    }

    // === Controller Definition -----------------------------------------

    angular.module('ovTopo2', ['onosUtil', 'onosSvg', 'onosRemote'])
    .controller('OvTopo2Ctrl', [
        '$scope', '$log', '$location',
        'FnService', 'MastService', 'KeyService', 'GlyphService', 'MapService',
        'SvgUtilService', 'FlashService', 'WebSocketService',
        'PrefsService', 'ThemeService',
        'Topo2EventService', 'Topo2ForceService', 'Topo2InstanceService',
        'Topo2BreadcrumbService', 'Topo2KeyCommandService', 'Topo2MapService',
        'Topo2MapConfigService', 'Topo2ZoomService', 'Topo2SpriteLayerService',
        'Topo2SummaryPanelService', 'Topo2DeviceDetailsPanel', 'Topo2ToolbarService',

        function (
            _$scope_, _$log_, _$loc_,
            _fs_, _mast_, _ks_, _gs_, _ms_,
            _sus_, _flash_, _wss_,
            _ps_, _th_,
            _t2es_, _t2fs_, _t2is_,
            _t2bcs_, _t2kcs_, _t2ms_,
            _t2mcs_, _t2zs_, t2sls,
            summaryPanel, detailsPanel, t2tbs
        ) {
            var params = _$loc_.search(),
                dim,
                wh,
                uplink = {
                    // provides function calls back into this space
                    // showNoDevs: showNoDevs,
                    // projection: function () { return projection; },
                    zoomLayer: function () { return zoomLayer; },
                    zoomer: function () { return zoomer; }
                    // opacifyMap: opacifyMap,
                };

            $scope = _$scope_;
            $log = _$log_;

            fs = _fs_;
            mast = _mast_;
            ks = _ks_;
            wss = _wss_;
            gs = _gs_;
            sus = _sus_;
            ps = _ps_;

            t2es = _t2es_;
            t2fs = _t2fs_;
            t2is = _t2is_;
            t2bcs = _t2bcs_;
            t2kcs = _t2kcs_;
            t2ms = _t2ms_;
            t2mcs = _t2mcs_;
            t2zs = _t2zs_;

            // capture selected intent parameters (if they are set in the
            //  query string) so that the traffic overlay can highlight
            //  the path for that intent
            if (params.intentKey &&
                params.intentAppId &&
                params.intentAppName) {

                $scope.intentData = {
                    key: params.intentKey,
                    appId: params.intentAppId,
                    appName: params.intentAppName,
                    intentType: params.intentType
                };
            }

            $scope.notifyResize = function () {
                svgResized(fs.windowSize(mast.mastHeight()));
            };

            // Cleanup on destroyed scope..
            $scope.$on('$destroy', function () {
                $log.log('OvTopo2Ctrl is saying Buh-Bye!');
                t2es.stop();
                ks.unbindKeys();
                t2fs.destroy();
                t2is.destroy();
                summaryPanel.destroy();
                detailsPanel.destroy();
            });

            // svg layer and initialization of components
            ovtopo2 = d3.select('#ov-topo2');
            svg = ovtopo2.select('svg');
            // set the svg size to match that of the window, less the masthead
            wh = fs.windowSize(mast.mastHeight());
            $log.debug('setting topo SVG size to', wh);
            svg.attr(wh);
            dim = [wh.width, wh.height];

            // set up our keyboard shortcut bindings
            setUpKeys();
            setUpZoom();
            setUpDefs();

            // make sure we can respond to topology events from the server
            t2es.bindHandlers();

            t2bcs.init();
            t2kcs.init(t2fs, t2tbs);
            t2is.initInst({ showMastership: t2fs.showMastership });
            t2fs.init(svg, forceG, uplink, dim, zoomer);

            // === ORIGINAL CODE ===

            // setUpToolbar();
            // setUpNoDevs();

            // tes.bindHandlers();
            // setUpSprites();

            // forceG = zoomLayer.append('g').attr('id', 'topo-force');
            // tfs.initForce(svg, forceG, uplink, dim);
            // tis.initInst({ showMastership: tfs.showMastership });
            // tps.initPanels();

            // restoreConfigFromPrefs();
            // ttbs.setDefaultOverlay(prefsState.ovid);

            // $log.debug('registered overlays...', tov.list());

            summaryPanel.init();
            detailsPanel.init();

            // Now that we are initialized, ask the server for what we
            //  need to show.
            t2es.start();

            $log.log('OvTopo2Ctrl has been created');
        }]);
})();
