/*
 * 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 Layout Module.
 Module that contains the d3.force.layout logic
 */

(function () {
    'use strict';

    var $log, wss, sus, t2rs, t2d3, t2vs, t2ss;

    var uplink, linkG, linkLabelG, nodeG;
    var link, node;

    var highlightedLink;

    // default settings for force layout
    var defaultSettings = {
        gravity: 0.4,
        friction: 0.7,
        charge: {
            // note: key is node.class
            device: -8000,
            host: -5000,
            _def_: -12000
        },
        linkDistance: {
            // note: key is link.type
            direct: 100,
            optical: 120,
            hostLink: 3,
            _def_: 50
        },
        linkStrength: {
            // note: key is link.type
            // range: {0.0 ... 1.0}
            direct: 1.0,
            optical: 1.0,
            hostLink: 1.0,
            _def_: 1.0
        }
    };

    // configuration
    var linkConfig = {
        light: {
            baseColor: '#939598',
            inColor: '#66f',
            outColor: '#f00'
        },
        dark: {
            // TODO : theme
            baseColor: '#939598',
            inColor: '#66f',
            outColor: '#f00'
        },
        inWidth: 12,
        outWidth: 10
    };

    // internal state
    var settings,   // merged default settings and options
        force,      // force layout object
        drag,       // drag behavior handler
        nodeLock = false;       // whether nodes can be dragged or not (locked)

    var tickStuff = {
        nodeAttr: {
            transform: function (d) {
                var dx = isNaN(d.x) ? 0 : d.x,
                    dy = isNaN(d.y) ? 0 : d.y;
                return sus.translate(dx, dy);
            }
        },
        linkAttr: {
            x1: function (d) { return d.get('position').x1; },
            y1: function (d) { return d.get('position').y1; },
            x2: function (d) { return d.get('position').x2; },
            y2: function (d) { return d.get('position').y2; }
        }
    };

    function init(_svg_, forceG, _uplink_, _dim_, opts) {

        $log.debug("Initialising Topology Layout");
        uplink = _uplink_;
        settings = angular.extend({}, defaultSettings, opts);

        linkG = forceG.append('g').attr('id', 'topo-links');
        linkLabelG = forceG.append('g').attr('id', 'topo-linkLabels');
        forceG.append('g').attr('id', 'topo-numLinkLabels');
        nodeG = forceG.append('g').attr('id', 'topo-nodes');
        forceG.append('g').attr('id', 'topo-portLabels');

        link = linkG.selectAll('.link');
        linkLabelG.selectAll('.linkLabel');
        node = nodeG.selectAll('.node');

        _svg_.on('mousemove', mouseMoveHandler);
    }

    function createForceLayout() {

        force = d3.layout.force()
            .size(t2vs.getDimensions())
            .nodes(t2rs.regionNodes())
            .links(t2rs.regionLinks())
            .gravity(settings.gravity)
            .friction(settings.friction)
            .charge(settings.charge._def_)
            .linkDistance(settings.linkDistance._def_)
            .linkStrength(settings.linkStrength._def_)
            .on('tick', tick);

        drag = sus.createDragBehavior(force,
            t2ss.selectObject, atDragEnd, dragEnabled, clickEnabled);

        start();
        update();
    }

    function zoomingOrPanning(ev) {
        return ev.metaKey || ev.altKey;
    }

    function atDragEnd(d) {
        // once we've finished moving, pin the node in position
        d.fixed = true;
        d3.select(this).classed('fixed', true);
        sendUpdateMeta(d);
        t2ss.clickConsumed(true);
    }

    // predicate that indicates when dragging is active
    function dragEnabled() {
        var ev = d3.event.sourceEvent;
        // nodeLock means we aren't allowing nodes to be dragged...
        return !nodeLock && !zoomingOrPanning(ev);
    }

    function sendUpdateMeta(d, clearPos) {
        var metaUi = {},
            ll;

        // if we are not clearing the position data (unpinning),
        // attach the x, y, (and equivalent longitude, latitude)...
        if (!clearPos) {
            ll = d.lngLatFromCoord([d.x, d.y]);
            metaUi = {
                x: d.x,
                y: d.y,
                equivLoc: {
                    lng: ll[0],
                    lat: ll[1]
                }
            };
        }
        d.metaUi = metaUi;
        wss.sendEvent('updateMeta2', {
            id: d.get('id'),
            class: d.get('class'),
            memento: metaUi
        });
    }

    // predicate that indicates when clicking is active
    function clickEnabled() {
        return true;
    }

    function tick() {
        // guard against null (which can happen when our view pages out)...
        if (node && node.size()) {
            node.attr(tickStuff.nodeAttr);
        }
        if (link && link.size()) {
            link.call(calcPosition)
                .attr(tickStuff.linkAttr);
            // t2d3.applyNumLinkLabels(linkNums, numLinkLabelsG);
        }
    }

    function update() {
        _updateNodes();
        _updateLinks();
    }

    function _updateNodes() {

        var regionNodes = t2rs.regionNodes();

        // select all the nodes in the layout:
        node = nodeG.selectAll('.node')
            .data(regionNodes, function (d) { return d.get('id'); });

        var entering = node.enter()
            .append('g')
            .attr({
                id: function (d) { return sus.safeId(d.get('id')); },
                class: function (d) { return d.svgClassName(); },
                transform: function (d) {
                    // Need to guard against NaN here ??
                    return sus.translate(d.node.x, d.node.y);
                },
                opacity: 0
            })
            .call(drag)
            // .on('mouseover', tss.nodeMouseOver)
            // .on('mouseout', tss.nodeMouseOut)
            .transition()
            .attr('opacity', 1);

        entering.filter('.device').each(t2d3.nodeEnter);
        entering.filter('.sub-region').each(t2d3.nodeEnter);
        entering.filter('.host').each(t2d3.hostEnter);

        // operate on exiting nodes:
        // Note that the node is removed after 2 seconds.
        // Sub element animations should be shorter than 2 seconds.
        var exiting = node.exit()
            .transition()
            .duration(2000)
            .style('opacity', 0)
            .remove();

        // exiting node specifics:
        // exiting.filter('.host').each(t2d3.hostExit);
        exiting.filter('.device').each(t2d3.nodeExit);
    }

    function _updateLinks() {

        // var th = ts.theme();
        var regionLinks = t2rs.regionLinks();

        link = linkG.selectAll('.link')
            .data(regionLinks, function (d) { return d.get('key'); });

        // operate on entering links:
        var entering = link.enter()
            .append('line')
            .call(calcPosition)
            .attr({
                x1: function (d) { return d.get('position').x1; },
                y1: function (d) { return d.get('position').y1; },
                x2: function (d) { return d.get('position').x2; },
                y2: function (d) { return d.get('position').y2; },
                stroke: linkConfig.light.inColor,
                'stroke-width': linkConfig.inWidth
            });

        entering.each(t2d3.linkEntering);

        // operate on both existing and new links:
        // link.each(...)

        // add labels for how many links are in a thick line
        // t2d3.applyNumLinkLabels(linkNums, numLinkLabelsG);

        // apply or remove labels
        // t2d3.applyLinkLabels();

        // operate on exiting links:
        link.exit()
            .attr('stroke-dasharray', '3 3')
            .attr('stroke', linkConfig.light.outColor)
            .style('opacity', 0.5)
            .transition()
            .duration(1500)
            .attr({
                'stroke-dasharray': '3 12',
                'stroke-width': linkConfig.outWidth
            })
            .style('opacity', 0.0)
            .remove();
    }

    function calcPosition() {
        var lines = this;

        lines.each(function (d) {
            if (d.get('type') === 'hostLink') {
                d.set('position', getDefaultPos(d));
            }
        });

        lines.each(function (d) {
            d.set('position', getDefaultPos(d));
        });
    }

    function getDefaultPos(link) {

        return {
            x1: link.get('source').x,
            y1: link.get('source').y,
            x2: link.get('target').x,
            y2: link.get('target').y
        };
    }

    function setDimensions() {
        if (force) {
            force.size(t2vs.getDimensions());
        }
    }

    function start() {
        force.start();
    }

    // Mouse Events
    function mouseMoveHandler() {
        var mp = getLogicalMousePosition(this),
            link = computeNearestLink(mp);

        if (highlightedLink) {
            highlightedLink.unenhance();
            highlightedLink = null;
        }

        if (link) {
            link.enhance();
            highlightedLink = link;
        }
    }

    // ======== ALGORITHM TO FIND LINK CLOSEST TO MOUSE ========

    function getLogicalMousePosition(container) {
        var m = d3.mouse(container),
            sc = uplink.zoomer().scale(),
            tr = uplink.zoomer().translate(),
            mx = (m[0] - tr[0]) / sc,
            my = (m[1] - tr[1]) / sc;
        return { x: mx, y: my };
    }

    function sq(x) {
        return x * x;
    }

    function mdist(p, m) {
        return Math.sqrt(sq(p.x - m.x) + sq(p.y - m.y));
    }

    function prox(dist) {
        return dist / uplink.zoomer().scale();
    }

    function computeNearestLink(mouse) {
        var proximity = prox(30),
            nearest = null,
            minDist,
            regionLinks = t2rs.regionLinks();

        function pdrop(line, mouse) {

            var x1 = line.x1,
                y1 = line.y1,
                x2 = line.x2,
                y2 = line.y2,
                x3 = mouse.x,
                y3 = mouse.y,
                k = ((y2 - y1) * (x3 - x1) - (x2 - x1) * (y3 - y1)) /
                    (sq(y2 - y1) + sq(x2 - x1)),
                x4 = x3 - k * (y2 - y1),
                y4 = y3 + k * (x2 - x1);
            return { x: x4, y: y4 };
        }

        function lineHit(line, p, m) {
            if (p.x < line.x1 && p.x < line.x2) return false;
            if (p.x > line.x1 && p.x > line.x2) return false;
            if (p.y < line.y1 && p.y < line.y2) return false;
            if (p.y > line.y1 && p.y > line.y2) return false;
            // line intersects, but are we close enough?
            return mdist(p, m) <= proximity;
        }

        if (regionLinks.length) {
            minDist = proximity * 2;

            regionLinks.forEach(function (d) {
                // if (!api.showHosts() && d.type() === 'hostLink') {
                //     return; // skip hidden host links
                // }

                var line = d.get('position'),
                    point = pdrop(line, mouse),
                    hit = lineHit(line, point, mouse),
                    dist;

                if (hit) {
                    dist = mdist(point, mouse);
                    if (dist < minDist) {
                        minDist = dist;
                        nearest = d;
                    }
                }
            });
        }
        return nearest;
    }

    angular.module('ovTopo2')
    .factory('Topo2LayoutService',
        [
            '$log', 'WebSocketService', 'SvgUtilService', 'Topo2RegionService',
            'Topo2D3Service', 'Topo2ViewService', 'Topo2SelectService',

            function (_$log_, _wss_, _sus_, _t2rs_, _t2d3_, _t2vs_, _t2ss_) {

                $log = _$log_;
                wss = _wss_;
                t2rs = _t2rs_;
                t2d3 = _t2d3_;
                t2vs = _t2vs_;
                t2ss = _t2ss_;
                sus = _sus_;

                return {
                    init: init,
                    createForceLayout: createForceLayout,
                    update: update,
                    tick: tick,
                    start: start,

                    setDimensions: setDimensions
                };
            }
        ]
    );
})();
