'use strict';

/*
 * ngInclude functionality but waits until a list of dependencies have resolved.
 *
 * = Directive args =
 * deps-ng-include = <path/to/template.html>
 * deps = <comma separated list of dependencies>
 *
 * == Example ==
 * <div deps-ng-include="'my_widget/template.html'" deps="ServiceX,ServiceY"></div>
 *
 * = Dependency Interface Sample =
 * // when ServiceX starts loading
 * var initDoneCallbacks = [];
 * ...
 * // public facing function
 * init: function () {
 *     var progress = $q.defer();
 *     if (serviceIsReady) {
 *         progress.resolve({});
 *     } else {
 *         initDoneCallbacks.push(function () {
 *             progress.resolve({});
 *         });
 *     }
 *     return progress.promise;
 * }
 * ...
 * // when ServiceX finishes loading
 * initDoneCallbacks.forEach(function (func){
 *      func();
 * });
 */
myApp.directive('depsNgInclude',
    ['$q', '$injector',
    function ($q, $injector) {
        return {
            restrict: 'A',
            replace: true,
            template: '<div ng-include="depsNgIncludeUrl"></div>',
            transclude: false,
            // need this to isolate scope
            scope: {
                depsNgIncludeUrl: '@',
                depsNgIncludeSrc: '&depsNgInclude'
            },
            // needs greater than 400 because want it to happen before ngInclude
            priority: 425,
            link: function(scope, element, attrs) {

                var depsNames = attrs.deps.split(','),
                    deps = depsNames.map(
                        function(name){
                            return $injector.get(name).init();
                        }
                    );

                $q.all(deps).then(function(){

                    scope.depsNgIncludeUrl = scope.depsNgIncludeSrc();

                    scope.$watch('depsNgIncludeSrc()',function(){
                        scope.depsNgIncludeUrl = scope.depsNgIncludeSrc();
                    });
                });
            }
        };
    }]
);