
 EditWhisper = function(a_properties) {
 /*
   id => name
   z_index
   width
   post: "repository.method"
 */
   try {
     this.id = a_properties.id
     this.e_whisper = document.getElementById(this.id); // div
     this.id_edit = a_properties.id_edit
     this.e_edit = document.getElementById(this.id_edit); // input
     this.default_to_whisper = a_properties.default_to_whisper ? a_properties.default_to_whisper : null;

//     this.e_edit.name = this.e_edit.id;
//     this.z_index = a_properties.z_index;
//     this.width = a_properties.width;
     this.call = a_properties.call;
     this.c_keyword_min_length = a_properties.keyword_min_length ? a_properties.keyword_min_length : 3;
     this.params = a_properties.params ? a_properties.params : null;
   }
   catch (e) {
     alert(e);
   }
   this.o_key_wait_timer = null;

//   this.e_whisper.className = 'whisper';
//   this.e_whisper.style.zIndex = this.z_index;

   this.e_edit.owner = this;
//   this.e_edit.style.width = this.width + 'px'; //?

   this.e_list = document.createElement('select');
   this.e_list.owner = this;
   this.e_list.size = 10;
   this.e_list.focused = false;
//   this.e_list.style.width = (this.width + 4) + 'px';

   this.attachEvent(this.e_edit, 'keyup', this.doKeyPress);
   this.attachEvent(this.e_edit, 'blur', this.doHideList);
   this.attachEvent(this.e_list, 'keypress', this.doListKey);
   this.attachEvent(this.e_list, 'click', this.doListSelect);
   this.attachEvent(this.e_list, 'focus', this.doListFocus);
   this.attachEvent(this.e_list, 'blur', this.doListBlur);
/**/
   this.visible(!false); //!!! false

   this.e_whisper.appendChild(this.e_list);

//   this.i_key_wait = 0;
//   this.i_keyword = '';
//   this.id_possible = 0;
//   this.onListSelect = a_onListSelect != 'undefined' ? a_onListSelect : null;
 }

 EditWhisper.prototype.visible = function(a_visible) {
   if (this.e_list.options.length < 2)
     this.e_list.size = 2;
   else if (this.e_list.options.length < 10)
     this.e_list.size = this.e_list.options.length;
   else
     this.e_list.size = 10;

   a_visible = a_visible && this.e_list.options.length > 0;
   this.e_list.style.display = a_visible ? 'block' : 'none';
 }

 EditWhisper.prototype.attachEvent = function(a_element, a_event_name, a_function) {
//alert('attachEvent');
   try {
//alert('on' + a_event_name +', ' + a_function);
     a_element.attachEvent('on' + a_event_name, a_function);
   }
   catch (e) {
     a_element.addEventListener(a_event_name, a_function, true);
   }
 }

 EditWhisper.prototype.doKeyPress = function(e) {

//alert('doKeyPress');

   var handle = e.srcElement ? e.srcElement.owner : this.owner;

   if (handle.e_edit.value.length == 0) {
     if (handle.default_to_whisper) {
       if (handle.e_list.style.display == 'none') {
         handle.o_key_wait_timer = setTimeout('EditWhisper.prototype.doDefaultWhisper.call(this, \'' + handle.e_edit.id + '\');', 200);
       }
       else if (e.keyCode == 38 || e.keyCode == 40) {
         handle.e_list.focus();
       }
     }
   }
   else if (handle.e_edit.value.length >= handle.c_keyword_min_length) {
     if (e.keyCode == 38 || e.keyCode == 40) {
       handle.e_list.focus();
     }
     else {
       if (handle.o_key_wait_timer != null)
         clearTimeout(handle.o_key_wait_timer);

       handle.o_key_wait_timer = setTimeout('EditWhisper.prototype.doRequest.call(this, \'' + handle.e_edit.id + '\');', 200);
     }
   }
   else if (handle.e_list.style.display == 'block')
     handle.visible(false);
 }

 EditWhisper.prototype.doDefaultWhisper = function(a_id_edit) {
   handle = document.getElementById(a_id_edit).owner;
   handle.requestCallback(handle.default_to_whisper, {id_edit: handle.id_edit});
 }

 EditWhisper.prototype.doRequest = function(a_id_edit) {

//alert('doRequest');

   handle = document.getElementById(a_id_edit).owner;

   if (handle.e_edit.value.length >= handle.c_keyword_min_length) {
     params = {call: handle.call, keywords: handle.e_edit.value};
     if (handle.params) {
       for (key in handle.params) {
         params[key] = handle.params[key];
       }
     }
     request(
       params,
       {method: handle.requestCallback, params: {id_edit: a_id_edit}}           // >> client side callback data
     );
   }
 }

 EditWhisper.prototype.requestCallback = function(a_data, a_params) {
   handle = document.getElementById(a_params.id_edit).owner;
   handle.clear();

   for (key in a_data) {
     if (a_data[key].text != undefined && a_data[key].value != undefined) {
       handle.add(key, a_data[key].text, a_data[key].value);
     }
   }
   handle.visible(true);
 }

 EditWhisper.prototype.doListKey = function(e) {
   if (e.keyCode == 13)
     EditWhisper.prototype.doListSelect.call(this, e);
 }

 EditWhisper.prototype.doListSelect = function(e) {
   var handle = e.srcElement ? e.srcElement.owner : this.owner;
   handle.e_edit.value = handle.e_list.options[handle.e_list.selectedIndex].value;
   handle.visible(false);

/*   if (handle.onListSelect) //??
     handle.onListSelect();*/
 }

 EditWhisper.prototype.doListFocus = function(e) {
   var handle = e.srcElement ? e.srcElement.owner : this.owner;
   handle.e_list.focused = true;
 }

 EditWhisper.prototype.doListBlur = function(e) {
   var handle = e.srcElement ? e.srcElement.owner : this.owner;
//   handle.e_edit.focus();
   handle.e_list.focused = false;
//   handle.i_key_wait = -1;
   handle.visible(false);
 }

 EditWhisper.prototype.doHideList = function(e) {
   var handle = e.srcElement ? e.srcElement.owner : this.owner;
   window.setTimeout('EditWhisper.prototype.doHideListLaged.call(this, \'' + handle.e_edit.id + '\');', 200);
 }

 EditWhisper.prototype.doHideListLaged = function(a_id_edit) {
   handle = document.getElementById(a_id_edit).owner;
//debug('hide list, ' + this.elementList.focused);
   if (handle.e_list.focused == false)
     handle.visible(false);
 }

 EditWhisper.prototype.clear = function() {
   this.e_list.options.length = 0;
 }

 EditWhisper.prototype.add = function(a_key, a_text, a_value) {
   var e_option = document.createElement('option');
   e_option.value = a_value;
   e_option.text = (a_text != undefined) ? a_text : a_key;
//   e_option.data = a_data;

   try {
     return this.e_list.add(e_option, null);
   }
   catch (e) {
     return this.e_list.add(e_option); // IE only
   }
 }

 EditWhisper.prototype.show = function() {
   this.visible(true);
   this.e_list.focus();
 }

