Перем мИмяНомерСтроки;
Перем ПодходящиеСлова;
Перем СтрокаСловаРезультата Экспорт;
Перем ВКОбщая Экспорт;
Перем мЧислоВидимыхСтрок;
Перем мФоновыйЗапросХттп;

Процедура ОбновлениеОтображения()
	Если ВКОбщая <> Неопределено Тогда
		Если ВКОбщая <> Null Тогда
			РазрешитьВыходЗаГраницыЭкрана = Не (МодальныйРежим Или ПараметрАктивизировать);
			ПоверхВсехОкон = ирОбщий.ЛиЕстьМодальныеГруппыЛкс() Или ирКэш.ЛиСеансТолстогоКлиентаУПЛкс();
			ВКОбщая.ПереместитьОкноВПозициюКаретки(РазрешитьВыходЗаГраницыЭкрана, ПоверхВсехОкон, Заголовок);
		КонецЕсли;
		ВКОбщая = Неопределено;
		Если Не ПараметрАктивизировать Тогда
			АктивироватьВладельца(ЭтаФорма);
		КонецЕсли;
		УстановитьГраницыВыделенияФильтра();
	КонецЕсли;
	ЭтаФорма.ПараметрАктивизировать = Ложь;
КонецПроцедуры

// Надо вызывать до начала открытия (до ПередОткрытием), иначе недоступность формы-владельца будет сброшена
Процедура ЗапомнитьПозициюКаретки() Экспорт
	Если Не ирКэш.ЛиПлатформаWindowsЛкс() Тогда
		ВКОбщая = Null;
		Возврат;
	КонецЕсли;
	ВКОбщая = ирОбщий.НоваяВКОбщаяЛкс();
	ОбработкаПрерыванияПользователя();
	Если ВКОбщая <> Неопределено Тогда
		#Если Сервер И Не Сервер Тогда
			ПолеТекста = Обработки.ирОболочкаПолеТекста.Создать();
		#КонецЕсли
		ПолеТекста.ПолучитьПозициюКаретки(ВКОбщая, ФормаВладелец);
	КонецЕсли;
КонецПроцедуры

Процедура ПодходящиеСловаВыбор(Элемент, ВыбраннаяСтрока, Колонка = Неопределено, СтандартнаяОбработка = Истина)
	// Было закомментировано для https://www.hostedredmine.com/issues/1001061
	ЭтаФорма.СтрокаСловаРезультата = ВыбраннаяСтрока;
	ЗакрытьИВставитьСлово();
КонецПроцедуры

Процедура ЗакрытьИВставитьСлово(ПараметрЗакрытия = Истина) Экспорт
	Если МодальныйРежим Тогда
		Если Не Открыта() Тогда
			ОповеститьОВыборе(Истина); // Аналог Закрыть(), но Закрыть() нельзя здесь вызывать
		Иначе
			Закрыть(ПараметрЗакрытия);
		КонецЕсли;
	Иначе
		Если Открыта() Тогда
			Закрыть();
			СтрокаНапарника = СтрокаСловаНапарника();
			Если Истина
				И СтрокаСловаРезультата = СтрокаНапарника 
				И (Ложь
					Или СтрокаНапарника.Слово = СтатусИИНеЗнает()
					Или СтрокаНапарника.Слово = СтатусИИДумает())
			Тогда
				Возврат;
			КонецЕсли;
			ВариантАвтоВызова = ВставитьВыбранноеСловоАвтодополнения(СтрокаСловаРезультата,, ПараметрЗакрытия);
			//ТекстПредупреждения = ПроверитьСовместимостьТипаЗначенияСлова(СтрокаСловаРезультата);
			//Если ЗначениеЗаполнено(ТекстПредупреждения) Тогда
			//  // Не нашел способа быстро и удобно показать рядом с кареткой
			//КонецЕсли;
			Если ВариантАвтоВызова = 1 Тогда
				ОткрытьАвтодополнение("я"); // Автовызов
				ОбновитьФормуАвтодополнения();
			ИначеЕсли ВариантАвтоВызова = 2 Тогда
				ОткрытьАвтодополнение(ирКэш.КодыКлавишЛкс()["ctrl+space"],, СтрокаСловаРезультата = СтрокаНапарника); // Так будет обязательное открытие. Вредно внутри ненадежного текстового литерала и комментария
				ОбновитьФормуАвтодополнения();
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Процедура НайтиПодходящиеСлова(Знач СброситьТекущуюСтроку = Истина)
	ЭлементОтбора = ЭлементыФормы.ТаблицаСлов.ОтборСтрок.ПремияФильтра;
	ЭлементОтбора.ВидСравнения = ВидСравнения.Больше;
	ЭлементОтбора.Значение = 0;
	СтрокаМаксимальногоРейтинга = Неопределено;
	выхЛиНашли = Ложь;
	Если ЭлементыФормы.ДействияФормы.Кнопки.ПереключитьОтборИСортировку.Пометка Тогда
		Если ЛиАвтодополнениеНапарника() Или ПродолжатьСловоНапарника Тогда
			СтрокаСловаНапарника = СтрокаСловаНапарника();
		КонецЕсли;
		Если СтрокаСловаНапарника <> Неопределено Тогда
			СтароеСловоНапарника = СтрокаСловаНапарника.Слово;
			СтрокаСловаНапарника.Слово = "";
		КонецЕсли;
		ВыделениеРезультатовПоиска = мПлатформа.ВыделениеРезультатовПоиска;
		Для Каждого Строка Из ТаблицаСлов Цикл
			Строка.ПремияФильтра = ирОбщий.НайтиФильтрВСловеЛкс(Ложь, ТекущееСлово, Строка.Слово, Строка.НСлово,, ВыделениеРезультатовПоиска);
		КонецЦикла;
		ИмяНомерСтроки = ирОбщий.ПеревестиСтроку("НомерСтроки");
		ЭлементОтбора.Использование = Истина;
		Если СтрокаСловаНапарника <> Неопределено Тогда
			СтрокаСловаНапарника.ПремияФильтра = 10;
			СтрокаСловаНапарника.Слово = СтароеСловоНапарника;
		КонецЕсли;
		ТаблицаСлов.Сортировать("ПремияФильтра Убыв, Рейтинг Убыв, НСлово, ТипСлова");
		ВременныйПостроительЗапроса = ирКлиент.ПостроительТабличногоПоляСОтборомКлиентаЛкс(ЭлементыФормы.ТаблицаСлов);
		ВременныйПостроительЗапроса.ВыбранныеПоля.Очистить();
		ВременныйПостроительЗапроса.ВыбранныеПоля.Добавить(ИмяНомерСтроки);
		ПодходящиеСлова = ВременныйПостроительЗапроса.Результат.Выгрузить();
		Если СброситьТекущуюСтроку И ПодходящиеСлова.Количество() Тогда
			ИндексЛучшего = 0;
			Если Истина
				И СтрокаСловаНапарника <> Неопределено
				И ПодходящиеСлова.Количество() > 1
				И Не ПродолжатьСловоНапарника
			Тогда
				ИндексЛучшего = ИндексЛучшего + 1;
			КонецЕсли;
			ТекущаяСтрока = ТаблицаСлов.Найти(ПодходящиеСлова[ИндексЛучшего][ИмяНомерСтроки], "НомерСтроки");
			ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока = ТекущаяСтрока;
		КонецЕсли;
		Если Автозакрытие И ПодходящиеСлова.Количество() = 0 Тогда
			Закрыть();
		КонецЕсли;
	Иначе
		ЭлементОтбора.Использование = Ложь;
		ТаблицаСлов.Сортировать("НСлово, ТипСлова");
		Фильтр = НРег(ТекущееСлово);
		ДлинаФильтра = СтрДлина(Фильтр);
		ПодходящиеСлова = ТаблицаСлов;
		Для Каждого СтрокаСлова Из ПодходящиеСлова Цикл
			НСлово = СтрокаСлова.НСлово;
			Если СтрДлина(НСлово) < ДлинаФильтра Тогда
				Продолжить;
			КонецЕсли;
			Если Лев(СтрокаСлова.НСлово, ДлинаФильтра) = Фильтр Тогда
				выхЛиНашли = Истина;
				Если СтрокаМаксимальногоРейтинга = Неопределено Тогда
					СтрокаМаксимальногоРейтинга = СтрокаСлова;
					ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока = СтрокаСлова;
					Если Ложь
						//Или ДлинаТекущегоСлова = 0 // Мешает активировать при открытии строку с макс. рейтингом
						Или ДлинаФильтра = СтрДлина(СтрокаСлова.Слово)
					Тогда
						Прервать;
					КонецЕсли;
					ДлинаСловРейтинга = СтрДлина(СтрокаСлова.Слово);
				Иначе
					Если Истина
						//И СтрДлина(СтрокаСлова.Слово) <= ДлинаСловРейтинга  // Мешает активировать при открытии строку с макс. рейтингом
						И СтрокаМаксимальногоРейтинга.Рейтинг < СтрокаСлова.Рейтинг
					Тогда
						СтрокаМаксимальногоРейтинга = СтрокаСлова;
					КонецЕсли;
				КонецЕсли;
			ИначеЕсли выхЛиНашли Тогда
				Прервать;
			ИначеЕсли СтрокаСлова.НСлово > Фильтр Тогда
				Если СброситьТекущуюСтроку Тогда
					ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока = СтрокаСлова;
				КонецЕсли;
				Прервать;
			КонецЕсли;
		КонецЦикла;
		Если Не выхЛиНашли Тогда
			ЭлементыФормы.ТаблицаСлов.ВыделенныеСтроки.Очистить();
		КонецЕсли;
	КонецЕсли;
	ЭлементыФормы.ТаблицаСлов.Видимость = Истина;
КонецПроцедуры

Функция ОбработкаОбщихКлавиш(ПолеВвода, КодСочетанияКлавиш)
	СочетаниеОбработано = Ложь;
	КодыКлавиш = Неопределено;
	Если ТекущийЭлемент <> ЭлементыФормы.ТаблицаСлов Тогда
		Если ирОбщий.ПроверитьНажатиеКлавишЛкс(КодСочетанияКлавиш, "Down", КодыКлавиш) Тогда
			СочетаниеОбработано = Истина;
			Если ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока <> Неопределено Тогда
				Смещение = + 1;
				ИндексТекущейСтроки = ИндексТекущейСтрокиВПодходящихСловах();
				НовыйИндекс = Мин(ИндексТекущейСтроки + Смещение, ПодходящиеСлова.Количество() - 1);
				ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока = ТаблицаСлов[ПодходящиеСлова[НовыйИндекс][мИмяНомерСтроки] - 1];
			КонецЕсли;
		ИначеЕсли ирОбщий.ПроверитьНажатиеКлавишЛкс(КодСочетанияКлавиш, "Up", КодыКлавиш) Тогда
			УстановитьГраницыВыделенияФильтра(); // https://www.hostedredmine.com/issues/929384
			СочетаниеОбработано = Истина;
			Если ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока <> Неопределено Тогда
				Смещение = - 1;
				ИндексТекущейСтроки = ИндексТекущейСтрокиВПодходящихСловах();
				НовыйИндекс = Макс(ИндексТекущейСтроки + Смещение, 0);
				ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока = ТаблицаСлов[ПодходящиеСлова[НовыйИндекс][мИмяНомерСтроки] - 1];
			КонецЕсли;
		ИначеЕсли ирОбщий.ПроверитьНажатиеКлавишЛкс(КодСочетанияКлавиш, "PgDown", КодыКлавиш) Тогда
			СочетаниеОбработано = Истина;
			Если ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока <> Неопределено Тогда
				Смещение = + мЧислоВидимыхСтрок;
				ИндексТекущейСтроки = ИндексТекущейСтрокиВПодходящихСловах();
				НовыйИндекс = Мин(ИндексТекущейСтроки + Смещение, ПодходящиеСлова.Количество() - 1);
				ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока = ТаблицаСлов[ПодходящиеСлова[НовыйИндекс][мИмяНомерСтроки] - 1];
			КонецЕсли;
		ИначеЕсли ирОбщий.ПроверитьНажатиеКлавишЛкс(КодСочетанияКлавиш, "PgUp", КодыКлавиш) Тогда
			СочетаниеОбработано = Истина;
			Если ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока <> Неопределено Тогда
				Смещение = - мЧислоВидимыхСтрок;
				ИндексТекущейСтроки = ИндексТекущейСтрокиВПодходящихСловах();
				НовыйИндекс = Макс(ИндексТекущейСтроки + Смещение, 0);
				ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока = ТаблицаСлов[ПодходящиеСлова[НовыйИндекс][мИмяНомерСтроки] - 1];
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	Если ирОбщий.ПроверитьНажатиеКлавишЛкс(КодСочетанияКлавиш, "ENTER, =", КодыКлавиш) Тогда
		СочетаниеОбработано = Истина;
		Если Истина
			И ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока <> Неопределено
			И ЭлементыФормы.ТаблицаСлов.ВыделенныеСтроки.Содержит(ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока)
		Тогда
			ЭтаФорма.СтрокаСловаРезультата = ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока;
		Иначе
			ЭтаФорма.СтрокаСловаРезультата = НоваяСтруктураРезультата();
			ЭтаФорма.СтрокаСловаРезультата.Слово = ТекущееСлово;
			Если Не ЗначениеЗаполнено(ТекущееСлово) Тогда
				Закрыть();
				Возврат Истина;
			КонецЕсли;
		КонецЕсли;
		Если ирОбщий.ПроверитьНажатиеКлавишЛкс(КодСочетанияКлавиш, "ENTER", КодыКлавиш) Тогда
			ЗакрытьИВставитьСлово();
		Иначе
			ЗакрытьИВставитьСлово(" = ");
		КонецЕсли;
	ИначеЕсли ирОбщий.ПроверитьНажатиеКлавишЛкс(КодСочетанияКлавиш, ".", КодыКлавиш) Тогда 
		СочетаниеОбработано = Истина;
		ОткрытьДочерние();
	КонецЕсли;
	Если ЭтаФорма.Открыта() Тогда
		ЭтаФорма.ТекущийЭлемент = ПолеВвода;
	КонецЕсли;
	Возврат СочетаниеОбработано;
КонецФункции

Функция ИндексТекущейСтрокиВПодходящихСловах() Экспорт
	СтруктраОтбора = Новый Структура(мИмяНомерСтроки);
	ЗаполнитьЗначенияСвойств(СтруктраОтбора, ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока);
	Если ТипЗнч(ПодходящиеСлова) = Тип("ТаблицаЗначений") Тогда
		СтрокаПодходящегоСлова = ПодходящиеСлова.НайтиСтроки(СтруктраОтбора)[0];
	Иначе
		СтрокаПодходящегоСлова = ПодходящиеСлова[СтруктраОтбора[мИмяНомерСтроки] - 1];
	КонецЕсли;
	Возврат ПодходящиеСлова.Индекс(СтрокаПодходящегоСлова);
КонецФункции

Функция НоваяСтруктураРезультата() Экспорт
	Возврат Новый Структура("Слово, ТипСлова, Определение, ТипЗначения");
КонецФункции

Процедура ОткрытьДочерние()
	Если Истина
		И ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока <> Неопределено
		И ЭлементыФормы.ТаблицаСлов.ВыделенныеСтроки.Содержит(ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока)
	Тогда
		ЭтаФорма.СтрокаСловаРезультата = ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока;
		Закрыть(".");
	КонецЕсли;
КонецПроцедуры

Функция ЭлементУправленияTextBoxKeyDown(Элемент, КодСочетанияКлавиш)
	Результат = ОбработкаОбщихКлавиш(Элемент, КодСочетанияКлавиш);
	Возврат Результат;
КонецФункции

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
	ОтборПоСлову = ЭлементыФормы.ТаблицаСлов.ОтборСтрок.ПремияФильтра;
	ОтборПоСлову.ВидСравнения = ВидСравнения.Больше;
	ОтборПоСлову.Значение = 0;
	ОтборПоСлову.Использование = Истина;
	СтрокаСловаРезультата = Неопределено;
	Если МодальныйРежим Или ПараметрАктивизировать Тогда
		ПриИзмененииОтбора();
	КонецЕсли;
	Если Истина
		И СтрокаСловаРезультата <> Неопределено
		И СтрокаСловаРезультата = ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока
		И ирОбщий.СтрНачинаетсяСЛкс(СтрокаСловаРезультата.Слово, мКонтекст)
	Тогда
		Отказ = Истина;
	КонецЕсли;
	Если Отказ Тогда
		ЗакрытьИВставитьСлово();
	КонецЕсли;
КонецПроцедуры

Процедура ПриОткрытии()
	Если КлючУникальности = "Автотест" Тогда
		Возврат;
	КонецЕсли; 
	ирКлиент.Форма_ПриОткрытииЛкс(ЭтаФорма);
	мФоновыйЗапросХттп = ирКлиент.НовыйФоновыйЗапросХттпЛкс(ЭтаФорма);
	ЭлементыФормы.ДействияФормы.Кнопки.ПереключитьОтборИСортировку.Пометка = Истина;
	Если Ложь
		Или ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока = Неопределено
		Или Лев(ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока.НСлово, СтрДлина(ТекущееСлово)) <> НРег(ТекущееСлово)
	Тогда
		ЭлементыФормы.ТаблицаСлов.ВыделенныеСтроки.Очистить();
	КонецЕсли;
	ЭтаФорма.ТипКонтекста = ИмяТипаКонтекста();
	Если ТипКонтекста = "Строка" И ЗначениеЗаполнено(мСтруктураТипаКонтекста.ТипЯзыка) Тогда
		ЭтаФорма.ТипКонтекста = мСтруктураТипаКонтекста.ТипЯзыка;
	КонецЕсли;
	ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ТекущееСлово;
	//ЭлементыФормы.КоманднаяПанельФормы.Кнопки.ПерейтиКОпределению.Доступность = Истина
	//	И ЯзыкПрограммы = 1
	//	И Найти(ТипКонтекста, ".") > 0;
	//ЭтаФорма.Заголовок = "Контекст: " + Контекст;
	ЭтаФорма.Заголовок = "Тип: " + ТипКонтекста;
	Если ЗначениеЗаполнено(ОжидаемыйТип) Тогда
		ЭтаФорма.Заголовок = ЭтаФорма.Заголовок + " -> " + ОжидаемыйТип;
	КонецЕсли;
	Если Автозакрытие Тогда
		ПриИзмененииОтбора();
	КонецЕсли;
	Если Не ЗначениеЗаполнено(ТекущееСлово) И ирКлиент.ЛиПерехватКлавиатурногоВводаЛкс() Тогда
		ТекущееСлово = " "; // Чтобы пустое значение затем тоже вызвало изменение
		ЭлементыФормы.ТаблицаСлов.Видимость = Ложь;
		ЭлементыФормы.Описание.УстановитьТекст("");
	КонецЕсли; 
	#Если ТолстыйКлиентУправляемоеПриложение Тогда
		ПодключитьОбработчикОжидания("ПроверкаФокусаВводаВладельца", 2, Истина);;
	#КонецЕсли 
	Если ЛиАвтодополнениеНапарника() Или ПродолжатьСловоНапарника Тогда
		СтрокаСлова = ТаблицаСлов.Вставить(0);
		СтрокаСлова.ТипСлова = ПеречТипСлова.Конструкция;
		СтрокаСлова.ТипЗначения = "ИИ";
		КонтекстНапарника = мПлатформа.КонтекстНапарника();
		Если ПродолжатьСловоНапарника И ЗначениеЗаполнено(мОстатокСловаНапарника) Тогда
			СтрокаСлова.Слово = мОстатокСловаНапарника;
		Иначе
			СтрокаСлова.Слово = СтатусИИСпит();
			Интервал = ?(КонтекстНапарника.Соединение = Неопределено, 1, 0.1);
			ПодключитьОбработчикОжидания("ЗапуститьЗапросНапарникаВФорме", Интервал, Истина);
		КонецЕсли;
		мОстатокСловаНапарника = "";
	КонецЕсли;
	Если ирКэш.НомерИзданияПлатформыЛкс() > "83" Тогда
		ПодключитьОбработчикОжидания("АктивироватьВладельцаОтложенно", 0.3, Истина);
	КонецЕсли;
КонецПроцедуры

Процедура АктивироватьВладельцаОтложенно()
	АктивироватьВладельца(ЭтаФорма);
КонецПроцедуры

Функция СтатусИИСпит() Экспорт
	Возврат "ИИ -";
КонецФункции 

Функция СтатусИИДумает() Экспорт
	Возврат "ИИ ...";
КонецФункции 

Функция СтатусИИНеЗнает() Экспорт
	Возврат "ИИ не знает";
	//Возврат "ИИ Ø";
КонецФункции

Функция ЗапуститьЗапросНапарникаВФорме()
	СтрокаСловаНапарника = СтрокаСловаНапарника();
	Если Ложь
		Или СтрокаСловаНапарника = Неопределено 
		Или ТекущееСлово <> "" И ЛиСловоНапарникаПодходитФильтру()
		Или мФоновыйЗапросХттп = Неопределено
		Или Не Открыта() // Для подстраховки
	Тогда
		Возврат Ложь;
	КонецЕсли;
	мФоновыйЗапросХттп.ОтменитьЗапрос();
	РезультатСоединения = СоединениеНапарника();
	Если ТипЗнч(РезультатСоединения) = Тип("Строка") Тогда
		СтрокаСловаНапарника.Слово = РезультатСоединения;
		Возврат Ложь;
	КонецЕсли;
	ТелоЗапросаСтрока = ТелоЗапросаАвтодополненияНапарника();
	Если ПустаяСтрока(ТелоЗапросаСтрока) Тогда
		Возврат Ложь;
	КонецЕсли;
	СтрокаСловаНапарника.Слово = СтатусИИДумает();
	ЗапросНапарника = ирОбщий.ЗапросHTTPЛкс("/api/v1/complete");
	ЗапросНапарника.Заголовки = ЗаголовкиЗапросаНапарника(); 
	ЗапросНапарника.УстановитьТелоИзСтроки(ТелоЗапросаСтрока);
	Попытка
		ЗапроситьНапарникаАсинх(ЗапросНапарника, Истина, мФоновыйЗапросХттп);
	Исключение
		СтрокаСловаНапарника.Слово = "Ошибка:
		|" + ОписаниеОшибки();
	КонецПопытки;
	Возврат Истина;
КонецФункции 

Функция СтрокаСловаНапарника() Экспорт
	Если ТаблицаСлов.Количество() = 0 Тогда
		Возврат Неопределено;
	КонецЕсли;
	СтрокаСлова = ТаблицаСлов[0];
	Если СтрокаСлова.ТипЗначения <> "ИИ" Тогда
		Возврат Неопределено;
	КонецЕсли;
	Возврат СтрокаСлова;
КонецФункции 

Процедура СлужебноеПолеХТМЛonclick(Элемент, pEvtObj) Экспорт
	СтрокаСловаНапарника = СтрокаСловаНапарника();
	Если СтрокаСловаНапарника.Слово = СтатусИИНеЗнает() Тогда
		Возврат;
	КонецЕсли;
	ЛиПерваяЧасть = СтрокаСловаНапарника.Слово = СтатусИИДумает();
	ЛиПоследняяЧасть = мФоновыйЗапросХттп.ЛиПотокЗавершен();
	Если Истина
		И Не ЛиПерваяЧасть 
		И Не ЛиПоследняяЧасть
	Тогда
		Возврат;
	КонецЕсли;
	ЧастьОтвета = мФоновыйЗапросХттп.ПрочитатьЧастьОтвета();
	Если ЧастьОтвета = "" Тогда
		Возврат;
	КонецЕсли;
	Отказ = Ложь;
	Результат = ОбработатьОтветНапарника(ЧастьОтвета,, ЛиПерваяЧасть, ЛиПоследняяЧасть, Отказ);
	Если Отказ Тогда
		мФоновыйЗапросХттп.ОтменитьЗапрос();
		Если ПустаяСтрока(Результат) И ЛиПерваяЧасть Тогда
			Результат = СтатусИИНеЗнает();
		КонецЕсли;
		Если Не ЛиПоследняяЧасть Тогда
			// Чтобы отправились заказанные метаданные
			ОбработатьОтветНапарника("Конец:",, Ложь, Истина, Отказ);
		КонецЕсли;
	КонецЕсли;
	Если ЛиСжиматьПустыеСтроки() Тогда
		//УдалитьПустыеСтрокиВТекстеНапарника(Слово);
		Если ПустаяСтрока(Результат) Тогда
			Результат = "";
		КонецЕсли;
	КонецЕсли;
	Если СтрокаСловаНапарника.Слово = СтатусИИНеЗнает() Тогда
		// очень странная ситуация, как будто эти обработчики работают параллельно
		Возврат;
	КонецЕсли;
	Если СтрокаСловаНапарника.Слово <> СтатусИИДумает() Тогда
		Результат = СтрокаСловаНапарника.Слово + Результат;
	ИначеЕсли ЗначениеЗаполнено(Результат) Тогда
		Результат = СокрЛ(Результат);
	КонецЕсли;
	Если ПустаяСтрока(Результат) Тогда
		Результат = СтатусИИНеЗнает();
	КонецЕсли;
	СтрокаСловаНапарника.Слово = Результат;
	ЭлементыФормы.ТаблицаСлов.ОбновитьСтроки(ирОбщий.ЗначенияВМассивЛкс(СтрокаСловаНапарника));
	Если ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока = СтрокаСловаНапарника Тогда
		ОбновитьОписаниеСлова();
	КонецЕсли;
КонецПроцедуры

Процедура УстановитьГраницыВыделенияФильтра()
	ирКлиент.ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(ЭтаФорма, ЭлементыФормы.ТекущееСлово,, Истина);
КонецПроцедуры

Процедура ПодходящиеСловаПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Экспорт
	Если Истина
		И ЗначениеЗаполнено(ОжидаемыйТип)
		И (Ложь
			//Или ДанныеСтроки.Рейтинг >= ШагРейтингаСлова()
			Или Найти(ДанныеСтроки.ТипЗначения, ОжидаемыйТип) > 0)
	Тогда
		ОформлениеСтроки.ЦветФона = ирОбщий.ЦветФонаАкцентаЛкс();
	КонецЕсли;
	ирКлиент.ТабличноеПолеПриВыводеСтрокиЛкс(ЭтаФорма, Элемент, ОформлениеСтроки, ДанныеСтроки);
	//Если Лев(ДанныеСтроки.НСлово, СтрДлина(ТекущееСлово)) <> НРег(ТекущееСлово) Тогда
	//	ОформлениеСтроки.ЦветТекста = WebЦвета.Коричневый;
	//КонецЕсли;
	ЯчейкаКартинки = ОформлениеСтроки.Ячейки.Картинка;
	ЯчейкаКартинки.ОтображатьКартинку = Истина;
	ИндексКартинки = ирКлиент.ИндексКартинкиСловаПодсказкиЛкс(ДанныеСтроки);
	Если ИндексКартинки >= 0 Тогда
		ЯчейкаКартинки.ИндексКартинки = ИндексКартинки;
	КонецЕсли;
	ОформитьЯчейкуТипаЗначения(ОформлениеСтроки, ДанныеСтроки);
	ДопСвойства = ирКлиент.ДопСвойстваЭлементаФормыЛкс(ЭтаФорма, Элемент);
	Если Истина
		И ЗначениеЗаполнено(ТекущееСлово)
		И ДопСвойства.ЗапретРазметкиВхождений <> Истина
		И ЭлементыФормы.ДействияФормы.Кнопки.ПереключитьОтборИСортировку.Пометка
		И ДанныеСтроки <> СтрокаСловаНапарника()
	Тогда
		ОформленноеСлово = ирОбщий.НайтиФильтрВСловеЛкс(Истина, ТекущееСлово, ДанныеСтроки.Слово, ДанныеСтроки.НСлово,, мПлатформа.ВыделениеРезультатовПоиска);
		ОформлениеСтроки.Ячейки.Слово.УстановитьТекст(ОформленноеСлово);
	КонецЕсли;
КонецПроцедуры

Процедура ПриИзмененииОтбора() Экспорт
	СписокФильтраПоТипуСлова = Новый СписокЗначений;
	Если ЭлементыФормы.ДействияФормы.Кнопки.НеМетоды.Пометка Тогда
		СписокФильтраПоТипуСлова.Добавить("Метод");
	КонецЕсли;
	Если ЭлементыФормы.ДействияФормы.Кнопки.НеСвойства.Пометка Тогда
		СписокФильтраПоТипуСлова.Добавить("Свойство");
	КонецЕсли;
	Если ЭлементыФормы.ДействияФормы.Кнопки.НеКлючевыеСлова.Пометка Тогда
		СписокФильтраПоТипуСлова.Добавить("Конструкция");
	КонецЕсли;
	ОтборПоТипуСлова = ЭлементыФормы.ТаблицаСлов.ОтборСтрок.ТипСлова;
	Если СписокФильтраПоТипуСлова.Количество() > 0 Тогда
		ОтборПоТипуСлова.ВидСравнения = ВидСравнения.НеВСписке;
		ОтборПоТипуСлова.Значение = СписокФильтраПоТипуСлова;
		ОтборПоТипуСлова.Использование = Истина;
	ИначеЕсли ОтборПоТипуСлова.ВидСравнения = ВидСравнения.НеВСписке Тогда
		ОтборПоТипуСлова.Использование = Ложь;
	КонецЕсли;
	НайтиПодходящиеСлова();
	Если ЛиАвтодополнениеНапарника() Тогда
		СтрокаСловаНапарника = СтрокаСловаНапарника();
		Если Истина
			И СтрокаСловаНапарника <> Неопределено 
			//И СтрокаСловаНапарника.Слово <> СтатусИИДумает()
			И (Ложь
				Или ТекущееСлово = "" И Не ПродолжатьСловоНапарника
				Или ТекущееСлово <> "" И Не ЛиСловоНапарникаПодходитФильтру())
		Тогда
			СтрокаСловаНапарника.Слово = СтатусИИСпит();
			ПодключитьОбработчикОжидания("ЗапуститьЗапросНапарникаВФорме", 0.5, Истина);
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Функция ЛиСловоНапарникаПодходитФильтру() Экспорт
	СтрокаСловаНапарника = СтрокаСловаНапарника();
	Результат = ирОбщий.СтрНачинаетсяСЛкс(СтрокаСловаНапарника.Слово, ТекущееСлово);
	Возврат Результат;
КонецФункции

Процедура ДействияФормыНеМетоды(Кнопка)
	Кнопка.Пометка = Не Кнопка.Пометка;
	ПриИзмененииОтбора();
КонецПроцедуры

Процедура ДействияФормыНеСвойства(Кнопка)
	Кнопка.Пометка = Не Кнопка.Пометка;
	ПриИзмененииОтбора();
КонецПроцедуры

Процедура ДействияФормыНеКлючевыеСлова(Кнопка)
	Кнопка.Пометка = Не Кнопка.Пометка;
	ПриИзмененииОтбора();
КонецПроцедуры

Процедура КоманднаяПанельФормыКонтекстнаяСправка(Кнопка = Неопределено)
	Если ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	РодительИСлово = РодительИСловоСтрокиТаблицыСлов(ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока);
	ПутьКСлову = РодительИСлово.Слово;
	Если РодительИСлово.ВнутриГруппыОбщихМодулей Тогда
		ПутьКСлову = РодительИСлово.Родитель + "." + ПутьКСлову;
	КонецЕсли;
	Если ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока.ТипСлова = "Метод" Тогда
		ПутьКСлову = ПутьКСлову + "(";
	КонецЕсли;
	ФормаФокуса = ?(ЭтаФорма.ВводДоступен(), ЭтаФорма, ФормаВладелец);
	ФормаВызовМетода = ФормаВызовМетода();
	ФормаВызовМетода.ЗапомнитьПозициюКаретки(Ширина + 4);
	ОткрытьКонтекстнуюСправку(ПутьКСлову, ФормаФокуса);
	Если ирКэш.ЛиСеансТолстогоКлиентаУПЛкс() Тогда
		// Нельзя сразу активировать обратно эту форму, т.к. тогда платформа открытую форму сразу скроет и пользователь может не понять, что та форма открыта в отдельном окне
	Иначе
		ирКлиент.Форма_АктивироватьОткрытьЛкс(ФормаФокуса);
	КонецЕсли;
КонецПроцедуры

Процедура ПолеОтбораПоПодстрокеKeyDown(Элемент, КодСочетанияКлавиш)
	ОбработкаОбщихКлавиш(Элемент, КодСочетанияКлавиш);
КонецПроцедуры

Процедура КоманднаяПанельФормыВнутрь(Кнопка)
	ОткрытьДочерние();
КонецПроцедуры

Процедура ПриЗакрытии()
	ирКлиент.Форма_ПриЗакрытииЛкс(ЭтаФорма);
	ЭтаФорма.ПродолжатьСловоНапарника = Ложь;
	ЭтаФорма.ТекущееСлово = "";
	ОтключитьОбработчикОжидания("ЗапуститьЗапросНапарникаВФорме");
	мФоновыйЗапросХттп = Неопределено; // Так иногда будет аварийный выход, начавшийся в 7.99
КонецПроцедуры

Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
	ЭтаФорма.ТекущийЭлемент = ЭлементыФормы.ТаблицаСлов; // Антибаг флатформы 8.3.12 чтобы каретка в поле текстового документа родительской формы не исчезала
	мФоновыйЗапросХттп = Неопределено; // Против аварийного выхода
КонецПроцедуры

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник) Экспорт
	ирКлиент.Форма_ОбработкаОповещенияЛкс(ЭтаФорма, ИмяСобытия, Параметр, Источник);
КонецПроцедуры

// Для нее еще нужна ОбработчикОжиданияСПараметрамиЛкс()
Процедура КлсКомандаНажатие(Кнопка) Экспорт
	ирКлиент.УниверсальнаяКомандаФормыЛкс(ЭтаФорма, Кнопка);
КонецПроцедуры

Процедура ТаблицаСловПриАктивизацииСтроки(Элемент)
	ирКлиент.ТабличноеПолеПриАктивизацииСтрокиЛкс(ЭтаФорма, Элемент);
	Если Элемент.ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	ЭлементыФормы.Описание.УстановитьТекст("");
	ПодключитьОбработчикОжидания("ОбновитьОписаниеСлова", 0.2, Истина);
КонецПроцедуры

Процедура ОбновитьОписаниеСлова() Экспорт
	Элемент = ЭлементыФормы.ТаблицаСлов;
	ТекущаяСтрока = Элемент.ТекущаяСтрока;
	ЭлементыФормы.Описание.УстановитьТекст("");
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	//Если ТекущаяСтрока.ТипЗначения = "ИИ" Тогда
	//	Если ЗапуститьЗапросНапарникаВФорме() Тогда
	//		Возврат;
	//	КонецЕсли;
	//КонецЕсли;
	СтруктураТипа = СтруктураТипаСлова(ТекущаяСтрока);
	Если СтруктураТипа <> Неопределено И СтруктураТипа.СтрокаОписания <> Неопределено Тогда
		ирКлиент.ОповеститьФормыПодсистемыЛкс("ПоказатьОписаниеСлова", СтруктураТипа, ЭтаФорма);
	КонецЕсли;
	СтруктураОписания = ОписаниеТекущегоСловаАвтодополнения(Элемент.ТекущаяСтрока.Слово, Элемент.ТекущаяСтрока.ТипСлова = "Метод",,,, Истина);
	Если СтруктураОписания <> Неопределено Тогда
		ТекстХТМЛ = СтруктураОписания.Описание;
		Если Истина
			И ТекущаяСтрока.ТипЗначения = "ИИ" 
			И ТекстХТМЛ = ТекущаяСтрока.Слово
		Тогда
			ЭлементыФормы.Описание.УстановитьТекст(мПлатформа.СкриптРаскраскиКодаВстроенногоЯзыка());
		Иначе
			ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ, "{ToolTipForeColor}", "black");
			ТекстХТМЛ = СтрЗаменить(ТекстХТМЛ, "{ToolTipBackColor}", "#e0e0e0");
			ЭлементыФормы.Описание.УстановитьТекст(ТекстХТМЛ);
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

//.
// Параметры:
//    ТекущаяСтрока - ОбработкаТабличнаяЧастьСтрока.ирКлсПолеТекстаПрограммы.ТаблицаСлов -
// Возвращаемое значение:
//    РезультатПоискаПоРегулярномуВыражению -
Функция СтруктураТипаСлова(ТекущаяСтрока = Неопределено) Экспорт
	Если ТекущаяСтрока = Неопределено Тогда
		ТекущаяСтрока = ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока;
	КонецЕсли;
	Если ТекущаяСтрока <> Неопределено Тогда
		ВернутьСтруктуруТипа = ТекущаяСтрока.Определение <> "Статистический";
		ТаблицаТипов = УточнитьТипЗначенияВСтрокеТаблицыСлов(ТекущаяСтрока, ВернутьСтруктуруТипа, Ложь);
		Если ТаблицаТипов <> Неопределено И ТаблицаТипов.Количество() > 0 Тогда
			СтруктураТипа = ТаблицаТипов[0];
		КонецЕсли;
	КонецЕсли;
	Возврат СтруктураТипа;
КонецФункции 

Процедура ВнешнееСобытие(Источник, Событие, Данные) Экспорт
	ирКлиент.Форма_ВнешнееСобытиеЛкс(ЭтаФорма, Источник, Событие, Данные);
	Если Источник = "KeyboardHook" Тогда
		//Сообщить(Данные); // Для отладки
		Если ирОбщий.ПроверитьНажатиеКлавишЛкс(Данные, "CTRL+F1") Тогда
			КоманднаяПанельФормыКонтекстнаяСправка();
		ИначеЕсли ТекущийЭлемент = ЭлементыФормы.ТекущееСлово Тогда
			ЗначениеИзменилось = ТекущийЭлемент.Значение <> ТекущееСлово;
			Если ЗначениеИзменилось Тогда
				ирКлиент.ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(ЭтаФорма, ТекущийЭлемент, ТекущийЭлемент.Значение);
			КонецЕсли;
			Если Не ЭлементУправленияTextBoxKeyDown(ТекущийЭлемент, Данные) Тогда
				Если ЗначениеИзменилось Тогда
					ПриИзмененииОтбора();
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Процедура ТабличноеПолеПриПолученииДанных(Элемент, ОформленияСтрок) Экспорт
	ирКлиент.ТабличноеПолеПриПолученииДанныхЛкс(ЭтаФорма, Элемент, ОформленияСтрок);
КонецПроцедуры

Процедура КоманднаяПанельФормыПерейтиКОпределению(Кнопка)
	ТекущаяСтрока = ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока;
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	СтруктураТипа = СтруктураТипаСлова();
	Если СтруктураТипа <> Неопределено И СтруктураТипа.СтрокаОписания <> Неопределено Тогда
		Если Истина
			И Найти(ТипКонтекста, ".") > 0
			И ирОбщий.МножественноеИмяМДЛкс(ирОбщий.ПервыйФрагментЛкс(ТипКонтекста)) <> Неопределено
		Тогда
			ФормаКолонки = ирКлиент.ОткрытьКолонкуБДЛкс(ТипКонтекста, ТекущаяСтрока.Слово);
		КонецЕсли;
		Если ФормаКолонки = Неопределено Тогда
			ОткрытьОпределениеСтруктурыТипа(СтруктураТипа);
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Процедура ДействияФормыНастройки(Кнопка)
	Закрыть();
	ПолучитьФорму("Настройки", ФормаВладелец).Открыть();
КонецПроцедуры

Процедура ПроверкаФокусаВводаВладельца()
	// Плохой код. При открытии контекстного меню форма сразу закрывается.
	Если Не Открыта() Тогда
		Возврат;
	КонецЕсли;
	Окна = ПолучитьОкна();
	Если Истина
		И Не ВводДоступен()
		И ирОбщий.НайтиЭлементКоллекцииЛкс(Окна, "Заголовок", "Настройка списка") = Неопределено
		И (Ложь
			Или Не ФормаВладелец.Открыта()
			Или Не ФормаВладелец.ВводДоступен())
	Тогда
		Закрыть();
	Иначе
		ПодключитьОбработчикОжидания("ПроверкаФокусаВводаВладельца", 1, Истина);
	КонецЕсли;
КонецПроцедуры

Процедура ДействияФормыПереключитьОтборИСортировку(Кнопка = Неопределено) Экспорт
	НовыйРежим = Не ЭлементыФормы.ДействияФормы.Кнопки.ПереключитьОтборИСортировку.Пометка;
	ЭлементыФормы.ДействияФормы.Кнопки.ПереключитьОтборИСортировку.Пометка = НовыйРежим;
	НайтиПодходящиеСлова(НовыйРежим);
КонецПроцедуры

Процедура ТекущееСловоАвтоПодборТекста(Элемент, Текст, ТекстАвтоПодбора, СтандартнаяОбработка)
	Если ирКлиент.ЛиПерехватКлавиатурногоВводаЛкс() Тогда
		Возврат;
	КонецЕсли;
	ирКлиент.ПромежуточноеОбновлениеСтроковогоЗначенияПоляВводаЛкс(ЭтаФорма, Элемент, Текст);
	ПриИзмененииОтбора();
КонецПроцедуры

Процедура КоманднаяПанельФормыВыбрать(Кнопка)
	ЭтаФорма.СтрокаСловаРезультата = ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока;
	ЗакрытьИВставитьСлово();
КонецПроцедуры

Процедура КоманднаяПанельФормыПерехватКлавиатуры(Кнопка)
	ирКлиент.ОткрытьПанельИнструментовЛкс(, Истина, "ПерехватКлавиатурногоВводаВОбычномПриложении");
КонецПроцедуры

Процедура ТаблицаСловПриПолученииДанных(Элемент, ОформленияСтрок)
	мЧислоВидимыхСтрок = Макс(мЧислоВидимыхСтрок, ОформленияСтрок.Количество());
КонецПроцедуры

Процедура СлужебноеПолеХТМЛДокументСформирован(Элемент)
	// Вставить содержимое обработчика.
КонецПроцедуры

Процедура ОписаниеДокументСформирован(Элемент)
	ТекущаяСтрока = ЭлементыФормы.ТаблицаСлов.ТекущаяСтрока;
	Если ТекущаяСтрока = Неопределено Тогда
		Возврат;
	КонецЕсли;
	Если ТекущаяСтрока.ТипЗначения = "ИИ" Тогда 
		Браузер = Элемент.Документ.defaultView._1CAPI;
		Если Браузер <> Неопределено Тогда
			Браузер.setText(ТекущаяСтрока.Слово, "9pt");
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

Процедура Описаниеonclick(Элемент, pEvtObj)
	htmlElement = pEvtObj.srcElement;
	Если htmlElement = Неопределено Тогда
		Возврат;
	КонецЕсли;
	Если htmlElement.href = "ИмяТипа" Тогда
		ИмяТипа = htmlElement.innerText;
		СтруктураТипа = ТаблицаТиповИзТекста(ИмяТипа)[0];
		СтруктураТипа.ТипЯзыка = "ИмяТипа";
		НайтиПоказатьСправкуПоСтруктуреТипа(ИмяТипа, СтруктураТипа,,, ВладелецФормы);
	Иначе
		Если ирКлиент.ОткрытьГиперссылкуИзПоляHTMLЛкс(pEvtObj.srcElement, pEvtObj.ctrlKey) Тогда 
			pEvtObj.returnValue = Ложь;
		КонецЕсли;
	КонецЕсли; 
КонецПроцедуры

ирКлиент.ИнициироватьФормуЛкс(ЭтаФорма, "Обработка.ирКлсПолеТекстаПрограммы.Форма.Автодополнение");
Если мПлатформа = Неопределено Тогда
	ИнициироватьНеинтерактивно();
КонецЕсли;
ЭтаФорма.РазрешитьСостояниеОбычное = Ложь;
ЭтаФорма.РазрешитьСоединятьОкно = Ложь;
мИмяНомерСтроки = ирОбщий.ПеревестиСтроку("НомерСтроки");
ПодходящиеСлова = ТаблицаСлов.ВыгрузитьКолонки();
Если ирКлиент.ЛиПерехватКлавиатурногоВводаЛкс() Тогда
	ЭлементыФормы.КоманднаяПанельФормы.Кнопки.Удалить(ЭлементыФормы.КоманднаяПанельФормы.Кнопки.ПерехватКлавиатуры);
КонецЕсли;
мЧислоВидимыхСтрок = 0;
