/*
 * 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 Oblique View Module.
 Provides functionality to view the topology as two planes (packet & optical)
 from an oblique (side-on) perspective.
 */

(function () {
    'use strict';

    // injected refs
    var $log, fs, sus;

    // api to topoForce
    var api;
    /*
     force()                        // get ref to force layout object
     zoomLayer()                    // get ref to zoom layer
     nodeGBBox()                    // get bounding box of node group layer
     node()                         // get ref to D3 selection of nodes
     link()                         // get ref to D3 selection of links
     nodes()                        // get ref to network nodes array
     tickStuff                      // ref to tick functions
     nodeLock(b)                    // test-and-set nodeLock state
     opacifyMap(b)                  // show or hide map layer
     inLayer(d, layer)              // return true if d in layer {'pkt'|'opt'}
     */

    // configuration
    var xsky = -.7,     // x skew y factor
        xsk = -35,      // x skew angle
        ysc = .5,       // y scale
        pad = 50,
        time = 1500,
        fill = {
            pkt: 'rgba(130,130,170,0.3)',   // blue-ish
            opt: 'rgba(170,130,170,0.3)'    // magenta-ish
        };

    // internal state
    var oblique = false,
        xffn = null,
        plane = {},
        oldNodeLock;


    function planeId(tag) {
        return 'topo-obview-' + tag + 'Plane';
    }

    function ytfn(h, dir) {
        return h * ysc * dir * 1.1;
    }

    function obXform(h, dir) {
        var yt = ytfn(h, dir);
        return sus.scale(1, ysc) + sus.translate(0, yt) + sus.skewX(xsk);
    }

    function noXform() {
        return sus.skewX(0) + sus.translate(0,0) + sus.scale(1,1);
    }

    function padBox(box, p) {
        box.x -= p;
        box.y -= p;
        box.width += p*2;
        box.height += p*2;
    }

    function toObliqueView() {
        var box = api.nodeGBBox(),
            ox, oy;

        padBox(box, pad);

        ox = box.x + box.width / 2;
        oy = box.y + box.height / 2;

        // remember node lock state, then lock the nodes down
        oldNodeLock = api.nodeLock(true);
        api.opacifyMap(false);

        insertPlanes(ox, oy);

        xffn = function (xy, dir) {
            var yt = ytfn(box.height, dir),
                ax = xy.x - ox,
                ay = xy.y - oy,
                x = ax + ay * xsky,
                y = (ay + yt) * ysc;
            return {x: ox + x, y: oy + y};
        };

        showPlane('pkt', box, -1);
        showPlane('opt', box, 1);
        obTransitionNodes();
    }

    function toNormalView() {
        xffn = null;

        hidePlane('pkt');
        hidePlane('opt');
        obTransitionNodes();

        removePlanes();

        // restore node lock state
        api.nodeLock(oldNodeLock);
        api.opacifyMap(true);
    }

    function obTransitionNodes() {
        // return the direction for the node
        // -1 for pkt layer, 1 for optical layer
        function dir(d) {
            return api.inLayer(d, 'pkt') ? -1 : 1;
        }

        if (xffn) {
            api.nodes().forEach(function (d) {
                var oldxy = {x: d.x, y: d.y},
                    coords = xffn(oldxy, dir(d));
                d.oldxy = oldxy;
                d.px = d.x = coords.x;
                d.py = d.y = coords.y;
            });
        } else {
            api.nodes().forEach(function (d) {
                var old = d.oldxy || {x: d.x, y: d.y};
                d.px = d.x = old.x;
                d.py = d.y = old.y;
                delete d.oldxy;
            });
        }

        api.node().transition()
            .duration(time)
            .attr(api.tickStuff.nodeAttr);
        api.link().transition()
            .duration(time)
            .attr(api.tickStuff.linkAttr);
        api.linkLabel().transition()
            .duration(time)
            .attr(api.tickStuff.linkLabelAttr);
    }

    function showPlane(tag, box, dir) {
        // set box origin at center..
        box.x = -box.width/2;
        box.y = -box.height/2;

        plane[tag].select('rect')
            .attr(box)
            .attr('opacity', 0)
            .transition()
            .duration(time)
            .attr('opacity', 1)
            .attr('transform', obXform(box.height, dir));
    }

    function hidePlane(tag) {
        plane[tag].select('rect')
            .transition()
            .duration(time)
            .attr('opacity', 0)
            .attr('transform', noXform());
    }

    function insertPlanes(ox, oy) {
        function ins(tag) {
            var id = planeId(tag),
                g = api.zoomLayer().insert('g', '#topo-G')
                    .attr('id', id)
                    .attr('transform', sus.translate(ox,oy));
            g.append('rect')
                .attr('fill', fill[tag])
                .attr('opacity', 0);
            plane[tag] = g;
        }
        ins('opt');
        ins('pkt');
    }

    function removePlanes() {
        function rem(tag) {
            var id = planeId(tag);
            api.zoomLayer().select('#'+id)
                .transition()
                .duration(time + 50)
                .remove();
            delete plane[tag];
        }
        rem('opt');
        rem('pkt');
    }


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

angular.module('ovTopo')
    .factory('TopoObliqueService',
    ['$log', 'FnService', 'SvgUtilService',

    function (_$log_, _fs_, _sus_) {
        $log = _$log_;
        fs = _fs_;
        sus = _sus_;

        function initOblique(_api_) {
            api = _api_;
        }

        function destroyOblique() { }

        function toggleOblique() {
            oblique = !oblique;
            if (oblique) {
                api.force().stop();
                toObliqueView();
            } else {
                toNormalView();
            }
        }

        return {
            initOblique: initOblique,
            destroyOblique: destroyOblique,

            isOblique: function () { return oblique; },
            toggleOblique: toggleOblique
        };
    }]);
}());
