text: (function () {
      'use strict';
  
      var pluginName = 'vdb-bench.widgets';
      var pluginDirName = 'vdb-bench-widgets';
  
      angular
          .module(pluginName)
          .directive('jdbcFilterOptions', JdbcFilterOptions);
  
      JdbcFilterOptions.$inject = ['CONFIG', 'SYNTAX'];
      JdbcFilterOptionsController.$inject = ['$scope', '$rootScope', '$document', '$translate', 'RepoRestService', 
                                             'REST_URI', 'SYNTAX', 'JDBC_FILTER', 'ConnectionSelectionService'];
  
      function JdbcFilterOptions(config, syntax) {
          var directive = {
              restrict: 'E',
              scope: {},
              controller: JdbcFilterOptionsController,
              controllerAs: 'vm',
              templateUrl: config.pluginDir + syntax.FORWARD_SLASH +
                  pluginDirName + syntax.FORWARD_SLASH +
                  'jdbcFilterOptions.html'
          };
  
          return directive;
      }
  
      function JdbcFilterOptionsController($scope, $rootScope, $document, $translate, RepoRestService, 
                                           REST_URI, SYNTAX, JDBC_FILTER, ConnectionSelectionService) {
          var vm = this;
  
          vm.selectedConn = null;
          vm.optionsResetting = false;
          vm.jdbcConnectionSelected = false;
          vm.initialNodeSelection = null;
          vm.initialExpandedNodes = null;
          vm.supportsCatalogOrSchema = true;
          vm.tablesLoading = false;
          vm.tables = [];
          vm.allTables = [];
          vm.hasTableFetchError = false;
          vm.tableFetchErrorMsg = "";
          vm.treedata = [];
          vm.treeLoading = false;
          vm.hasTreeFetchError = false;
          vm.treeFetchErrorMsg = "";
          vm.selectedTreeNode = null;
          vm.catalogFilter = JDBC_FILTER.BLANK;
          vm.schemaFilter = JDBC_FILTER.BLANK;
          vm.tableFilter = JDBC_FILTER.WILD_CARD;
  
          /*
           * Set initial source selection
           */
          $document.ready(function () {
              resetFilterOptions();
          });
  
          /*
           * Request to reset the filters
           */
          $scope.$on('resetJdbcFilters', function (event) {
              resetFilterOptions();
          });
  
          function resetFilterOptions() {
              vm.optionsResetting = true;
              vm.selectedConn = ConnectionSelectionService.selectedConnection();
  
              // Initialize filters if available
              var filterProperties = ConnectionSelectionService.selectedConnectionFilterProperties();
              vm.catalogFilter = JDBC_FILTER.BLANK;
              vm.schemaFilter = JDBC_FILTER.BLANK;
              vm.tableFilter = JDBC_FILTER.WILD_CARD;
              if(angular.isDefined(filterProperties) && filterProperties.length > 0) {
                  for(var key in filterProperties) {
                      var propName = filterProperties[key].name;
                      var propValue = filterProperties[key].value;
                      if(propName==JDBC_FILTER.KEY_CATALOG) {
                          vm.catalogFilter = propValue;
                      } else if(propName==JDBC_FILTER.KEY_SCHEMA_PATTERN) {
                          vm.schemaFilter = propValue;
                      } else if(propName==JDBC_FILTER.KEY_TABLE_NAME_PATTERN) {
                          vm.tableFilter = propValue;
                      }
                  }
              }
              // Reset the filter patterns
              updateFilterProperties(vm.catalogFilter,vm.schemaFilter,vm.tableFilter);
  
              // Determine if the selected connection is jdbc
              if(vm.selectedConn !== null && vm.selectedConn.dv__type === true) {
                  vm.jdbcConnectionSelected = true;
                  updateCatalogSchemaTree(vm.selectedConn);
              } else {
                  vm.tables = [];
                  vm.allTables = [];
                  vm.treedata = [];
                  vm.jdbcConnectionSelected = false;
                  vm.optionsResetting = false;
              }
          }
  
          // Builds the tree control data.  The tree control is expecting data in this form
          //    	vm.treedata =
          //    	[
          //    	    { "name" : "Catalog1", "type" : "Catalog", "children" : [
          //    	        { "name" : "Cat1Schema1", "type" : "Schema", "children" : [] },
          //    	        { "name" : "Cat1Schema2", "type" : "Schema", "children" : [] }
          //    	    ]},
          //    	    { "name" : "Catalog2", "type" : "Catalog", "children" : [
          //    	        { "name" : "Cat2Schema1", "type" : "Schema", "children" : [] },
          //    	        { "name" : "Cat2Schema2", "type" : "Schema", "children" : [] }
          //    	    ]},
          //    	    { "name" : "Catalog3", "type" : "Catalog", "children" : [] }
          //    	];
          function updateCatalogSchemaTree(connection) {
              vm.supportsCatalogOrSchema = true; // shows empty tree container while loading
  
              // Update the catalog - schema tree
              vm.tables = [];
              vm.allTables = [];
              vm.treeLoading = true;
              vm.hasTreeFetchError = false;
              try {
                  RepoRestService.getJdbcConnectionCatalogSchemaInfo( connection.keng__id ).then(
                      function ( result ) {
                          var hasCatalogs = false;
                          if(result.length === 0) {
                              vm.treedata = [];
                              vm.supportsCatalogOrSchema = false;
                          } else {
                              var treeInfo = [];
                              vm.supportsCatalogOrSchema = true;
                              for (var r = 0; r < result.length; ++r) {
                                  var schemaKids = result[r].schemaNames;
                                  var kids = [];
                                  if(!angular.isUndefined(schemaKids) && result[r].schemaKids !== null) {
                                      for(var i = 0; i < schemaKids.length; ++i) {
                                          var kid = {
                                              name : schemaKids[i],
                                              type : JDBC_FILTER.SCHEMA,
                                              parent : result[r].name,
                                              children : []
                                          };
                                          kids.push(kid);
                                      }
                                  }
                                  var resultItem = {
                                      name : result[r].name,
                                      type : result[r].type,
                                      parent : null,
                                      children : kids
                                  };
                                  if(result[r].type === JDBC_FILTER.CATALOG) {
                                      hasCatalogs = true;
                                  }
                                  // teiid handling - dont show SYS, SYSADMIN, pg_catalog schemas
                                  if(connection.dv__driverName === "teiid") {
                                      if(resultItem.type==="Schema" && 
                                          (resultItem.name!=="SYS" && resultItem.name!=="SYSADMIN" && resultItem.name!=="pg_catalog")) {
                                          treeInfo.push(resultItem);
                                      }
                                  } else {
                                      treeInfo.push(resultItem);
                                  }
                              }
                              // filters available - use to set initial selections
                              if(vm.catalogFilter!==JDBC_FILTER.BLANK || vm.schemaFilter!==JDBC_FILTER.BLANK) {
                                  determineExpandedAndSelectedNodesUsingFilters(treeInfo,vm.catalogFilter,vm.schemaFilter);
                                  updateTableListUsingSelections();
                              } else {
                                  var userName = null;
                                  if(angular.isDefined(connection.keng__properties)) {
                                      for(var key in connection.keng__properties) {
                                          var propName = connection.keng__properties[key].name;
                                          var propValue = connection.keng__properties[key].value;
                                          if(propName==JDBC_FILTER.USER_NAME) {
                                              userName = propValue;
                                              break;
                                          }
                                      }
                                  }
                                  determineExpandedAndSelectedNodesUsingUsername(treeInfo, userName);
                              }
                              vm.treedata = treeInfo;
                          }
                          vm.optionsResetting = false;
                          vm.treeLoading = false;
  
                          if(vm.initialNodeSelection !== null && hasCatalogs === false) {
                              vm.setTreeSelection(vm.initialNodeSelection, true);
                          }
                      },
                      function (response) {
                          vm.optionsResetting = false;
                          vm.treeLoading = false;
                          vm.treedata = [];
                          vm.hasTreeFetchError = true;
                          vm.treeFetchErrorMsg = RepoRestService.responseMessage(response);
                      });
              } catch (error) {
                  vm.optionsResetting = false;
                  vm.treeLoading = false;
                  vm.treedata = [];
                  vm.hasTreeFetchError = true;
                  vm.treeFetchErrorMsg = error.message;
              } finally {
              }
          }
  
          /**
           * Determines the nodes to expand and the node selections in the tree
           */
          function determineExpandedAndSelectedNodesUsingFilters(treeInfo, catalogFilter, schemaFilter) {
              vm.initialExpandedNodes = [];
              vm.initialNodeSelection = null;
              for (var r = 0; r < treeInfo.length; ++r) {
                  // Expand the catalogs
                  if(treeInfo[r].type === JDBC_FILTER.CATALOG) {
                      if(angular.isDefined(catalogFilter) && catalogFilter !== null) {
                          if(treeInfo[r].name.toUpperCase() === catalogFilter.toUpperCase()) {
                              vm.initialExpandedNodes.push(treeInfo[r]);
                              if(angular.isDefined(treeInfo[r].children) && treeInfo[r].children.length>0) {
                                  for(var c = 0; c <treeInfo[r].children.length; ++c) {
                                      if(treeInfo[r].children[c].name.toUpperCase() === schemaFilter.toUpperCase()) {
                                          vm.initialNodeSelection = treeInfo[r].children[c];
                                          break;
                                      }
                                  }
                              } else if(treeInfo[r].name.toUpperCase() === catalogFilter.toUpperCase()){
                                  vm.initialNodeSelection = treeInfo[r];
                              }
                          }
                      }
                  } else if(treeInfo[r].type === JDBC_FILTER.SCHEMA) {
                      if(angular.isDefined(schemaFilter) && schemaFilter !== null) {
                          if(treeInfo[r].name.toUpperCase() === schemaFilter.toUpperCase()) {
                              vm.initialNodeSelection = treeInfo[r];
                          }
                      }
                  }
              }
          }
  
          /**
           * Determines the nodes to expand and the node selections in the tree
           */
          function determineExpandedAndSelectedNodesUsingUsername(treeInfo, userName) {
              vm.initialExpandedNodes = [];
              vm.initialNodeSelection = null;
              for (var r = 0; r < treeInfo.length; ++r) {
                  // Expand the catalogs
                  if(treeInfo[r].type === JDBC_FILTER.CATALOG) {
                      if(angular.isDefined(userName) && userName !== null) {
                          if(treeInfo[r].name.toUpperCase() === userName.toUpperCase()) {
                              vm.initialExpandedNodes.push(treeInfo[r]);
                          }
                      }
                  } else if(treeInfo[r].type === JDBC_FILTER.SCHEMA) {
                      if(angular.isDefined(userName) && userName !== null) {
                          if(treeInfo[r].name.toUpperCase() === userName.toUpperCase()) {
                              vm.initialNodeSelection = treeInfo[r];
                          }
                      }
                  }
              }
          }
          
          /**
           * Set the tree selection when node is selected
           */
          vm.setTreeSelection = function(theNode, isSelected) {
              vm.selectedTreeNode = theNode;
              vm.catalogFilter = JDBC_FILTER.BLANK;
              vm.schemaFilter = JDBC_FILTER.BLANK;
  
              // If this is a leaf node, update the tables list
              if( angular.isDefined(vm.selectedTreeNode) && vm.selectedTreeNode!==null && vm.selectedTreeNode.children.length===0 && isSelected) {
                  // Catalog and Schema Filter based on node selection
                  if(vm.selectedTreeNode.type === JDBC_FILTER.SCHEMA) {
                      vm.schemaFilter = vm.selectedTreeNode.name;
                      if(vm.selectedTreeNode.parent !== null) {
                          vm.catalogFilter = vm.selectedTreeNode.parent;
                      }
                  } else if(vm.selectedTreeNode.type === JDBC_FILTER.CATALOG) {
                      vm.catalogFilter = vm.selectedTreeNode.name;
                  }
                  updateFilterProperties(vm.catalogFilter, vm.schemaFilter, vm.tableFilter);
                  // Update the table list
                  updateTableListUsingSelections();
              } else {
                  updateFilterProperties(vm.catalogFilter, vm.schemaFilter, vm.tableFilter);
                  vm.allTables = [];
                  vm.tables = [];
                  // Broadcast the loading value for any interested clients
                  $rootScope.$broadcast("jdbcFilterOptionTablesChanged", 0);
              }
          };
  
          function updateTableListUsingSelections() {
              // Update the table list
              var tblFilter = JDBC_FILTER.BLANK;
              if(vm.tableFilter === null || vm.tableFilter === JDBC_FILTER.BLANK) {
                  tblFilter = JDBC_FILTER.WILD_CARD;
              } else {
                  tblFilter = vm.tableFilter;
              }
              updateTableNames(vm.catalogFilter, vm.schemaFilter, tblFilter, vm.selectedConn);
          }
  
          function updateTableNames(catFilter, schFilter, tblFilter, connection) {
              vm.hasTableFetchError = false;
              vm.tableFetchErrorMsg = "";
              vm.tablesLoading = true;
              if(connection === null) {
                  vm.allTables = [];
                  vm.tables = [];
                  vm.tablesLoading = false;
                  vm.hasTableFetchError = true;
                  vm.tableFetchErrorMsg = $translate.instant('jdbcFilterOptions.tableFetchNoConnectionErrorMsg');
                  return;
              }
  
              // Update the tables using the Repo scratch object
              try {
                  RepoRestService.getJdbcConnectionTables( catFilter, schFilter, tblFilter, connection.keng__id ).then(
                      function ( result ) {
                          var tableNames = [];
                          var i = 1;
                          var tableKey = 'Table'+i;
                          var tableName = result.Information[tableKey];
                          while ( !angular.isUndefined(tableName) && tableName !== null) {
                              tableNames.push(tableName);
                              i++;
                              tableKey = 'Table'+i;
                              tableName = result.Information[tableKey];
                          }                        
                          vm.allTables = tableNames;
                          vm.tables = vm.allTables;
                          vm.tablesLoading = false;
                          // Broadcast the loading value for any interested clients
                          $rootScope.$broadcast("jdbcFilterOptionTablesChanged", tableNames.length);
                      },
                      function (response) {
                          vm.hasTableFetchError = true;
                          vm.tableFetchErrorMsg = RepoRestService.responseMessage(response);
                          vm.tablesLoading = false;
                          // Broadcast the loading value for any interested clients
                          $rootScope.$broadcast("jdbcFilterOptionTablesChanged", 0);
                      });
              } catch (error) {
                  vm.tablesLoading = false;
                  vm.hasTableFetchError = true;
                  vm.tableFetchErrorMsg = error.message;
                  // Broadcast the loading value for any interested clients
                  $rootScope.$broadcast("jdbcFilterOptionTablesChanged", 0);
              } finally {
              }
          }
  
          function updateFilterProperties(catalog, schemaPattern, tablePattern) {
              // Basic properties
              ConnectionSelectionService.resetFilterProperties();
  
              // Add catalog pattern
              if(catalog!==null) {
                  ConnectionSelectionService.setFilterProperty(JDBC_FILTER.KEY_CATALOG, catalog);
              }
  
              // Add schema Pattern
              if(schemaPattern!==null) {
                  ConnectionSelectionService.setFilterProperty(JDBC_FILTER.KEY_SCHEMA_PATTERN, schemaPattern);
              }
  
              // Add table Pattern
              var tblPattern = JDBC_FILTER.BLANK;
              if(tablePattern===null || tablePattern.length===0) {
                  tblPattern = JDBC_FILTER.WILD_CARD;
              } else {
                  tblPattern = tablePattern;
              }
              ConnectionSelectionService.setFilterProperty(JDBC_FILTER.KEY_TABLE_NAME_PATTERN, tablePattern);
          }
  
          /**
           * handler for refresh of filter text
           */
          vm.tableFilterRefresh = function() {
              updateFilterProperties(vm.catalogFilter, vm.schemaFilter, vm.tableFilter);
              updateTableListUsingSelections();
          };
  
          /**
           * Filter checkbox selection changed.
           */
          vm.filterCheckboxChanged = function( ) {
              updateCatalogSchemaTree(vm.selectedConn);
          };
  
          /**
           * Access to the collection of filtered data services
           */
          vm.getTables = function() {
              return vm.tables;
          };
  
          /**
           * Access to the collection of filtered data services
           */
          vm.getAllTables = function() {
              return vm.allTables;
          };
  
          /**
           * List Configuration
           */
          vm.listConfig = {
            showSelectBox: false,
            multiSelect: true,
            checkDisabled: false
          };
  
      }
  
  })();
  