/*
 * 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 Sprite Module.
 Defines behavior for loading sprites into the sprite layer.
 */

 (function() {
    'use strict';

    var instance,
        renderer;

    function vbox(w, h) {
      return '0 0 ' + w + ' ' + h;
    }

    angular.module('ovTopo2')
        .factory('Topo2SpriteLayerService', [
            '$log', 'FnService',
            'Topo2ViewController', 'SpriteService', 'ThemeService',

            function ($log, fs, ViewController, ss, ts) {

                var SpriteLayer = ViewController.extend({

                    id: 'topo2-sprites',
                    displayName: 'Sprite Layer',

                    init: function() {
                        this.svg = d3.select('#topo2');
                        this.createSpriteDefs();
                        this.container = this.appendElement('#topo2-background', 'g');
                    },
                    loadLayout: function (id) {
                        var _this = this;
                        this.container.selectAll("*").remove();
                        this.layout = ss.layout(id);

                        if (this.layout) {
                            this.width = this.layout.data.w;
                            this.height = this.layout.data.h;

                            this.renderLayout();

                            if (fs.debugOn('sprite_grid')) {
                                this.renderGrid();
                            }
                        } else {
                            $log.warn('no sprite layout registered:', id);
                        }

                        // Returns a promise for consistency with Topo2MapService
                        return new Promise(function(resolve) {
                            resolve(_this);
                        });
                    },
                    createSpriteDefs: function () {
                       this.defs = this.svg.append('defs')
                            .attr('id', 'sprites');
                    },
                    getWidth: function () {
                        return this.width;
                    },
                    getHeight: function () {
                        return this.height;
                    },
                    renderSprite: function (spriteData) {

                        var id = spriteData.sprite.data.id,
                            definition = d3.select('#' + id);
                            // is '#<id>' sufficient? namespace? '#t2spr-<id>' ?

                        if (definition.empty()) {

                            var data = spriteData.sprite.data,
                                spriteEl = this.defs.append('symbol')
                                    .attr('viewBox', vbox(data.w, data.h))
                                    .attr('id', id);

                            // TODO: add elements to sprite in the order defined
                            //   when the sprite was created (layered bottom up)
                            //   e.g. (1) rect, (2) path, (3) rect...
                            //   not in groups by type.
                            //   For now, assume rectangles are behind paths...

                            // draw rectangles before paths
                            _.each(spriteData.sprite.rects, function (rect) {
                                spriteEl.append('rect')
                                    .attr('width', rect.w)
                                    .attr('height', rect.h)
                                    .attr('x', rect.x)
                                    .attr('y', rect.y)
                                    .style('fill', ts.spriteColor(rect.o.fill, 'fill'))
                                    .style('stroke', ts.spriteColor(rect.o.stroke, 'stroke'));
                            });

                            // draw paths after rectangles
                            _.each(spriteData.sprite.paths, function (path) {
                                spriteEl.append('path')
                                    .attr('d', path.d)
                                    .style('fill', ts.spriteColor(path.o.fill, 'fill'))
                                    .style('stroke', ts.spriteColor(path.o.stroke, 'stroke'));
                            });
                        }

                        return spriteEl;
                    },
                    renderLayout: function () {

                        var _this = this;
                        var layout = this.container.append('svg')
                            .attr('class', layout)
                            .attr('viewBox', vbox(this.layout.data.w, this.layout.data.h));

                        _.each(this.layout.sprites, function (spriteData) {
                            _this.renderSprite(spriteData);

                            layout
                                .append('g')
                                .append("use")
                                .attr('xlink:href', '#rack')
                                .attr('width', 20)
                                .attr('height', 25)
                                .attr('x', spriteData.x)
                                .attr('y', spriteData.y);
                        });
                    },
                    renderGrid: function () {

                        var layout = this.container.select('svg').append('g');

                        var gridSpacing = 5,
                            x = this.width / gridSpacing,
                            y = this.height / gridSpacing,
                            i, l;

                        for (i = 0, l = x; i < l; i++) {
                            layout.append('rect')
                                .attr('width', 0.1)
                                .attr('height', this.height)
                                .attr('x', i * gridSpacing)
                                .attr('y', 0);
                        }

                        for (i = 0, l = y; i < l; i++) {
                            layout.append('rect')
                                .attr('height', 0.1)
                                .attr('width', this.width)
                                .attr('y', i * gridSpacing)
                                .attr('x', 0);
                        }
                    }
                });

                function getInstance() {
                    return instance || new SpriteLayer();
                }

                return getInstance();
            }
        ])
 })();