/* global ngDefine: false, require: false */
/**
  Defines a widget to filter activity instances in the activity tree

  @name quickFilter
  @memberof cam.cockpit.directives
  @type angular.directive

  @author Valentin Vago <valentin.vago@camunda.com>

  @example
    <div cam-quick-filter
         state-filter
         name-filter
         holder-selector=".instance-tree"
         label-selector=".tree-node-group"
         item-selector=".tree-node-group">
    </div>
 */
ngDefine('cockpit.directives', ['jquery'], function(module, $) {
  'use strict';

  module.directive('camQuickFilter', function() {

    /**
      determine if an element has to be schown
     */
    function showElement(states, searched, $el) {
      if ($el.find('.selected').length) {
        return true;
      }

      if (!!states.canceled ||
          !!states.running ||
          !!states.completed) {
        if (
          (!states.canceled  && $el.hasClass('state-canceled'))  ||
          (!states.running   && $el.hasClass('state-running'))   ||
          (!states.completed && $el.hasClass('state-completed'))
        ) {
          return false;
        }
      }

      if (!searched) {
        return true;
      }

      var exp = new RegExp(searched, 'i');
      return exp.test($.trim($el.text()));
    }

    return {
      scope: {
        holderSelector: '@',
        labelSelector: '@',
        itemSelector: '@'
      },

      restrict: 'A',

      templateUrl: require.toUrl('./app/cockpit/directives/quick-filter.html'),

      link: function(scope, element, attrs) {
        if (!scope.holderSelector) {
          throw new Error('A holder-selector attribute must be specified');
        }
        if (!scope.labelSelector) {
          throw new Error('A label-selector attribute must be specified');
        }
        if (!scope.itemSelector) {
          throw new Error('A item-selector attribute must be specified');
        }

        scope.$root.$on('instance-tree-selection-change', function() {
          // wait a bit to prevent
          setTimeout(scope.search, 200);
        });

        var $holder = $(scope.holderSelector);

        // activate (or not) a input (name or state)
        // if the relevant attribute is present (might be empty)
        scope.showNameFilter = typeof attrs.nameFilter !== 'undefined';
        scope.showStateFilter = typeof attrs.stateFilter !== 'undefined';

        scope.search = function() {
          var searched = scope.showNameFilter ? $.trim(scope.quickFilters.name.$viewValue) : '';
          var states = {
            running: !!scope.showStateFilter && !!scope.quickFilters.running.$viewValue,
            canceled: !!scope.showStateFilter && !!scope.quickFilters.canceled.$viewValue,
            completed: !!scope.showStateFilter && !!scope.quickFilters.completed.$viewValue
          };

          $(scope.itemSelector, $holder).each(function() {
            var $el = $(this);
            var visible = showElement(states, searched, $el);
            $el[visible ? 'show' : 'hide']();
          });
        };

        scope.clearName = function() {
          scope.quickFilters.name.$setViewValue('');
          scope.quickFilters.name.$render();
          scope.search();
        };
      }
    };
  });
});

@@ -2485,16 +2485,43 @@
 eFilter 
+&& scope.quickFilters.name 
 ? $.trim
@@ -2627,32 +2627,64 @@
 owStateFilter &&
+ !!scope.quickFilters.running &&
  !!scope.quickFi
@@ -2749,32 +2749,65 @@
 owStateFilter &&
+ !!scope.quickFilters.canceled &&
  !!scope.quickFi
@@ -2874,32 +2874,66 @@
 owStateFilter &&
+ !!scope.quickFilters.completed &&
  !!scope.quickFi

add further null check