/*
 * Copyright 2015-present Open Networking Foundation
 *
 * 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 D3 Module.
 Functions for manipulating the D3 visualizations of the Topology
 */

(function () {
    'use strict';

    // injected refs
    var sus, is, ts, ps, ttbs;

    // function to be replaced by the localization bundle function
    var topoLion = function (x) {
        return '#tfs#' + x + '#';
    };

    // api to topoForce
    var zoomer, api;
    /*
     node()                 // get ref to D3 selection of nodes
     link()                 // get ref to D3 selection of links
     linkLabel()            // get ref to D3 selection of link labels
     instVisible()          // true if instances panel is visible
     posNode()              // position node
     showHosts()            // true if hosts are to be shown
     restyleLinkElement()   // update link styles based on backing data
     updateLinkLabelModel() // update backing data for link labels
     */

    // configuration
    var devIconDim = 36,
        devColorDim = 32,
        labelPad = 4,
        hostRadius = 14,
        badgeConfig = {
            radius: 12,
            yoff: 5,
            gdelta: 10,
        },
        halfDevIcon = devIconDim / 2,
        devBadgeOff = { dx: -halfDevIcon, dy: -halfDevIcon },
        hostBadgeOff = { dx: -hostRadius, dy: -hostRadius },
        portLabelDim = 30,
        status = {
            i: 'badgeInfo',
            w: 'badgeWarn',
            e: 'badgeError',
        };

    // NOTE: this type of hack should go away once we have implemented
    //       the server-side UiModel code.
    // {virtual -> cord} is for the E-CORD demo at ONS 2016
    var remappedDeviceTypes = {
        virtual: 'cord',

        // for now, map to the new glyphs via this lookup.
        // may have to find a better way to do this...
        'switch': 'm_switch',
        roadm: 'm_roadm',
        otn: 'm_otn',
        ols: 'm_roadm',
        terminal_device: 'm_otn',
        roadm_otn: 'm_roadm_otn',
        fiber_switch: 'm_fiberSwitch',
        microwave: 'm_microwave',
    };

    var remappedHostTypes = {
        router: 'm_router',
        endstation: 'm_endstation',
        bgpSpeaker: 'm_bgpSpeaker',
    };

    function mapDeviceTypeToGlyph(type) {
        return remappedDeviceTypes[type] || type || 'unknown';
    }

    function mapHostTypeToGlyph(type) {
        return remappedHostTypes[type] || type || 'unknown';
    }

    function badgeStatus(badge) {
        return status[badge.status] || status.i;
    }

    // internal state
    var deviceLabelIndex = 0,
        hostLabelIndex = 0,
        linkLabelsEnabled = true;

    // note: these are the device icon colors without affinity (no master)
    var dColTheme = {
        light: {
            online: '#444444',
            offline: '#cccccc',
        },
        dark: {
            // TODO: theme
            online: '#444444',
            offline: '#cccccc',
        },
    };

    function devGlyphColor(d) {
        var o = d.online,
            id = d.master,
            otag = o ? 'online' : 'offline';
        return o ? sus.cat7().getColor(id, 0, ts.theme())
                 : dColTheme[ts.theme()][otag];
    }

    function setDeviceColor(d) {
        // want to color the square rectangle (no longer the 'use' glyph)
        d.el.selectAll('rect').filter(function (d, i) { return i === 1; })
            .style('fill', devGlyphColor(d));
    }

    function incDevLabIndex() {
        setDevLabIndex(deviceLabelIndex+1);
        switch (deviceLabelIndex) {
            case 0: return topoLion('fl_device_labels_hide');
            case 1: return topoLion('fl_device_labels_show_friendly');
            case 2: return topoLion('fl_device_labels_show_id');
        }
    }

    function setDevLabIndex(mode) {
        deviceLabelIndex = mode % 3;
        var p = ps.getPrefs('topo_prefs', ttbs.defaultPrefs);
        p.dlbls = deviceLabelIndex;
        ps.setPrefs('topo_prefs', p);
    }

    function incHostLabIndex() {
        setHostLabIndex(hostLabelIndex+1);
        switch (hostLabelIndex) {
            case 0: return topoLion('fl_host_labels_show_friendly');
            case 1: return topoLion('fl_host_labels_show_ip');
            case 2: return topoLion('fl_host_labels_show_mac');
            case 3: return topoLion('fl_host_labels_hide');
        }
    }

    function setHostLabIndex(mode) {
        hostLabelIndex = mode % 4;
        var p = ps.getPrefs('topo_prefs', ttbs.defaultPrefs);
        p.hlbls = hostLabelIndex;
        ps.setPrefs('topo_prefs', p);
    }

    function hostLabel(d) {
        var idx = (hostLabelIndex < d.labels.length) ? hostLabelIndex : 0;
        return d.labels[idx];
    }

    function deviceLabel(d) {
        var idx = (deviceLabelIndex < d.labels.length) ? deviceLabelIndex : 0;
        return d.labels[idx];
    }

    function toggleLinkLabels() {
        linkLabelsEnabled = !linkLabelsEnabled;
        return linkLabelsEnabled;
    }

    function trimLabel(label) {
        return (label && label.trim()) || '';
    }

    function computeLabelWidth(n) {
        var text = n.select('text'),
            box = text.node().getBBox();
        return box.width + labelPad * 2;
    }

    function iconBox(dim, labelWidth) {
        return {
            x: -dim/2,
            y: -dim/2,
            width: dim + labelWidth,
            height: dim,
        };
    }

    function updateDeviceRendering(d) {
        var node = d.el,
            bdg = d.badge,
            label = trimLabel(deviceLabel(d)),
            labelWidth;

        node.select('text').text(label);
        labelWidth = label ? computeLabelWidth(node) : 0;

        node.select('rect')
            .transition()
            .attr(iconBox(devIconDim, labelWidth));

        if (bdg) {
            renderBadge(node, bdg, devBadgeOff);
        }
    }

    function updateHostRendering(d) {
        var node = d.el,
            bdg = d.badge;

        updateHostLabel(d);

        if (bdg) {
            renderBadge(node, bdg, hostBadgeOff);
        }
    }

    function renderBadge(node, bdg, boff) {
        var bsel,
            bcr = badgeConfig.radius,
            bcgd = badgeConfig.gdelta;

        node.select('g.badge').remove();

        bsel = node.append('g')
            .classed('badge', true)
            .classed(badgeStatus(bdg), true)
            .attr('transform', sus.translate(boff.dx, boff.dy));

        bsel.append('circle')
            .attr('r', bcr);

        if (bdg.txt) {
            bsel.append('text')
                .attr('dy', badgeConfig.yoff)
                .attr('text-anchor', 'middle')
                .text(bdg.txt);
        } else if (bdg.gid) {
            bsel.append('use')
                .attr({
                    width: bcgd * 2,
                    height: bcgd * 2,
                    transform: sus.translate(-bcgd, -bcgd),
                    'xlink:href': '#' + bdg.gid,
                });
        }
    }

    function updateHostLabel(d) {
        var label = trimLabel(hostLabel(d));
        d.el.select('text').text(label);
    }

    function updateDeviceColors(d) {
        if (d) {
            setDeviceColor(d);
        } else {
            api.node().filter('.device').each(function (d) {
                setDeviceColor(d);
            });
        }
    }


    // ==========================
    // updateNodes - subfunctions

    function deviceExisting(d) {
        var node = d.el;
        node.classed('online', d.online);
        updateDeviceRendering(d);
        api.posNode(d, true);
    }

    function hostExisting(d) {
        updateHostRendering(d);
        api.posNode(d, true);
    }

    function deviceEnter(d) {
        var node = d3.select(this),
            glyphId = mapDeviceTypeToGlyph(d.type),
            label = trimLabel(deviceLabel(d)),
            rect, crect, glyph, labelWidth;

        d.el = node;

        rect = node.append('rect');
        crect = node.append('rect');

        node.append('text').text(label)
            .attr('text-anchor', 'left')
            .attr('y', '0.3em')
            .attr('x', halfDevIcon + labelPad);

        glyph = is.addDeviceIcon(node, glyphId, devIconDim);

        labelWidth = label ? computeLabelWidth(node) : 0;

        rect.attr(iconBox(devIconDim, labelWidth));
        crect.attr(iconBox(devColorDim, 0));
        glyph.attr(iconBox(devIconDim, 0));

        node.attr('transform', sus.translate(-halfDevIcon, -halfDevIcon));

        d.el.selectAll('*')
            .style('transform', 'scale(' + api.deviceScale() + ')');
    }

    function hostEnter(d) {
        var node = d3.select(this),
            glyphId = mapHostTypeToGlyph(d.type),
            textDy = hostRadius + 10;

        d.el = node;
        sus.visible(node, api.showHosts());

        is.addHostIcon(node, hostRadius, glyphId);

        node.append('text')
            .text(hostLabel)
            .attr('dy', textDy)
            .attr('text-anchor', 'middle');

        d.el.selectAll('g').style('transform', 'scale(' + api.deviceScale() + ')');
        d.el.selectAll('text').style('transform', 'scale(' + api.deviceScale() + ')');
    }

    function hostExit(d) {
        var node = d.el;
        node.select('use')
            .style('opacity', 0.5)
            .transition()
            .duration(800)
            .style('opacity', 0);

        node.select('text')
            .style('opacity', 0.5)
            .transition()
            .duration(800)
            .style('opacity', 0);

        node.select('circle')
            .style('stroke-fill', '#555')
            .style('fill', '#888')
            .style('opacity', 0.5)
            .transition()
            .duration(1500)
            .attr('r', 0);
    }

    function deviceExit(d) {
        var node = d.el;
        node.select('use')
            .style('opacity', 0.5)
            .transition()
            .duration(800)
            .style('opacity', 0);

        node.selectAll('rect')
            .style('stroke-fill', '#555')
            .style('fill', '#888')
            .style('opacity', 0.5);
    }


    // ==========================
    // updateLinks - subfunctions

    function linkEntering(d) {

        var link = d3.select(this);
        d.el = link;
        d.el.style('stroke-width', api.linkWidthScale() + 'px');
        api.restyleLinkElement(d);
        if (d.type() === 'hostLink') {
            sus.visible(link, api.showHosts());
        }
    }

    var linkLabelOffset = '0.3em';

    function applyLinkLabels() {
        var entering;

        api.updateLinkLabelModel();
        if (linkLabelsEnabled) {

            // for elements already existing, we need to update the text
            // and adjust the rectangle size to fit
            api.linkLabel().each(function (d) {
                var el = d3.select(this),
                    rect = el.select('rect'),
                    text = el.select('text');
                text.text(d.label);
                rect.attr(rectAroundText(el));
            });

            entering = api.linkLabel().enter().append('g')
                .classed('linkLabel', true)
                .attr('id', function (d) { return d.id; });

            entering.each(function (d) {
                var el = d3.select(this),
                    rect,
                    text;

                if (d.ldata.type() === 'hostLink') {
                    el.classed('hostLinkLabel', true);
                    sus.visible(el, api.showHosts());
                }

                d.el = el;
                rect = el.append('rect');
                text = el.append('text').text(d.label);
                rect.attr(rectAroundText(el));
                text.attr('dy', linkLabelOffset);

                el.attr('transform', transformLabel(d.ldata.position, d.key));
            });
        } else {
            api.linkLabel().each(function (d) {
                var el = d3.select(this),
                    rect = el.select('rect'),
                    text = el.select('text');
                text.text('');
                rect.attr(rectAroundText(el));
            });
        }

        // Remove any labels that are no longer required.
        api.linkLabel().exit().remove();
    }

    function rectAroundText(el) {
        var text = el.select('text'),
            box = text.node().getBBox();

        // translate the bbox so that it is centered on [x,y]
        box.x = -box.width / 2;
        box.y = -box.height / 2;

        // add padding
        box.x -= 1;
        box.width += 2;
        return box;
    }

    function generateLabelFunction() {
        var labels = [],
            xGap = 15,
            yGap = 17;

        return function (newId, newX, newY) {
            var idx = -1;

            labels.forEach(function (lab, i) {
                var minX, maxX, minY, maxY;

                if (lab.id === newId) {
                    idx = i;
                    return;
                }
                minX = lab.x - xGap;
                maxX = lab.x + xGap;
                minY = lab.y - yGap;
                maxY = lab.y + yGap;

                if (newX > minX && newX < maxX && newY > minY && newY < maxY) {
                    // labels are overlapped
                    newX = newX - xGap;
                    newY = newY - yGap;
                }
            });

            if (idx === -1) {
                labels.push({ id: newId, x: newX, y: newY });
            } else {
                labels[idx] = { id: newId, x: newX, y: newY };
            }

            return { x: newX, y: newY };
        };
    }

    var getLabelPos = generateLabelFunction();

    function transformLabel(p, id) {
        var dx = p.x2 - p.x1,
            dy = p.y2 - p.y1,
            xMid = dx/2 + p.x1,
            yMid = dy/2 + p.y1;

        if (id) {
            var pos = getLabelPos(id, xMid, yMid);
            return sus.translate(pos.x, pos.y);
        }

        return sus.translate(xMid, yMid);
    }

    function applyPortLabels(data, portLabelG) {
        var entering = portLabelG.selectAll('.portLabel')
            .data(data).enter().append('g')
            .classed('portLabel', true)
            .attr('id', function (d) { return d.id; });

        var labelScale = portLabelDim / (portLabelDim * zoomer.scale());

        entering.each(function (d) {
            var el = d3.select(this),
                rect = el.append('rect'),
                text = el.append('text').text(d.num);

            rect.attr(rectAroundText(el))
                .style('transform', 'scale(' + labelScale + ')');
            text.attr('dy', linkLabelOffset)
                .style('transform', 'scale(' + labelScale + ')');

            el.attr('transform', sus.translate(d.x, d.y));
        });
    }

    function labelPoint(linkPos) {
        var lengthUpLine = 1 / 3,
            dx = linkPos.x2 - linkPos.x1,
            dy = linkPos.y2 - linkPos.y1,
            movedX = dx * lengthUpLine,
            movedY = dy * lengthUpLine;

        return {
            x: movedX,
            y: movedY,
        };
    }

    function calcGroupPos(linkPos) {
        var moved = labelPoint(linkPos);
        return sus.translate(linkPos.x1 + moved.x, linkPos.y1 + moved.y);
    }

    // calculates where on the link that the hash line for 5+ label appears
    function hashAttrs(linkPos) {
        var hashLength = 25,
            halfLength = hashLength / 2,
            dx = linkPos.x2 - linkPos.x1,
            dy = linkPos.y2 - linkPos.y1,
            length = Math.sqrt((dx * dx) + (dy * dy)),
            moveAmtX = (dx / length) * halfLength,
            moveAmtY = (dy / length) * halfLength,
            mid = labelPoint(linkPos),
            angle = Math.atan(dy / dx) + 45;

        return {
            x1: mid.x - moveAmtX,
            y1: mid.y - moveAmtY,
            x2: mid.x + moveAmtX,
            y2: mid.y + moveAmtY,
            stroke: api.linkConfig()[ts.theme()].baseColor,
            transform: 'rotate(' + angle + ',' + mid.x + ',' + mid.y + ')',
        };
    }

    function textLabelPos(linkPos) {
        var point = labelPoint(linkPos),
            dist = 20;
        return {
            x: point.x + dist,
            y: point.y + dist,
        };
    }

    function applyNumLinkLabels(data, lblsG) {
        var labels = lblsG.selectAll('g.numLinkLabel')
                .data(data, function (d) { return 'pair-' + d.id; }),
            entering;

        // update existing labels
        labels.each(function (d) {
            var el = d3.select(this);

            el.attr({
                transform: function (d) { return calcGroupPos(d.linkCoords); },
            });
            el.select('line')
                .attr(hashAttrs(d.linkCoords));
            el.select('text')
                .attr(textLabelPos(d.linkCoords))
                .text(d.num);
        });

        // add new labels
        entering = labels
            .enter()
            .append('g')
            .attr({
                transform: function (d) { return calcGroupPos(d.linkCoords); },
                id: function (d) { return 'pair-' + d.id; },
            })
            .classed('numLinkLabel', true);

        entering.each(function (d) {
            var el = d3.select(this);

            el.append('line')
                .classed('numLinkHash', true)
                .attr(hashAttrs(d.linkCoords));
            el.append('text')
                .classed('numLinkText', true)
                .attr(textLabelPos(d.linkCoords))
                .text(d.num);
        });

        // remove old labels
        labels.exit().remove();
    }

    // invoked after the localization bundle has been received from the server
    function setLionBundle(bundle) {
        topoLion = bundle;
    }

    // ==========================
    // Module definition

    angular.module('ovTopo')
    .factory('TopoD3Service',
        ['SvgUtilService', 'IconService', 'ThemeService',
            'PrefsService', 'TopoToolbarService',

        function (_sus_, _is_, _ts_, _ps_, _ttbs_) {
            sus = _sus_;
            is = _is_;
            ts = _ts_;
            ps = _ps_;
            ttbs = _ttbs_;

            function initD3(_api_, _zoomer_) {
                api = _api_;
                zoomer = _zoomer_;
            }

            function destroyD3() { }

            return {
                initD3: initD3,
                destroyD3: destroyD3,

                incDevLabIndex: incDevLabIndex,
                setDevLabIndex: setDevLabIndex,
                incHostLabIndex: incHostLabIndex,
                setHostLabIndex: setHostLabIndex,
                hostLabel: hostLabel,
                deviceLabel: deviceLabel,
                toggleLinkLabels: toggleLinkLabels,
                trimLabel: trimLabel,

                updateDeviceLabel: updateDeviceRendering,
                updateHostLabel: updateHostLabel,
                updateDeviceColors: updateDeviceColors,

                deviceExisting: deviceExisting,
                hostExisting: hostExisting,
                deviceEnter: deviceEnter,
                hostEnter: hostEnter,
                hostExit: hostExit,
                deviceExit: deviceExit,

                linkEntering: linkEntering,
                applyLinkLabels: applyLinkLabels,
                transformLabel: transformLabel,
                applyPortLabels: applyPortLabels,
                applyNumLinkLabels: applyNumLinkLabels,

                setLionBundle: setLionBundle,
            };
        }]);
}());
