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

#Если Клиент Тогда

// Переменная документа, представляющего файл 
// настройки технологического журнала
Перем мДокументДОМ Экспорт;

// Переменные для работы с двоичным представлением числа
Перем мДвоичноеЧисло; 
Перем мЧисло;

// Костанты списков данных
Перем мВидыСравнения;
Перем мСписокТипов;
Перем мСписокСобытий;
Перем мСписокСвойствСобытий;
Перем мСоставСвойствСобытий;
Перем мСписокИменСвойств;
Перем мСписокДействий;
Перем мКодировкаФайла;
Перем мВариантыРасположенияФайла Экспорт;
Перем мСписокВариантовРасположенияКонфигурационногоФайла Экспорт;

////////////////////////////////////////////////////////////////////////////////
// ЗАПОЛНЕНИЕ КОНСТАНТ И ИХ ВОЗВРАТ ПО ТРЕБОВАНИЮ

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

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

// Возвращает каталог технологического журнала 
//
Функция ПолучитьДиректориюТехнологическогоЖурнала() Экспорт
	
	Возврат КаталогПрограммы() + "logs";
	
КонецФункции

// Возвращает каталог дампа 
//
Функция ПолучитьДиректориюДампа() Экспорт
	
	Возврат КаталогПрограммы() + "dumps";
	
КонецФункции

// Возвращает имя файла шаблона по имени шаблона
//
Функция ПолучитьИмяФайлаШаблона(ИмяШаблона) Экспорт
	
	Возврат ПолучитьКаталогНастроекПриложения() + "\" + ИмяШаблона + ".prst";

КонецФункции

// Заполнить структуру типов
//
Процедура ЗаполнитьСписокТипов()
	
	мСписокТипов = Новый Структура;
	СоставСвойствСобытий = ПолучитьСоставСвойствСобытий();
	#Если Сервер И Не Сервер Тогда
	    СоставСвойствСобытий = Новый ТаблицаЗначений;
	#КонецЕсли
	Для Счетчик = 1 По СоставСвойствСобытий.Колонки.Количество() - 1 Цикл
		ИмяСвойства = СоставСвойствСобытий.Колонки[Счетчик].Имя;
		ТипСвойства = НРег(СоставСвойствСобытий[0][Счетчик]);
		Если ТипСвойства = "n" Тогда
			СтрокаТипов = "Число";
		ИначеЕсли ТипСвойства = "s" Тогда
			СтрокаТипов = "Строка";
		ИначеЕсли ТипСвойства = "d" Тогда
			СтрокаТипов = "Дата"; // Пока не встречается
		ИначеЕсли ТипСвойства = "b" Тогда
			СтрокаТипов = "Булево";
		Иначе // fl, nl, ll
			//СтрокаТипов = "СписокЗначений";
			СтрокаТипов = "Строка";
		КонецЕсли; 
		ОписаниеТипов = Новый ОписаниеТипов(СтрокаТипов);
		мСписокТипов.Вставить(ИмяСвойства, ОписаниеТипов);
	КонецЦикла;
	
КонецПроцедуры

Процедура ЗаполнитьСписокВыбораСрокаХранения(СписокВыбора) Экспорт
	
	СписокВыбора.Очистить();
	СписокВыбора.Добавить(2);
	СписокВыбора.Добавить(6);
	СписокВыбора.Добавить(24, "1 день");
	СписокВыбора.Добавить(48, "2 дня");
	СписокВыбора.Добавить(168, "Неделя");

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

// Вернуть константу со списком типов
//
Функция ВернутьСписокТипов() Экспорт
	
	Если мСписокТипов = Неопределено Тогда
		ЗаполнитьСписокТипов();
	КонецЕсли;
	
	Возврат мСписокТипов;
	
КонецФункции

// Заполнить структуру списком событий
//
Процедура ЗаполнитьТаблицуТиповСобытий() Экспорт

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

// Заполнить список представления сравнений
//
Процедура ЗаполнитьСписокСравнения()
	
	мВидыСравнения = Новый СписокЗначений;
	мВидыСравнения.Добавить("eq", "Равно");
	мВидыСравнения.Добавить("ne", "Не равно");
	мВидыСравнения.Добавить("gt", "Больше");
	мВидыСравнения.Добавить("ge", "Больше или равно");
	мВидыСравнения.Добавить("lt", "Меньше");
	мВидыСравнения.Добавить("le", "Меньше или равно");
	мВидыСравнения.Добавить("like", "Шаблон");
	
КонецПроцедуры

// Вернуть константу со списком сравнений
//
Функция ПолучитьСписокСравнения() Экспорт
	
	Если мВидыСравнения = Неопределено Тогда
		ЗаполнитьСписокСравнения();
	КонецЕсли;
	
	Возврат мВидыСравнения;
	
КонецФункции

// Поиск значения в списке по представлению
Функция НайтиЭлементПоПредставлению(Список, Представление) Экспорт
	
	Результат = "";
	Для Каждого Элемент Из Список Цикл
		Если Элемент.Представление = Представление Тогда
			Результат = Элемент.Значение;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Возврат Результат;
	
КонецФункции

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

Функция ПолучитьСтруктуруСвойствСобытия(Событие, ВключатьКолонкуСобытия = Истина) Экспорт 
	
	ПолучитьСоставСвойствСобытий();
	СтрокаСобытия = мСоставСвойствСобытий.Найти(ВРег(Событие), "MainEvent");
	АктуальныеСвойства = Новый Структура;
	Если СтрокаСобытия <> Неопределено Тогда
		Для Каждого Колонка Из мСоставСвойствСобытий.Колонки Цикл
			Если СтрокаСобытия[Колонка.Имя] = "+" Тогда
				АктуальныеСвойства.Вставить(Колонка.Имя);
			КонецЕсли; 
		КонецЦикла;
		Если Не ВключатьКолонкуСобытия Тогда
			АктуальныеСвойства.Удалить("Name");
		КонецЕсли; 
	Иначе
		// событие - CONTEXT
		//АктуальныеСвойства = Неопределено;
	КонецЕсли;
	Возврат АктуальныеСвойства;

КонецФункции

// Заполнить структуру свойств событий
//
Процедура ЗаполнитьСписокСвойствСобытий() Экспорт

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

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

Функция ПолноеПредставлениеСвойства(Знач СтрокаТЧ) Экспорт 
	
	Возврат СтрокаТЧ.Представление + " (" + СтрокаТЧ.Имя + ")";

КонецФункции

// Заполнить структуру имен свойств
//
Процедура ЗаполнитьСписокИменСвойств()

	мСписокИменСвойств = ПолучитьСписокСвойствСобытий().Скопировать();
	мСписокИменСвойств.Вставить(0, "all", "All  (все свойства)");

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

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

// Вернуть константу со списком наименований выполняемого действия
//
Функция ПолучитьСписокДействий() Экспорт
	
	Если мСписокДействий = Неопределено Тогда
		ЗаполнитьСписокДействий();
	КонецЕсли;
	мСписокДействий.СортироватьПоПредставлению();
	Возврат мСписокДействий;
	
КонецФункции

// Поиск в списке значений значения по представлению
//
Функция НайтиЗначениеПоПредставлению(Представление) Экспорт
	
	Для Инд = 0 По мВидыСравнения.Количество() Цикл
		
		Если Представление = мВидыСравнения[Инд].Представление Тогда
			
			Возврат мВидыСравнения[Инд].Значение;
			
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат Неопределено;
	
КонецФункции

Функция ПредставлениеЭлементаОтбораСобытийЖурнала(ИндексЖурнала, ИндСоб) Экспорт

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

КонецФункции

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

КонецФункции

Функция ПредставлениеЭлементаОтбораСвойствЖурнала(ИндексЖурнала, ИндСоб) Экспорт

	УзелУсловия = ПолучитьУзелСвойства(ИндексЖурнала, ИндСоб);
	Если УзелУсловия <> Неопределено Тогда
		Результат = ПредставлениеЭлементаОтбораСвойств(УзелУсловия);
	Иначе
		Результат = "";
	КонецЕсли; 
	Возврат Результат;

КонецФункции

Функция ПредставлениеЭлементаОтбораСвойств(УзелУсловия) Экспорт

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

КонецФункции

Функция ПолучитьИмяСобытияЭлементаОтбораСобытийНаРавенство(УзелСобытий, ИндСоб) Экспорт

	УзелУсловий = УзелСобытий.Элемент(ИндСоб).ПервыйДочерний;
	Пока УзелУсловий <> Неопределено Цикл
		Если УзелУсловий.ЛокальноеИмя = "eq" Тогда
			АтрибутИмениСобытия = УзелУсловий.Атрибуты.ПолучитьИменованныйЭлемент("property");
			Если Истина
				И АтрибутИмениСобытия <> Неопределено 
				И НРег(АтрибутИмениСобытия.ЗначениеУзла) = НРег("Name")
			Тогда
				АтрибутЗначенияИмениСобытия = УзелУсловий.Атрибуты.ПолучитьИменованныйЭлемент("value");
				Если АтрибутЗначенияИмениСобытия <> Неопределено Тогда
					Возврат АтрибутЗначенияИмениСобытия.ЗначениеУзла;
				КонецЕсли; 
			КонецЕсли; 
		ИначеЕсли УзелУсловий.ЛокальноеИмя = "ne" Тогда
			АтрибутИмениСобытия = УзелУсловий.Атрибуты.ПолучитьИменованныйЭлемент("property");
			Если Истина
				И АтрибутИмениСобытия <> Неопределено 
				И НРег(АтрибутИмениСобытия.ЗначениеУзла) = НРег("Name")
			Тогда
				АтрибутЗначенияИмениСобытия = УзелУсловий.Атрибуты.ПолучитьИменованныйЭлемент("value");
				Если АтрибутЗначенияИмениСобытия <> Неопределено Тогда
					Если АтрибутЗначенияИмениСобытия.ЗначениеУзла = "" Тогда
						Возврат "<ALL>";
					КонецЕсли; 
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли; 
		УзелУсловий = УзелУсловий.СледующийСоседний;
	КонецЦикла;
	Возврат Неопределено;

КонецФункции

Функция НайтиДобавитьУзелВКоллекцию(Искать = Истина, Документ = Неопределено, РодительскийЭлемент = Неопределено, ИмяУзла) Экспорт

	Если Документ = Неопределено Тогда
		Документ = мДокументДОМ;
	КонецЕсли; 
	#Если Сервер И Не Сервер Тогда
	    Документ = Новый ДокументDOM;
	#КонецЕсли
	Если РодительскийЭлемент = Неопределено Тогда
		РодительскийЭлемент = Документ.ПервыйДочерний;
	КонецЕсли;
	Если Искать Тогда
		СписокУзлов = РодительскийЭлемент.ПолучитьЭлементыПоИмени(ИмяУзла);
	КонецЕсли; 
	Если Истина
		И Искать
		И СписокУзлов.Количество() > 0 
	Тогда
		Узел = СписокУзлов.Элемент(0);
	Иначе
		Узел = СоздатьЭлементДОМ(ИмяУзла, Документ);
		РодительскийЭлемент.ДобавитьДочерний(Узел);
	КонецЕсли; 
	Возврат Узел;
	
КонецФункции // ДобавитьУзелВКоллекцию()

Функция НайтиДобавитьУзелСАтрибутами(Искать = Истина, Документ = Неопределено, Родитель = Неопределено, ИмяУзла, СтруктураАтрибутов = Неопределено) Экспорт
	
	Узел = НайтиДобавитьУзелВКоллекцию(Искать, Документ, Родитель, ИмяУзла);
	Если СтруктураАтрибутов <> Неопределено Тогда
		Для каждого Атрибут Из СтруктураАтрибутов Цикл
			Узел.УстановитьАтрибут(Атрибут.Ключ, XMLСтрока(Атрибут.Значение));
		КонецЦикла;
	КонецЕсли;
	Возврат Узел;
	
КонецФункции

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

// Проверить принадлежность имени к требуемому
//
Функция ДоступныеЗначенияСвойства(Имя) Экспорт
	
	Если НРег(Имя) = "name" Тогда
		Результат = ПолучитьСписокСобытий();
	ИначеЕсли НРег(Имя) = "func" Тогда
		Результат = ПолучитьСписокДействий();
	ИначеЕсли НРег(Имя) = "level" Тогда
		Результат = УровниСистемныхСобытий();
	Иначе 
		Результат = Новый СписокЗначений;
		Если ЗначениеЗаполнено(Имя) Тогда
			СтруктураТиповЗначенийСвойств = ВернутьСписокТипов();
			ТипЗначенияСвойства = Неопределено;
			Если СтруктураТиповЗначенийСвойств.Свойство(СтрЗаменить(Имя, ":", "_"), ТипЗначенияСвойства) Тогда
				Если ТипЗначенияСвойства.СодержитТип(Тип("Булево")) Тогда
					//Результат.Добавить("1", "Да");
					//Результат.Добавить("0", "Нет");
					Результат.Добавить("true", "Да");
					Результат.Добавить("false", "Нет");
				КонецЕсли; 
			КонецЕсли; 
		КонецЕсли; 
	КонецЕсли;
	Возврат Результат;
	
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// ФУНКЦИИ РАБОТЫ С ДОКУМЕНТОМ DOM

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

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

КонецПроцедуры // ПереместитьФайл()

Функция ЛиФайлСуществует(ПолноеИмяФайла, пНаСервере = Неопределено, выхДатаИзменения = Неопределено) Экспорт 

	Если пНаСервере = Неопределено Тогда
		пНаСервере = НаСервере;
	КонецЕсли; 
	Если пНаСервере Тогда
		ФайлНайден = ирСервер.ЛиФайлСуществуетЛкс(ПолноеИмяФайла, выхДатаИзменения);
	Иначе
		Файл1 = Новый Файл(ПолноеИмяФайла);
		ФайлНайден = Файл1.Существует();
		Если ФайлНайден Тогда
			выхДатаИзменения = Файл1.ПолучитьВремяИзменения() + ирКэш.ПолучитьСмещениеВремениЛкс();
		КонецЕсли; 
	КонецЕсли; 
	Возврат ФайлНайден;

КонецФункции // ЛиФайлСуществует()
 
// Загрузить конфигурационный файл XML в документ DOM
//
Функция ЗагрузитьКонфигурационныйXML(Знач ИмяФайла, пНаСервере = Неопределено) Экспорт
	
	ТекущийЖурнал = -1;
	Если пНаСервере = Неопределено Тогда
		пНаСервере = НаСервере;
	КонецЕсли; 
	Шаблон = Ложь;
	МетаМакет = Метаданные().Макеты.Найти(ИмяФайла);
	Если МетаМакет <> Неопределено Тогда
		ДокументДОМПриемник = ЗагрузитьШаблон(ИмяФайла, "", "");
		Возврат ДокументДОМПриемник;
	ИначеЕсли ЗначениеЗаполнено(ИмяФайла) Тогда
		ФайлСуществует = ЛиФайлСуществует(ИмяФайла, пНаСервере);
		Если Не ФайлСуществует Тогда
			ИмяФайла = ПолучитьИмяФайлаШаблона(ИмяФайла);
			Шаблон = Истина;
		КонецЕсли; 
	Иначе 
		ИмяФайла = ПолучитьПолноеИмяКонфигурационногоФайла();
	КонецЕсли;
		
	КонфигурационныйФайл = Новый Файл(ИмяФайла);
	ФайлСуществует = ЛиФайлСуществует(ИмяФайла, пНаСервере);
	Если Не ФайлСуществует Тогда
		ДокументДОМПриемник = Новый ДокументDOM("http://v8.1c.ru/v8/tech-log", "config");
		Элемент = СоздатьЭлементДОМ("dump", ДокументДОМПриемник);
		Элемент.УстановитьАтрибут("create", "true");
		//Элемент.УстановитьАтрибут("location", "");
		Элемент.УстановитьАтрибут("type", "0");
		Элемент.УстановитьАтрибут("prntscrn", "false");
		ДокументДОМПриемник.ПервыйДочерний.ДобавитьДочерний(Элемент);
		
		Элемент = СоздатьЭлементДОМ("log", ДокументДОМПриемник);
		Элемент.УстановитьАтрибут("history", "24");
		Элемент.УстановитьАтрибут("location", "");
		ЭлементProperty = СоздатьЭлементДОМ("property", ДокументДОМПриемник);
		ЭлементProperty.УстановитьАтрибут("name", "all");
		УзелСвойства = Элемент.ДобавитьДочерний(ЭлементProperty);
		ДокументДОМПриемник.ПервыйДочерний.ДобавитьДочерний(Элемент);
		
		УтечкиМетоды.Очистить();
		СистемныеСобытия.Очистить();

		//ЗаписатьДОМ(Документ, КонфигурационныйФайл.ПолноеИмя);
		УстановитьПути(ОсновнойКаталогЖурнала, ОсновнойКаталогДампов, ДокументДОМПриемник);
	Иначе
		СтрокаХМЛ = ирОбщий.ПрочитатьТекстИзФайлаЛкс(КонфигурационныйФайл.ПолноеИмя,, пНаСервере);
		ДокументДОМПриемник = ПрочитатьДокументДомИзСтроки(СтрокаХМЛ);
	КонецЕсли;
	Если Шаблон Тогда
		УдалитьОписаниеШаблона(ДокументДОМПриемник);
	КонецЕсли;
	Возврат ДокументДОМПриемник;
	
КонецФункции

Функция ПрочитатьДокументДомИзСтроки(СтрокаХМЛ)

	ЧтениеХМЛ = Новый ЧтениеXML();              
	ЧтениеХМЛ.УстановитьСтроку(СтрокаХМЛ);
	ПостроительДом = Новый ПостроительDOM();
	Попытка
		Результат = ПостроительДом.Прочитать(ЧтениеХМЛ);
	Исключение
		Сообщить("Ошибка при чтении файла XML: " + ОписаниеОшибки(), СтатусСообщения.Внимание);
		Результат = Неопределено;
	КонецПопытки;
	Возврат Результат;

КонецФункции

// Записать документ DOM в файл XML
//
Процедура ЗаписатьДОМ(Документ, ИмяФайла) Экспорт
	
	ЗаписьХМЛ = Новый ЗаписьXML();
	ЗаписьХМЛ.УстановитьСтроку(мКодировкаФайла);
	ЗаписатьДом = Новый ЗаписьDOM();
	ЗаписатьДом.Записать(Документ, ЗаписьХМЛ);
	СтрокаХМЛ = ЗаписьХМЛ.Закрыть();
	ирОбщий.ЗаписатьТекстВФайлЛкс(ИмяФайла, СтрокаХМЛ, мКодировкаФайла, НаСервере);
	
КонецПроцедуры

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

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

// Удаляется из документа описание шаблона
// 
Процедура УдалитьОписаниеШаблона(ДокументДОМПриемник = Неопределено) Экспорт
	
	Если ДокументДОМПриемник = Неопределено Тогда
		ДокументДОМПриемник = мДокументДОМ;
	КонецЕсли; 
	Попытка
		КоллекцияУзловОписанияШаблона = ДокументДОМПриемник.ПолучитьЭлементыПоИмени("draft");
		Для Инд = 1 По КоллекцияУзловОписанияШаблона.Количество() Цикл
			УзелОписанияШаблона = КоллекцияУзловОписанияШаблона.Элемент(0);
			УзелОписанияШаблона.РодительскийУзел.УдалитьДочерний(УзелОписанияШаблона);
		КонецЦикла;
	Исключение
	КонецПопытки;
	
КонецПроцедуры

// Получить строку XML представления документа DOM для записи в
// поле текстового документа
Функция ПолучитьСтрокуХМЛ(Документ) Экспорт
	
	ЗаписьХМЛ = Новый ЗаписьXML();
	ЗаписьХМЛ.УстановитьСтроку(мКодировкаФайла);
	ЗаписатьДом = Новый ЗаписьDOM();
	
	УдалитьОписаниеШаблона();
	
	ЗаписатьДом.Записать(Документ, ЗаписьХМЛ);
	Возврат ЗаписьХМЛ.Закрыть();
	
КонецФункции

Функция ПолучитьОбновитьДокументДОМ() Экспорт
	
	ЗаписатьНастройкиДампа();
	ИмяЭлемента = "defaultlog";
	УдалитьКорневыеЭлементыПоИмени(ИмяЭлемента);
	Если Не ПустаяСтрока(КаталогСистемногоЖурнала) Тогда
		Элемент = НайтиДобавитьУзелВКоллекцию(, , , ИмяЭлемента);
		Если Не ПустаяСтрока(КаталогСистемногоЖурнала) Тогда
			Элемент.УстановитьАтрибут("location", XMLСтрока(КаталогСистемногоЖурнала));
		КонецЕсли;
		Если СрокХраненияСистемногоЖурнала <> 24 Тогда
			Элемент.УстановитьАтрибут("history", XMLСтрока(СрокХраненияСистемногоЖурнала));
		КонецЕсли;
	КонецЕсли; 
	
	ИмяЭлемента = "leaks";
	УдалитьКорневыеЭлементыПоИмени(ИмяЭлемента);
	Если СледитьЗаУтечкамиПамятиВПрикладномКоде Тогда
		Утечки = НайтиДобавитьУзелСАтрибутами(,,, ИмяЭлемента, Новый Структура("collect", Истина));
		Пока Утечки.ПервыйДочерний <> Неопределено Цикл
			Утечки.УдалитьДочерний(Утечки.ПервыйДочерний);
		КонецЦикла; 
		Если КонтрольнаяТочкаУтечкиКлиент Тогда
			НайтиДобавитьУзелСАтрибутами(Ложь, , Утечки, "point", Новый Структура("call", "client"));
		КонецЕсли;
		Если КонтрольнаяТочкаУтечкиСервер Тогда
			НайтиДобавитьУзелСАтрибутами(Ложь, , Утечки, "point", Новый Структура("call", "server"));
		КонецЕсли;
		Для каждого СтрокаУтечки Из УтечкиМетоды Цикл
			Если ПустаяСтрока(СтрокаУтечки.Метод) Тогда
				Продолжить;
			КонецЕсли;
			НайтиДобавитьУзелСАтрибутами(Ложь, , Утечки, "point", Новый Структура("proc", СтрокаУтечки.Метод));
		КонецЦикла;
		//Для каждого Утечка Из УтечкиПроцедуры Цикл
		//	НайтиДобавитьУзелСАтрибутами(Ложь, , Утечки, "point", Новый Структура("on, off", Утечка.Строка1, Утечка.Строка2));
		//КонецЦикла;
	КонецЕсли;
	
	ИмяЭлемента = "system";
	УдалитьКорневыеЭлементыПоИмени(ИмяЭлемента);
	Если СистемныеСобытия.Количество() Тогда
		Для каждого СтрокаСобытия Из СистемныеСобытия Цикл
			Если ПустаяСтрока(СтрокаСобытия.Уровень) Тогда
				Продолжить;
			КонецЕсли;
			Элемент = НайтиДобавитьУзелВКоллекцию(Ложь, , , ИмяЭлемента);
			Элемент.УстановитьАтрибут("level", XMLСтрока(СтрокаСобытия.Уровень));
			Если НЕ ПустаяСтрока(СтрокаСобытия.Компонент) Тогда
				Элемент.УстановитьАтрибут("component", XMLСтрока(СтрокаСобытия.Компонент));
			КонецЕсли;
			Если НЕ ПустаяСтрока(СтрокаСобытия.Класс) Тогда
				Элемент.УстановитьАтрибут("class", XMLСтрока(СтрокаСобытия.Класс));
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	ИмяЭлемента = "mem";
	УдалитьКорневыеЭлементыПоИмени(ИмяЭлемента);
	Если СледитьЗаУтечкамиПамятиВРабочихПроцессах Тогда
		НайтиДобавитьУзелВКоллекцию(, , , ИмяЭлемента);
	КонецЕсли;
	
	//ИмяЭлемента = "planSQL";
	ИмяЭлемента = "plansql";
	УдалитьКорневыеЭлементыПоИмени(ИмяЭлемента);
	Если ФиксироватьПланыЗапросовSQL Тогда
		НайтиДобавитьУзелВКоллекцию(, , , ИмяЭлемента);
	КонецЕсли;
	
	ИмяЭлемента = "dbmslocks";
	УдалитьКорневыеЭлементыПоИмени(ИмяЭлемента);
	Если СобиратьБлокировкиСУБД Тогда
		НайтиДобавитьУзелВКоллекцию(, , , ИмяЭлемента);
	КонецЕсли;
	
	ИмяЭлемента = "scriptcircrefs";
	УдалитьКорневыеЭлементыПоИмени(ИмяЭлемента);
	Если КонтрольЦиклическихСсылок Тогда
		НайтиДобавитьУзелВКоллекцию(, , , ИмяЭлемента);
	КонецЕсли;
	Возврат мДокументДОМ; 

КонецФункции

Процедура УдалитьКорневыеЭлементыПоИмени(ИмяЭлемента)

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

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


// Вернуть документ DOM
//
Функция ДокументДОМ() Экспорт
	
	Возврат мДокументДОМ;
	
КонецФункции

Функция СоздатьЭлементДОМ(ЛокальноеИмяЭлемента, Документ = Неопределено) Экспорт 
	
	Если Документ = Неопределено Тогда
		Документ = мДокументДОМ;
	КонецЕсли; 
	ЭлементДОМ = Документ.СоздатьЭлемент(Документ.ЭлементДокумента.URIПространстваИмен, Документ.ЭлементДокумента.Префикс + ":" + ЛокальноеИмяЭлемента);
	Возврат ЭлементДОМ;
	
КонецФункции

// Закрытие документа
//
Процедура ЗакрытьДокумент() Экспорт
	
	мДокументДОМ = Неопределено;
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// ФУНКЦИИ ДОСТУПА К ЭЛЕМЕНТАМ ДЕРЕВА ДОКУМЕНТА DOM

Функция ПолучитьУзелЖурнала(ИндексЖурнала) Экспорт
	
	СписокЭлементов = мДокументДОМ.ПолучитьЭлементыПоИмени("log");
	Если СписокЭлементов.Количество() > 0 Тогда
		Результат = СписокЭлементов.Элемент(ИндексЖурнала);
	КонецЕсли; 
	Возврат Результат;
	
КонецФункции

Процедура ОчиститьЖурнал(Индекс) Экспорт
	
	мДокументДОМ.ПервыйДочерний.ЗаменитьДочерний(НовыйЖурнал(), ПолучитьУзелЖурнала(Индекс));
	
КонецПроцедуры

Функция НовыйЖурнал() Экспорт
	
	Элемент = СоздатьЭлементДОМ("log");
	Элемент.УстановитьАтрибут("history", "2");
	Элемент.УстановитьАтрибут("location", "");
	Возврат Элемент;
	
КонецФункции

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

Функция ПолучитьУзелСобытия(ИндексЖурнала, ИндексСобытия) Экспорт
	
	СписокУзлов = ПолучитьСписокУзловЖурнала(ИндексЖурнала);
	Результат = УзелСобытияПоИндексу(СписокУзлов, ИндексСобытия);
	Возврат Результат;
	
КонецФункции

Функция УзелСобытияПоИндексу(Знач СписокУзлов, Знач ИндексСобытия)
	
	НомерУзла = 0;
	Результат = Неопределено;
	Для Инд = 0 По СписокУзлов.Количество() - 1 Цикл
		УзелСобытия = СписокУзлов.Элемент(Инд);
		Если Истина
			//И ирОбщий.СтрокиРавныЛкс(УзелСобытия.РодительскийУзел.ЛокальноеИмя, "log") 
			И ирОбщий.СтрокиРавныЛкс(УзелСобытия.ЛокальноеИмя, "event") 
		Тогда
			НомерУзла = НомерУзла + 1;
		КонецЕсли;
		Если НомерУзла = ИндексСобытия + 1 Тогда
			Результат = УзелСобытия;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	Возврат Результат;

КонецФункции

Функция ПолучитьУзелСвойства(ИндексЖурнала, ИндексСвойства) Экспорт
	
	НомерУзла = 0;
	СписокУзлов = ПолучитьСписокУзловЖурнала(ИндексЖурнала);
	Для Инд = 0 По СписокУзлов.Количество() - 1 Цикл
		УзелСобытия = СписокУзлов.Элемент(Инд);
		Если Истина
			//И ирОбщий.СтрокиРавныЛкс(УзелСобытия.РодительскийУзел.ЛокальноеИмя, "log") 
			И ирОбщий.СтрокиРавныЛкс(УзелСобытия.ЛокальноеИмя, "property") 
		Тогда
			НомерУзла = НомерУзла + 1;
		КонецЕсли;
		Если НомерУзла = ИндексСвойства + 1 Тогда
			Возврат УзелСобытия;
		КонецЕсли;
	КонецЦикла;
	Возврат Неопределено;
	
КонецФункции

Функция ПолучитьСписокЖурналов() Экспорт
	
	Результат = мДокументДОМ.ПолучитьЭлементыПоИмени("log");
	Возврат Результат;
	
КонецФункции

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

Функция ПолучитьСписокСвойств(ИндексЖурнала) Экспорт
	
	УзлыЖурнала = ПолучитьСписокЖурналов();
	Результат = УзлыЖурнала.Элемент(ИндексЖурнала).ПолучитьЭлементыПоИмени("property");
	Возврат Результат;
	
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// ФУНКЦИИ РАБОТЫ С ДАМПОМ

// Считать настройки дампа из документа DOM
//
Процедура ПрочитатьНастройкиДампа() Экспорт
	
	ЗаписатьНастройкиД = Ложь;
	ЭлементДамп = мДокументДОМ.ПолучитьЭлементыПоИмени("dump");
	Если ЭлементДамп.Количество() > 0 Тогда
		ПервыйЭлемент = ЭлементДамп.Элемент(0);
		Если ПервыйЭлемент <> Неопределено Тогда
			ТипДампа = ПервыйЭлемент.ПолучитьАтрибут("type");
			РасположениеДампа = ПервыйЭлемент.ПолучитьАтрибут("location");
			Попытка
				ДампСкриншот = XMLЗначение(Тип("Булево"), ПервыйЭлемент.ПолучитьАтрибут("prntscrn"));
			Исключение
				ДампСкриншот = Ложь;
				//ЗаписатьНастройкиД = Истина;
				//ПервыйЭлемент.УстановитьАтрибут("prntscrn", "false");
			КонецПопытки;
			Попытка
				СоздаватьДамп = XMLЗначение(Тип("Булево"), ПервыйЭлемент.ПолучитьАтрибут("create"));
			Исключение
				СоздаватьДамп = Ложь;
				//ЗаписатьНастройкиД = Истина;
				//ПервыйЭлемент.УстановитьАтрибут("create", "false");
			КонецПопытки;
		КонецЕсли;
	Иначе
		ТипДампа = 0;
		РасположениеДампа = "";
		ДампСкриншот = Ложь;
		СоздаватьДамп = Ложь;
	КонецЕсли;
	
	//Если ЗаписатьНастройкиД Тогда
	//	ЗаписатьДОМ(мДокументДОМ, ПолучитьПолноеИмяКонфигурационногоФайла());
	//КонецЕсли;
	
КонецПроцедуры

// Записать настройки дампа в документа DOM
//
Функция ЗаписатьНастройкиДампа() Экспорт
	
	Перем ПервыйДочерний;
	
	ЭлементДамп = мДокументДОМ.ПолучитьЭлементыПоИмени("dump");
	Если ЭлементДамп.Количество() = 0 Тогда
		Элемент = СоздатьЭлементДОМ("dump");
		Элемент.УстановитьАтрибут("create", "true");
		//Элемент.УстановитьАтрибут("location", "");
		Элемент.УстановитьАтрибут("type", "0");
		Элемент.УстановитьАтрибут("prntscrn", "false");
		ПервыйДочерний = Элемент;
		мДокументДОМ.ПервыйДочерний.ДобавитьДочерний(Элемент);
	Иначе
		ПервыйДочерний = ЭлементДамп.Элемент(0);
	КонецЕсли;
	ПервыйДочерний.УстановитьАтрибут("create", XMLСтрока(СоздаватьДамп));
	ПервыйДочерний.УстановитьАтрибут("type", XMLСтрока(ТипДампа));
	ПервыйДочерний.УстановитьАтрибут("prntscrn", XMLСтрока(ДампСкриншот));
	Если Не ПустаяСтрока(РасположениеДампа) Тогда
		ПервыйДочерний.УстановитьАтрибут("location", РасположениеДампа);
	Иначе
		ПервыйДочерний.УдалитьАтрибут("location");
	КонецЕсли; 
	Возврат мДокументДОМ;
	
КонецФункции

// Считать настройки журнала из документа DOM
//
Процедура ПрочитатьНастройкиЖурнала(Индекс, выхМестоположение, выхВремяХранения, выхПредставлениеСобытий = Неопределено, выхПредставлениеСвойств = Неопределено) Экспорт
	
	УзлыЖурналов = ПолучитьСписокЖурналов();
	УзелЖурнала = УзлыЖурналов.Элемент(Индекс);
	выхМестоположение = УзелЖурнала.ПолучитьАтрибут("location");
	Если Не ЗначениеЗаполнено(ОсновнойКаталогЖурнала) Тогда
		ЭтотОбъект.ОсновнойКаталогЖурнала = выхМестоположение;
	КонецЕсли; 
	выхВремяХранения = УзелЖурнала.ПолучитьАтрибут("history");
	Попытка
		выхВремяХранения = Число(выхВремяХранения);
	Исключение
		выхВремяХранения = 1;
	КонецПопытки;
	//Для Каждого Атрибут Из УзелЖурнала.Атрибуты Цикл
	//	Если Атрибут.ЛокальноеИмя = "location" Тогда
	//		Попытка
	//			Местоположение = Атрибут.ЗначениеУзла;
	//		Исключение
	//			Местоположение = "";
	//		КонецПопытки;
	//	КонецЕсли;
	//	Если Атрибут.ЛокальноеИмя = "history" Тогда
	//		Попытка
	//			ВремяХранения = Число(Атрибут.ЗначениеУзла);
	//		Исключение
	//			ВремяХранения = 1;
	//		КонецПопытки;
	//	КонецЕсли;
	//КонецЦикла;
	
	выхПредставлениеСобытий = ПредставлениеОтбораСобытийЖурнала(Индекс);
	выхПредставлениеСвойств = ПредставлениеОтбораСвойствЖурнала(Индекс);
	
КонецПроцедуры

Функция ПредставлениеОтбораСобытийЖурнала(Индекс) Экспорт
	
	СписокУзловЖурнала = ПолучитьСписокУзловЖурнала(Индекс);
	ПредставлениеСобытий = ПредставлениеОтбораСобытийПоСпискуУзлов(СписокУзловЖурнала);
	Возврат ПредставлениеСобытий;

КонецФункции

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

КонецФункции

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

КонецФункции

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

КонецФункции

// Запись настройки журнал в документ DOM
//
Процедура ЗаписатьНастройкиЖурнала(Индекс, Местоположение, ВремяХранения) Экспорт
	
	ЭлементДомЖурнала = ПолучитьУзелЖурнала(Индекс);
	Если ЭлементДомЖурнала = Неопределено Тогда
		Возврат;
	КонецЕсли;
	ЭлементДомЖурнала.УстановитьАтрибут("location", XMLСтрока(Местоположение));
	ЭлементДомЖурнала.УстановитьАтрибут("history", XMLСтрока(ВремяХранения));
	
КонецПроцедуры

// Считать настройки журналов из документа DOM
//
Процедура ПрочитатьНастройкиЖурналов(ТабличноеПолеЖурналы) Экспорт
	
	ТабличноеПолеЖурналы.Очистить();
	УзлыЖурналов = ПолучитьСписокЖурналов();
	Для Инд = 0 По УзлыЖурналов.Количество() - 1 Цикл
		Журнал = ТабличноеПолеЖурналы.Добавить();
		Журнал.НомерЖурнала = Инд + 1;
		ПрочитатьНастройкиЖурнала(Инд, Журнал.Местоположение, Журнал.ВремяХранения, Журнал.События, Журнал.Свойства);
		Журнал.Доступен = Не ирОбщий.ЛиКаталогТехножурналаНедоступенЛкс(Журнал.Местоположение, НаСервере);
	КонецЦикла;
	
КонецПроцедуры

// Изменить пути к файлам технологического журнала
//
Процедура УстановитьПути(КаталогЖурнала, КаталогДампа, ДокументДОМПриемник = Неопределено) Экспорт
	
	Если ДокументДОМПриемник = Неопределено Тогда
		ДокументДОМПриемник = мДокументДОМ;
	КонецЕсли; 
	ЭлементДамп = ДокументДОМПриемник.ПолучитьЭлементыПоИмени("dump");
	Если ЭлементДамп.Количество() > 0 Тогда
		ЭлементДамп = ЭлементДамп.Элемент(0);
	Иначе
		ЭлементДамп = Неопределено;
	КонецЕсли;
	Если ЭлементДамп <> Неопределено Тогда
		Если ЗначениеЗаполнено(КаталогДампа) Тогда
			ЭлементДамп.УстановитьАтрибут("location", КаталогДампа);
		КонецЕсли;
	КонецЕсли;
	
	Журналы = ДокументДОМПриемник.ПолучитьЭлементыПоИмени("log");
	Для Инд = 0 По Журналы.Количество() - 1 Цикл
		Журнал = Журналы.Элемент(Инд);
		Если ЗначениеЗаполнено(КаталогЖурнала) Тогда
			Журнал.УстановитьАтрибут("location", КаталогЖурнала);
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////
// СЕРВИСНЫЕ ФУНКЦИИ

// Перевести десятичное число в двоичное представление и 
// разместить в строке в перевернутом виде
//
Процедура ДесятичноеВДвоичное(Знач Число)
	
	мДвоичноеЧисло = "";
	мЧисло = Число;
	
	Пока Число >= 1 Цикл
		
		Остаток = Число % 2;
		Число = Цел(Число / 2);
		
		мДвоичноеЧисло = мДвоичноеЧисло + Строка(Остаток);
		
	КонецЦикла;
	
КонецПроцедуры

// Проверка взведения бита в числе
//
Функция ПроверитьБитЛкс(НомерБита, Число) Экспорт
	
	Если Число <> мЧисло Тогда
		ДесятичноеВДвоичное(Число);
	КонецЕсли;
	
	Если СтрДлина(мДвоичноеЧисло) < НомерБита Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Если Сред(мДвоичноеЧисло, НомерБита, 1) = "1" Тогда
		Возврат Истина;
	Иначе
		Возврат Ложь;
	КонецЕсли
	
КонецФункции

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

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

// Функция заменяет символ на другой
//
Функция ЗаменитьСимвол(Строка, Что, НаЧто) Экспорт
	
	Возврат СтрЗаменить(Строка, Что, НаЧто);
	
КонецФункции

////////////////////////////////////////////////////////////////////////////////
// ОБЩИЕ ОБРАБОТЧИКИ СОБЫТИЙ

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

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

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

////////////////////////////////////////////////////////////////////////////////
// ФУНКЦИИ РАБОТЫ С ШАБЛОНАМИ

// Добавляет описание шаблона в кэш
Процедура ДобавитьОписаниеШаблона(Имя, Описание) Экспорт
	
	Элемент = КэшОписанияШаблонов.НайтиПоЗначению(Имя);
	Если Элемент = Неопределено Тогда
		КэшОписанияШаблонов.Добавить(Имя, Описание);
	Иначе
		Элемент = Описание;
	КонецЕсли;

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

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

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

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

////////////////////////////////////////////////////////////////////////////////
// Стандартные шаблоны

// Пустой шаблон
//
Процедура ПустойШаблон(СписокВыбора, КаталогЖурнала, КаталогДампа, Описание)
	
	Если Описание Тогда
		Имя = "__empty";
		Представление = "Пустой шаблон";
		Описание = "Настройка технологического журнала на поведение по умолчанию, " +
				   "как если бы конфигурационного файла не было.";
		
		СписокВыбора.Добавить(Имя, Представление);
		ДобавитьОписаниеШаблона(Имя, Описание);
		Возврат;
	КонецЕсли;
	мДокументДОМ = Новый ДокументDOM("http://v8.1c.ru/v8/tech-log", "config");
	Элемент = СоздатьЭлементДОМ("dump");
	Элемент.УстановитьАтрибут("create", "true");
	//Элемент.УстановитьАтрибут("location", "");
	Элемент.УстановитьАтрибут("type", "0");
	Элемент.УстановитьАтрибут("prntscrn", "false");
	мДокументДОМ.ПервыйДочерний.ДобавитьДочерний(Элемент);
		
КонецПроцедуры

Функция ЗагрузитьШаблон(ИмяШаблона, КаталогЖурнала, КаталогДампа)
	
	МакетШаблона = ПолучитьМакет(ИмяШаблона);
	ТекстШаблона = МакетШаблона.ПолучитьТекст();
	Позиция = Найти(ТекстШаблона, "<?xml");
	Описание = Лев(ТекстШаблона, Позиция - 1);
	ТекстШаблона = Сред(ТекстШаблона, Позиция);
	ДокументДОМПриемник = ПрочитатьДокументДомИзСтроки(ТекстШаблона);
	Возврат ДокументДОМПриемник;
		
КонецФункции

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

мВариантыРасположенияФайла = ирОбщий.ВариантыРасположенияКонфигурационногоФайлаЛкс(мСписокВариантовРасположенияКонфигурационногоФайла);
ВариантРасположенияФайлаНастроек = мВариантыРасположенияФайла.АктивныйФайл;
мКодировкаФайла = "UTF-8";

#КонецЕсли
