view.cmp.TagField = (function(){

  const TagField = function( data ){
    Observable.call( this );
    var field, isFocused = false, lastVal, dropDown;

    //var cacheTagsDom = {};
    var offset = 0;
    var matchedItems = 0;
    var neBlur = false;
    var autocomplete = ( e ) => {
      offset = 0;
      var val = field.value.trim().toLowerCase();
      if( lastVal !== val ){

        var matched = val === '' ? [] : dP.tags.filter( t => t.name.toLowerCase().trim() !== val && t.name.toLowerCase().trim().indexOf( val ) > -1 ).slice( 0, 20 );
        this.value = lastVal = val;
        matchedItems = matched.length;
        D.removeChildren( dropDown );
        matched.forEach( function( match ){
          D.appendChild( dropDown, div( {
              cls: 'cmp-tag-dropdown-item',
              on: {
                click: () => {
                  field.value = match.name;
                  autocomplete();
                },
                mousedown: () => {
                  neBlur = true;
                  setTimeout( () => neBlur = false, 40 )
                  clearTimeout( blurTimeout )
                }
              }
            },
            view.cmp.Table.prototype.highlight.call( {
              filterText: val,
              filterRegExp: new RegExp( val, 'ig' )
            }, match.name ) ) );//cacheTagsDom[match.id] || (cacheTagsDom[match.id] = );
        } );
        dropDownUpdateCls();
      }

    };
    var _dropDownUpdateCls,
      dropDownUpdateCls = function(){
        _dropDownUpdateCls(
          D.cls( 'cmp-tag-dropdown', {
            'cmp-tag-dropdown__hidden': matchedItems === 0 || isFocused === false
          } )
        )
      };
    var blurTimeout;
    var el = div( { cls: 'cmp-tag-field' },
      field = D.input( {
        cls: 'cmp-tag-input',
        attr: { placeholder: 'Тэг' },
        on: {
          input: autocomplete,
          focus: () => {
            clearTimeout( blurTimeout );
            isFocused = true;
            dropDownUpdateCls()
          },
          blur: () => {
            if( !neBlur ){
              blurTimeout = setTimeout( function(){
                isFocused = false;
                dropDownUpdateCls();
              }, 100 )
            }
          }
        }
      } ),
      dropDown = div( {
        cls: ( update ) => {
          _dropDownUpdateCls = update;
          dropDownUpdateCls();
        }
      } )
    );

    this.dom = el;
  };
  TagField.prototype = {
    getValue: function(){
      return this.value;
    }
  };
  TagField.prototype = Object.assign( new Observable, TagField.prototype );
  return TagField;
})();