/*
 * 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 Node Module.
 Module that contains model for nodes within the topology
 */

(function () {
    'use strict';

    var ps, sus, is, ts, t2mcs, t2nps, fn;

    var devIconDim = 36,
        devIconDimMin = 20,
        devIconDimMax = 40,
        labelPad = 5,
        textPad = 5,
        halfDevIcon = devIconDim / 2;

    // 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'
            }
        },
        // and here are the stroke colors of the glyph, per theme
        dUseTheme = {
            light: 'white',
            dark: 'black'
        };

    angular.module('ovTopo2')
    .factory('Topo2NodeModel', [
        'Topo2Model', 'FnService', 'Topo2PrefsService',
        'SvgUtilService', 'IconService', 'ThemeService',
        'Topo2MapConfigService', 'Topo2ZoomService', 'Topo2NodePositionService',
        'Topo2SelectService',
        function (Model, _fn_, _ps_, _sus_, _is_, _ts_,
            _t2mcs_, zoomService, _t2nps_, t2ss) {

            ts = _ts_;
            fn = _fn_;
            ps = _ps_;
            sus = _sus_;
            is = _is_;
            t2mcs = _t2mcs_;
            t2nps = _t2nps_;

            return Model.extend({
                initialize: function () {
                    this.node = this.createNode();
                    this._events = {
                        'mouseover': 'mouseoverHandler',
                        'mouseout': 'mouseoutHandler'
                    };
                },
                select: function () {
                    this.set('selected', true);
                },
                index: function () {

                    var models = this.collection.models,
                        id = this.get('id');

                    var index = _.find(models, function (model, i) {
                        return model.get('id') === id;
                    });

                    return index || models.length;
                },
                deselect: function () {
                    this.set('selected', false);
                },
                createNode: function () {
                    this.set('svgClass', this.svgClassName());
                    t2nps.positionNode(this);
                    return this;
                },
                setUpEvents: function () {
                    var _this = this,
                        events = angular.extend({}, this._events, this.events);
                    angular.forEach(events, function (handler, key) {
                        _this.el.on(key, _this[handler].bind(_this));
                    });
                },
                mouseoverHandler: function () {
                    this.set('hovered', true);
                },
                mouseoutHandler: function () {
                    this.set('hovered', false);
                },
                onClick: function () {
                    if (d3.event.defaultPrevented) return;

                    d3.event.preventDefault();
                    t2ss.selectObject(this, this.multiSelectEnabled);
                },
                fix: function (fixed) {
                    this.set({ fixed: fixed });
                    this.fixed = fixed;
                },
                icon: function () {
                    return 'unknown';
                },
                labelIndex: function () {
                    return ps.get('dlbls');
                },
                label: function () {
                    var props = this.get('props'),
                        id = this.get('id'),
                        friendlyName = props && props.name ? props.name : id,
                        labels = ['', friendlyName || id, id],
                        nli = this.labelIndex(),
                        idx = (nli < labels.length) ? nli : 0;

                    return labels[idx];
                },
                trimLabel: function (label) {
                    return (label && label.trim()) || '';
                },
                computeLabelWidth: function (el) {
                    var text = el.select('text'),
                        box = text.node().getBBox();
                    return box.width + labelPad * 2;
                },
                devGlyphColor: function () {
                    var o = this.get('online'),
                        id = this.get('master'),
                        otag = o ? 'online' : 'offline';
                    return o ? sus.cat7().getColor(id, 0, ts.theme()) :
                        dColTheme[ts.theme()][otag];
                },
                addLabelElements: function (label) {
                    var rect = this.el.append('rect')
                        .attr('class', 'node-container');
                    var glythRect = this.el.append('rect')
                        .attr('class', 'icon-rect')
                        .attr('y', -halfDevIcon)
                        .attr('x', -halfDevIcon)
                        .attr('width', devIconDim)
                        .attr('height', devIconDim)
                        .style('fill', this.devGlyphColor.bind(this));

                    var text = this.el.append('text').text(label)
                        .attr('text-anchor', 'left')
                        .attr('y', '0.3em')
                        .attr('x', halfDevIcon + labelPad + textPad);

                    return {
                        rect: rect,
                        glythRect: glythRect,
                        text: text
                    };
                },
                labelBox: function (dim, labelWidth) {
                    var _textPad = (textPad * 2) - labelPad;

                    if (labelWidth === 0) {
                        _textPad = 0;
                    }

                    return {
                        x: -dim / 2 - labelPad,
                        y: -dim / 2 - labelPad,
                        width: dim + labelWidth + (labelPad * 2) + _textPad,
                        height: dim + (labelPad * 2)
                    };
                },
                iconBox: function (dim, labelWidth) {
                    return {
                        x: -dim / 2,
                        y: -dim / 2,
                        width: dim + labelWidth,
                        height: dim
                    };
                },
                svgClassName: function () {
                    return fn.classNames('node',
                        this.nodeType,
                        this.get('type'),
                        {
                            online: this.get('online'),
                            selected: this.get('selected'),
                            hovered: this.get('hovered'),
                            fixed: this.get('fixed')
                        }
                    );
                },
                lngLatFromCoord: function (coord) {
                    var p = t2mcs.projection();
                    return p ? p.invert(coord) : [0, 0];
                },
                resetPosition: function () {
                    t2nps.setLongLat(this);
                },
                update: function () {
                    this.updateLabel();
                },
                updateLabel: function () {
                    var node = this.el,
                        label = this.trimLabel(this.label()),
                        labelWidth;

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

                    node.select('rect')
                        .transition()
                        .attr(this.labelBox(devIconDim, labelWidth));
                },
                onEnter: function (el) {
                    this.el = d3.select(el);
                    this.render();
                },
                setScale: function () {

                    if (!this.el) return;

                    var dim = devIconDim,
                        multipler = 1;

                    if (dim * zoomService.scale() < devIconDimMin) {
                        multipler = devIconDimMin / (dim * zoomService.scale());
                    } else if (dim * zoomService.scale() > devIconDimMax) {
                        multipler = devIconDimMax / (dim * zoomService.scale());
                    }

                    this.el.selectAll('*')
                        .style('transform', 'scale(' + multipler + ')');
                },
                render: function () {
                    var node = this.el,
                        glyphId = this.icon(this.get('type')),
                        label = this.trimLabel(this.label()),
                        glyph, labelWidth;

                    // Label
                    var labelElements = this.addLabelElements(label);
                    labelWidth = label ? this.computeLabelWidth(node) : 0;
                    labelElements.rect
                        .attr(this.labelBox(devIconDim, labelWidth));

                    // Icon
                    glyph = is.addDeviceIcon(node, glyphId, devIconDim);
                    glyph.attr(this.iconBox(devIconDim, 0));
                    glyph.style('fill', dUseTheme[ts.theme()]);

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

                    if (this.events) {
                        this.setUpEvents();
                    }

                    this.setScale();
                }
            });
        }]
    );
})();
