/*
 * 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 Links Module.
 Module that holds the links for a region
 */

(function () {
    'use strict';

    var $log, Collection, Model, ts, sus, t2zs, t2vs, t2lps, fn;

    var linkLabelOffset = '0.35em';

    var widthRatio = 1.4,
        linkScale = d3.scale.linear()
            .domain([1, 12])
            .range([widthRatio, 12 * widthRatio])
            .clamp(true),
        allLinkTypes = 'direct optical tunnel UiDeviceLink',
        allLinkSubTypes = 'not-permitted',
        labelDim = 30;

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

    function createLink() {

        var linkPoints = this.linkEndPoints(this.get('epA'), this.get('epB'));

        var attrs = angular.extend({}, linkPoints, {
            key: this.get('id'),
            class: 'link',
            position: {
                x1: 0,
                y1: 0,
                x2: 0,
                y2: 0
            }
            // functions to aggregate dual link state
            // extra: link.extra
        });

        this.set(attrs);
    }

    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 -= 4;
        box.width += 8;
        return box;
    }

    function isLinkOnline(node) {
        return (node.get('nodeType') === 'region') ? true : node.get('online');
    }

    function linkEndPoints(srcId, dstId) {

        var findNodeById = this.region.model.findNodeById.bind(this.region),
            allNodes = this.region.model.nodes(),
            sourceNode = findNodeById(this, srcId),
            targetNode = findNodeById(this, dstId);

        if (!sourceNode || !targetNode) {
            $log.error('Node(s) not on map for link:' + srcId + '~' + dstId);
            // logicError('Node(s) not on map for link:\n' + sMiss + dMiss);
            return null;
        }

        this.source = allNodes.indexOf(sourceNode);
        this.target = allNodes.indexOf(targetNode);
        this.sourceNode = sourceNode;
        this.targetNode = targetNode;

        return {
            source: sourceNode,
            target: targetNode
        };
    }

    function createLinkCollection(data, _region) {

        var LinkModel = Model.extend({
            region: _region,
            createLink: createLink,
            linkEndPoints: linkEndPoints,
            type: function () {
                return this.get('type');
            },
            svgClassName: function () {
                return fn.classNames('link',
                    this.nodeType,
                    this.get('type'),
                    {
                        enhanced: this.get('enhanced'),
                        selected: this.get('selected')
                    }
                );
            },
            expected: function () {
                // TODO: original code is: (s && s.expected) && (t && t.expected);
                return true;
            },
            online: function () {

                var source = this.get('source'),
                    target = this.get('target'),
                    sourceOnline = isLinkOnline(source),
                    targetOnline = isLinkOnline(target);

                return (sourceOnline) && (targetOnline);
            },
            onChange: function () {
                // Update class names when the model changes
                if (this.el) {
                    this.el.attr('class', this.svgClassName());
                }
            },
            enhance: function () {
                var data = [],
                    point;

                if (showPort()) {
                    this.set('enhanced', true);
                    point = this.locatePortLabel();
                    angular.extend(point, {
                        id: 'topo2-port-tgt',
                        num: this.get('portB')
                    });
                    data.push(point);

                    if (this.get('portA')) {
                        point = this.locatePortLabel(1);
                        angular.extend(point, {
                            id: 'topo2-port-src',
                            num: this.get('portA')
                        });
                        data.push(point);
                    }

                    var entering = d3.select('#topo2-portLabels')
                        .selectAll('.portLabel')
                        .data(data)
                        .enter().append('g')
                        .classed('portLabel', true)
                        .attr('id', function (d) { return d.id; });

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

                        var rectSize = rectAroundText(el);

                        rect.attr(rectSize)
                            .attr('rx', 2)
                            .attr('ry', 2);

                        text.attr('dy', linkLabelOffset)
                            .attr('text-anchor', 'middle');

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

                    });

                    this.setScale();
                }
            },
            unenhance: function () {
                this.set('enhanced', false);
                d3.select('#topo2-portLabels').selectAll('.portLabel').remove();
            },
            getSelected: function () {
                return this.collection.filter(function (m) {
                    return m.get('selected');
                });
            },
            select: function () {

                // TODO: if single selection clear selected devices, hosts, sub-regions
                var s = Boolean(this.get('selected'));
                // Clear all selected Items
                _.each(this.collection.models, function (m) {
                    m.set('selected', false);
                });

                this.set('selected', !s);
                this.showDetails();

                return this.getSelected();
            },
            deselect: function () {
                this.set('selected', false);
                this.set('enhanced', false);
            },
            showDetails: function () {
                var selected = this.getSelected();

                if (selected) {
                    t2lps.displayLink(this);
                } else {
                    t2lps.hide();
                }
            },
            locatePortLabel: function (src) {

                var offset = 32 / (labelDim * t2zs.scale()),
                    sourceX = this.get('position').x1,
                    sourceY = this.get('position').y1,
                    targetX = this.get('position').x2,
                    targetY = this.get('position').y2,
                    nearX = src ? sourceX : targetX,
                    nearY = src ? sourceY : targetY,
                    farX = src ? targetX : sourceX,
                    farY = src ? targetY : sourceY;

                function dist(x, y) {
                    return Math.sqrt(x * x + y * y);
                }

                var dx = farX - nearX,
                    dy = farY - nearY,
                    k = (32 * offset) / dist(dx, dy);

                return { x: k * dx + nearX, y: k * dy + nearY };
            },
            restyleLinkElement: function (immediate) {
                // this fn's job is to look at raw links and decide what svg classes
                // need to be applied to the line element in the DOM
                var th = ts.theme(),
                    el = this.el,
                    type = this.get('type'),
                    online = this.online(),
                    modeCls = this.expected() ? '-inactive' : 'not-permitted',
                    delay = immediate ? 0 : 1000;

                // NOTE: understand why el is sometimes undefined on addLink events...
                // Investigated:
                // el is undefined when it's a reverse link that is being added.
                // updateLinks (which sets ldata.el) isn't called before this is called.
                // Calling _updateLinks in addLinkUpdate fixes it, but there might be
                // a more efficient way to fix it.
                if (el && !el.empty()) {
                    el.classed('link', true);
                    el.classed(allLinkSubTypes, false);
                    el.classed(modeCls, !online);
                    el.classed(allLinkTypes, false);
                    if (type) {
                        el.classed(type, true);
                    }
                    el.transition()
                        .duration(delay)
                        .attr('stroke', linkConfig[th].baseColor);

                    this.setScale();
                }
            },
            onEnter: function (el) {
                var link = d3.select(el);

                this.el = link;
                this.restyleLinkElement();

                if (this.get('type') === 'hostLink') {
                    // sus.visible(link, api.showHosts());
                }
            },
            setScale: function () {
                var width = linkScale(widthRatio) / t2zs.scale();
                this.el.style('stroke-width', width + 'px');

                var labelScale = labelDim / (labelDim * t2zs.scale());

                d3.select('#topo2-portLabels')
                    .selectAll('.portLabel')
                    .selectAll('*')
                    .style('transform', 'scale(' + labelScale + ')');

            },
            update: function () {
                if (this.get('enhanced')) {
                    this.enhance();
                }
            },
            remove: function () {

                var width = linkScale(widthRatio) / t2zs.scale();

                this.el.transition()
                    .duration(300)
                    .attr('stroke', '#ff0000')
                    .style('stroke-width', width * 4)
                    .transition()
                    .delay(1000)
                    .style('opacity', 0);
            }
        });

        var LinkCollection = Collection.extend({
            model: LinkModel
        });

        return new LinkCollection(data);
    }

    function showPort() {
        return t2vs.getPortHighlighting();
    }

    angular.module('ovTopo2')
    .factory('Topo2LinkService', [
        '$log', 'Topo2Collection', 'Topo2Model',
        'ThemeService', 'SvgUtilService', 'Topo2ZoomService',
        'Topo2ViewService', 'Topo2LinkPanelService', 'FnService',
        function (_$log_, _c_, _Model_, _ts_, _sus_,
            _t2zs_, _t2vs_, _t2lps_, _fn_) {

            $log = _$log_;
            ts = _ts_;
            sus = _sus_;
            t2zs = _t2zs_;
            t2vs = _t2vs_;
            Collection = _c_;
            Model = _Model_;
            t2lps = _t2lps_;
            fn = _fn_;

            return {
                createLinkCollection: createLinkCollection
            };
        }
    ]);
})();
