/*
 * 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', [
            'Topo2ViewController', 'SpriteService',

            function (ViewController, ss) {

                var SpriteLayer = ViewController.extend({

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

                    init: function(svg, zoomLayer) {
                        this.svg = svg;
                        this.createSpriteDefs();
                        this.container = zoomLayer.append('g').attr('id', this.id);
                    },
                    loadLayout: function (id) {
                        this.container.selectAll("*").remove();
                        this.layout = ss.layout(id);

                        this.width = this.layout.data.w;
                        this.height = this.layout.data.h;

                        this.renderLayout();
                    },
                    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);

                        if (definition.empty()) {

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

                            _.each(spriteData.sprite.paths, function (path) {
                                spriteEl.append('path')
                                    .attr('d', path)
                                    .style('fill', 'none')
                                    .style('stroke', 'black');
                            });

                            _.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', 'rgba(0,0,0,0.5)')
                            });
                        }

                        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);
                        });
                    }
                });

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

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