/*
 * Copyright 2015-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 -- SVG -- Zoom Service
 */
(function () {
    'use strict';

    // configuration
    var defaultSettings = {
        zoomMin: 0.05,
        zoomMax: 10,
        zoomEnabled: function (ev) { return true; },
        zoomCallback: function () {}
    };

    // injected references to services
    var $log;

    angular.module('onosSvg')
        .factory('ZoomService', ['$log',

        function (_$log_) {
            $log = _$log_;

/*
            NOTE: opts is an object:
            {
                svg: svg,                       D3 selection of <svg> element
                zoomLayer: zoomLayer,           D3 selection of <g> element
                zoomEnabled: function (ev) { ... },
                zoomCallback: function () { ... }
            }

            where:
                * svg and zoomLayer should be D3 selections of DOM elements.
                    * zoomLayer <g> is a child of <svg> element.
                * zoomEnabled is an optional predicate based on D3 event.
                    * default is always enabled.
                * zoomCallback is an optional callback invoked each time we pan/zoom.
                    * default is do nothing.

            Optionally, zoomMin and zoomMax also can be defined.
            These default to 0.25 and 10 respectively.
*/
            function createZoomer(opts) {
                var cz = 'ZoomService.createZoomer(): ',
                    d3s = ' (D3 selection) property defined',
                    settings = angular.extend({}, defaultSettings, opts),
                    zoom = d3.behavior.zoom()
                        .translate([0, 0])
                        .scale(1)
                        .scaleExtent([settings.zoomMin, settings.zoomMax])
                        .on('zoom', zoomed),
                    fail = false,
                    zoomer;


                if (!settings.svg) {
                    $log.error(cz + 'No "svg" (svg tag)' + d3s);
                    fail = true;
                }
                if (!settings.zoomLayer) {
                    $log.error(cz + 'No "zoomLayer" (g tag)' + d3s);
                    fail = true;
                }

                if (fail) {
                    return null;
                }

                // zoom events from mouse gestures...
                function zoomed() {
                    var ev = d3.event.sourceEvent;
                    if (settings.zoomEnabled(ev)) {
                        adjustZoomLayer(d3.event.translate, d3.event.scale);
                    }
                }

                function adjustZoomLayer(translate, scale, transition) {

                    settings.zoomLayer.transition()
                        .duration(transition || 0)
                        .attr("transform",
                            'translate(' + translate + ')scale(' + scale + ')');

                    settings.zoomCallback(translate, scale);
                }

                zoomer = {
                    panZoom: function (translate, scale, transition) {

                        zoom.translate(translate).scale(scale);
                        adjustZoomLayer(translate, scale, transition);
                    },

                    reset: function () {
                        zoomer.panZoom([0,0], 1);
                    },

                    translate: function () {
                        return zoom.translate();
                    },

                    scale: function () {
                        return zoom.scale();
                    },

                    scaleExtent: function () {
                        return zoom.scaleExtent();
                    }
                };

                // apply the zoom behavior to the SVG element
                settings.svg && settings.svg.call(zoom);

                // Remove zoom on double click (prevents a
                // false zoom navigating regions)
                settings.svg.on("dblclick.zoom", null);
                return zoomer;
            }

            return {
                createZoomer: createZoomer
            };
        }]);

}());
