//ирПортативный Перем ирПортативный Экспорт;
//ирПортативный Перем ирОбщий Экспорт;
//ирПортативный Перем ирСервер Экспорт;
//ирПортативный Перем ирКэш Экспорт;
//ирПортативный Перем ирПривилегированный Экспорт;

Перем СписокПоиска;
Перем ИмяСвойстваНомера;

Процедура НачатьПоиск()

	Если ПолеВводаПоиска = "" Тогда 
		Возврат;
	КонецЕсли;
	Если ОграничитьОбъектыПоиска = Истина Тогда
		МассивМД = Новый Массив();
		Для Каждого МД Из СписокМетаданных Цикл
			МассивМД.Добавить(Метаданные.НайтиПоПолномуИмени(МД.Значение));
		КонецЦикла;	
		СписокПоиска.ОбластьПоиска = МассивМД;
	Иначе	
		МассивМД = Новый Массив();
		СписокПоиска.ОбластьПоиска = МассивМД;
	КонецЕсли;
	
	Если ПрименитьНечеткийПоиск = Истина Тогда
		СписокПоиска.ПорогНечеткости = Нечеткость;
	Иначе	
		СписокПоиска.ПорогНечеткости = 0;
	КонецЕсли;
	
	СписокПоиска.СтрокаПоиска = ПолеВводаПоиска;
	СписокПоиска.РазмерПорции = РазмерПорции;
	СписокПоиска.ПерваяЧасть();
	Колво = СписокПоиска.ПолноеКоличество();
	
	ЗаполнитьСписокНайденных();
	
КонецПроцедуры

Процедура ПолучитьТекстДатыИндекса()
	
	ИндексАктуален = ПолнотекстовыйПоиск.ИндексАктуален();
	ЭлементыФормы.НадписьДатаАктуальностиИндекса.Заголовок = "Дата актуальности индекса " + ПолнотекстовыйПоиск.ДатаАктуальности() + ", " 
		+ ?(ИндексАктуален, "актуален", "не актуален");
	Если ИндексАктуален Тогда
		ЭлементыФормы.НадписьДатаАктуальностиИндекса.ЦветТекста = Новый Цвет;
	Иначе
		ЭлементыФормы.НадписьДатаАктуальностиИндекса.ЦветТекста = WebЦвета.Красный;
	КонецЕсли; 
		
Конецпроцедуры

Процедура ЗаполнитьСписокНайденных()
	
	Если СписокПоиска.ПолноеКоличество() = 0 Тогда
		ЭлементыФормы.Найдено.Значение = "Не найдено";
		ЭлементыФормы.КнопкаВперед.Видимость = Ложь;
		ЭлементыФормы.КнопкаНазад.Видимость = Ложь;
		ЭлементыФормы.HTMLОтображение.УстановитьТекст("");
		Если СписокПоиска.СлишкомМногоРезультатов() Тогда
			Предупреждение("Слишком много результатов, уточните запрос.");
		КонецЕсли;
		Возврат;
	КонецЕсли;
	Если ЭлементыФормы.ПолеВводаПоиска.СписокВыбора.НайтиПоЗначению(СписокПоиска.СтрокаПоиска) = Неопределено Тогда
		ЭлементыФормы.ПолеВводаПоиска.СписокВыбора.Вставить(0, СписокПоиска.СтрокаПоиска);
		ирОбщий.СохранитьЗначениеЛкс("Строки для полнотекстового поиска", ЭлементыФормы.ПолеВводаПоиска.СписокВыбора.ВыгрузитьЗначения());
	КонецЕсли;
	ЭлементыФормы.КнопкаВперед.Видимость = Истина;
	ЭлементыФормы.КнопкаНазад.Видимость = Истина;
	ЭлементыФормы.Найдено.Значение = 
		"Показаны " + 
		Строка(СписокПоиска.НачальнаяПозиция() + 1) + " - " +  
		Строка(СписокПоиска.НачальнаяПозиция() + СписокПоиска.Количество()) + 
		" из " + СписокПоиска.ПолноеКоличество();
	
	СтрHTML = СписокПоиска.ПолучитьОтображение(ВидОтображенияПолнотекстовогоПоиска.HTMLТекст);
	СтрHTML = СтрЗаменить(СтрHTML, "<td>", "<td><font face=""MS Sans Serif"" size=""1"">");
	СтрHTML = СтрЗаменить(СтрHTML, "<td valign=top width=1>", "<td valign=top width=1><font face=""MS Sans Serif"" size=""1"">");
	СтрHTML = СтрЗаменить(СтрHTML, "<body>", "<body><body topmargin=0 leftmargin=0>");
	СтрHTML = СтрЗаменить(СтрHTML, "</td>", "</font></td>");
	СтрHTML = СтрЗаменить(СтрHTML, "<b>", "");
	СтрHTML = СтрЗаменить(СтрHTML, "</b>", "");
	СтрHTML = СтрЗаменить(СтрHTML, "FFFF00", "FFFFC8");  
	
	ЭлементыФормы.HTMLОтображение.УстановитьТекст(СтрHTML);
	
	ДоступностьКнопок();	
	
КонецПроцедуры

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

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

	ЭлементыФормы.КнопкаВперед.Доступность = (СписокПоиска.ПолноеКоличество() - СписокПоиска.НачальнаяПозиция()) > СписокПоиска.Количество();
	ЭлементыФормы.КнопкаНазад.Доступность = (СписокПоиска.НачальнаяПозиция() > 0);
	
КонецПроцедуры

Процедура КнопкаВпередНажатие(Элемент)
	
	СписокПоиска.СледующаяЧасть();
	ЗаполнитьСписокНайденных();
	
КонецПроцедуры

Процедура КнопкаНазадНажатие(Элемент)
	
	СписокПоиска.ПредыдущаяЧасть();
	ЗаполнитьСписокНайденных();
	
КонецПроцедуры

Процедура ПоказыватьОписанияПриИзменении(Элемент)
	
	СписокПоиска.ПолучатьОписание = ПоказыватьОписания;
	
КонецПроцедуры

Процедура HTMLОтображениеonclick(Элемент, pEvtObj)
	
	htmlElement = pEvtObj.srcElement;
	Если (htmlElement.id = "FullTextSearchListItem") Тогда
		номерВСписке = Число(htmlElement[ИмяСвойстваНомера]);
		ВыбраннаяСтрока = списокПоиска[номерВСписке];
		Если ОткрыватьВРедактореОбъектаБД Тогда
			РедакторОбъектаБД = ирОбщий.ОткрытьСсылкуВРедактореОбъектаБДЛкс(ВыбраннаяСтрока.Значение);
			ПредставлениеПоля = ирОбщий.ПолучитьПервыйФрагментЛкс(htmlElement.parentElement.nextSibling.firstChild.textContent, ":");
			ПредставлениеЗначения = СокрЛП(Сред(htmlElement.parentElement.nextSibling.innerText, СтрДлина(ПредставлениеПоля + ": ") + 1));
			РедакторОбъектаБД.НайтиПоказатьПолеПоПредставлению(ПредставлениеПоля, ПредставлениеЗначения);
		Иначе
			ОткрытьЗначение(ВыбраннаяСтрока.Значение);
		КонецЕсли; 
		pEvtObj.returnValue = Ложь;
	КонецЕсли;
	
КонецПроцедуры

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

Процедура ОграничитьОбъектыПоискаПриИзменении(Элемент)
	
	Если ОграничитьОбъектыПоиска = Истина Тогда
		ЭлементыФОрмы.СписокМетаданных.Доступность = Истина;
	Иначе	
		ЭлементыФОрмы.СписокМетаданных.Доступность = Ложь;
	КонецЕсли;	
	
КонецПроцедуры

Процедура ПрименитьНечеткийПоискПриИзменении(Элемент)
	
	Если ПрименитьНечеткийПоиск = Истина Тогда
		ЭлементыФормы.Нечеткость.Доступность = Истина;
	Иначе	
		ЭлементыФормы.Нечеткость.Доступность = Ложь;
	КонецЕсли;	
	
КонецПроцедуры

Процедура КоманднаяПанельНастройка(Кнопка)
	Если ЭлементыФормы.ПанельНастройки.Свертка = РежимСверткиЭлементаУправления.Верх Тогда
		ЭлементыФормы.ПанельНастройки.Свертка = РежимСверткиЭлементаУправления.Нет;
		ЭлементыФормы.КоманднаяПанель.Кнопки.Настройка.Пометка = Истина;
	Иначе
		ЭлементыФормы.ПанельНастройки.Свертка = РежимСверткиЭлементаУправления.Верх;	
		ЭлементыФормы.КоманднаяПанель.Кнопки.Настройка.Пометка = Ложь;
	КонецЕсли;	
КонецПроцедуры

Процедура КоманднаяПанельПоиск(Кнопка)
	НачатьПоиск();
КонецПроцедуры

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

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

Процедура ПриПовторномОткрытии(СтандартнаяОбработка)
	ТекущийЭлемент = ЭлементыФормы.ПолеВводаПоиска;
КонецПроцедуры

Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
	Если Не ПроверитьДоступностьПоиска() Тогда
		Отказ = Истина;
		Возврат;
	КонецЕсли;
	
	СписокПоиска = ПолнотекстовыйПоиск.СоздатьСписок("", 20);
	СписокПоиска.ПолучатьОписание = Истина;
КонецПроцедуры

Процедура ОбновитьИндексНажатие(Элемент)
	ПолнотекстовыйПоиск.ОбновитьИндекс(Истина,Ложь);
	ПолучитьТекстДатыИндекса();
КонецПроцедуры

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

	Возврат Истина;
КонецФункции

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

КонецПроцедуры

Процедура КоманднаяПанельОткрыватьВРедактореОбъектаБД(Кнопка)
	
	ЭтаФорма.ОткрыватьВРедактореОбъектаБД = Не ОткрыватьВРедактореОбъектаБД;
	Кнопка.Пометка = ОткрыватьВРедактореОбъектаБД;
	
КонецПроцедуры

Процедура КоманднаяПанельОПодсистеме(Кнопка)
	
	ирОбщий.ОткрытьСправкуПоПодсистемеЛкс(ЭтотОбъект);
	
КонецПроцедуры

Процедура КоманднаяПанельКонсольОбработки(Кнопка)
	
	RegExp = Новый COMОбъект("VBScript.RegExp");
	RegExp.Global = Истина;
	//RegExp.MultiLine = Истина;
	RegExp.IgnoreCase = Истина;
	RegExp.Pattern = ИмяСвойстваНомера + "=""(\d+)""";
	Вхождения = RegExp.Execute(ЭлементыФормы.HTMLОтображение.Документ.selection.CreateRange().htmlText);
	МассивСсылок = Новый Массив;
	Для Каждого Вхождение Из Вхождения Цикл
		НомерВСписке = Число(Вхождение.SubMatches(0));
		ВыбраннаяСтрока = списокПоиска[НомерВСписке];
		МассивСсылок.Добавить(ВыбраннаяСтрока.Значение);
	КонецЦикла; 
	ирОбщий.ОткрытьМассивОбъектовВПодбореИОбработкеОбъектовЛкс(МассивСсылок);
	
КонецПроцедуры

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

//ирПортативный лФайл = Новый Файл(ИспользуемоеИмяФайла);
//ирПортативный ПолноеИмяФайлаБазовогоМодуля = Лев(лФайл.Путь, СтрДлина(лФайл.Путь) - СтрДлина("Модули\")) + "ирПортативный.epf";
//ирПортативный #Если Клиент Тогда
//ирПортативный 	Контейнер = Новый Структура();
//ирПортативный 	Оповестить("ирПолучитьБазовуюФорму", Контейнер);
//ирПортативный 	Если Не Контейнер.Свойство("ирПортативный", ирПортативный) Тогда
//ирПортативный 		ирПортативный = ВнешниеОбработки.ПолучитьФорму(ПолноеИмяФайлаБазовогоМодуля);
//ирПортативный 		ирПортативный.Открыть();
//ирПортативный 	КонецЕсли; 
//ирПортативный #Иначе
//ирПортативный 	ирПортативный = ВнешниеОбработки.Создать(ПолноеИмяФайлаБазовогоМодуля, Ложь); // Это будет второй экземпляр объекта
//ирПортативный #КонецЕсли
//ирПортативный ирОбщий = ирПортативный.ПолучитьОбщийМодульЛкс("ирОбщий");
//ирПортативный ирКэш = ирПортативный.ПолучитьОбщийМодульЛкс("ирКэш");
//ирПортативный ирСервер = ирПортативный.ПолучитьОбщийМодульЛкс("ирСервер");
//ирПортативный ирПривилегированный = ирПортативный.ПолучитьОбщийМодульЛкс("ирПривилегированный");

ирОбщий.ИнициализироватьФормуЛкс(ЭтаФорма, "Обработка.ирПоискДанных.Форма.Форма");

