angular.module("app").directive("multiPropertyGrid", function($rootScope, $q, $timeout, UniqueIdGenerator) {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            instance : '=',
            title: '@',
            options : '=',
            onChange: '=',
            afterInit: '&',
            customId: '@'
        },
        templateUrl: "../app/directives/multiPropertyGrid/multiPropertyGrid.html",
        link: function (scope, element, attrs) {

            var pgDeferred = $q.defer();
            var loaded = false;

            scope.id = scope.customId ? scope.customId : UniqueIdGenerator.generateId();

            scope.propGridInstance = {};
            scope.type = null;

            scope.instance.setSettings = function(settings) {
                if(!settings) return;
                
                var method = settings.method;
                var params = settings.params;

                printPropertyGrid(method, params) 
            }

            scope.onTypeChange = function(type) {
                printPropertyGrid(type);
            }

            scope.afterPGInit = function() {
                loaded = true;
                pgDeferred.resolve();
                if(scope.afterInit) $timeout(scope.afterInit, 0, false);
            }

            scope.onPGChange = function(data) {
                scope.onChange(data);
            }

            function printPropertyGrid(type, params) {        
                if(loaded){
                    scope.propGridInstance.printNote("");
                    
                    var option = getOption(type);
                    if(!option) {
                        if(scope.options>0) {
                            printPropertyGrid(scope.options[0]);
                        }
    
                        return;
                    }
    
                    scope.type = type;
                    scope.propGridInstance.printNote(option.help);
                    
                    scope.propGridInstance.createFromXML(option.config, function() {                    
                        scope.propGridInstance.setValues(params);
                    });
    
                    try { scope.$digest(); } catch(err){}
                }
                else pgDeferred.promise.then(function(){
                    printPropertyGrid(type, params);
                });     
            }

            function getOption(type) {
                for(var i=0; i<scope.options.length; i++){
                    var option = scope.options[i];

                    if(option.class == type){
                        return option;
                    }
                }
            }

            scope.instance.getSelectedType = function() {
                return scope.type;
            }

            scope.instance.setSelectedType = function(type) {
                scope.onTypeChange(type);
            }

            scope.instance.getSelectedValues = function() {
                return scope.propGridInstance.getValues();
            }

            scope.instance.setPropertyValues = function(xmlDoc, methodObj) {
                if(loaded){
                    scope.propGridInstance.getValuesXml(xmlDoc, methodObj);
                } else {
                    pgDeferred.promise.then(function(){
                        scope.instance.setPropertyValues(xmlDoc, methodObj);
                    });
                }
            }

            scope.instance.printValueByConfig = function(xmlConfig, key, value) {
                if(loaded){
                    scope.propGridInstance.printValueByConfig(xmlConfig, key, value);
                } else {
                    pgDeferred.promise.then(function(){
                        scope.instance.printValueByConfig(xmlConfig, key, value);
                    });
                }
            }

            scope.$on("$destroy", function(){
                UniqueIdGenerator.removeId(scope.id);
            })
        }
    };
});
