/*
 * Copyright 2015 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 -- Our own Angular directives defined here.
 */

(function () {
    'use strict';

    angular.module('onosApp')

        // Create a resize directive, that we can apply to elements
        // so that they can respond to window resize events.
        .directive('resize', ['$window', 'FnService', function ($window, fs) {
            return {
                scope: {
                    offsetHeight: '@',
                    offsetWidth: '@',
                    notifier: '&'
                },
                link: function (scope, element) {
                    var elem = d3.select(element[0]);
                    scope.$watchCollection(function () {
                        return {
                            h: $window.innerHeight,
                            w: $window.innerWidth
                        };
                    }, function () {
                        var offH = scope.offsetHeight || 0,
                            offW = scope.offsetWidth || 0,
                            wsz = fs.windowSize(offH, offW);

                        elem.style({
                            height: wsz.height + 'px',
                            width: wsz.width + 'px'
                        });

                        if (fs.isF(scope.notifier)) {
                            scope.notifier();
                        }
                    });

                    angular.element($window).bind('resize', function () {
                        scope.$apply();
                    });
                }
            };
        }])


        // create icon directive, so that we can inject icons into
        // HTML tables etc.
        .directive('icon', ['IconService', function (is) {
            return {
                restrict: 'A',
                scope: {
                    iconId: '@',
                    iconSize: '@'
                },
                link: function (scope, element, attrs) {
                    attrs.$observe('iconId', function () {
                        var div = d3.select(element[0]);
                        div.selectAll('*').remove();
                        is.loadEmbeddedIcon(div, scope.iconId, scope.iconSize);
                    });
                }
            };
        }])

        // create a general ng-repeat complete notifier directive
        .directive('ngRepeatDone', [function () {
            return function (scope) {
                if (scope.$last) {
                    scope.$emit('LastElement');
                }
            };
        }]);
}());
