//******************************************************************************
// Универсальный механизм "Комментирование выполняемых действий"
//******************************************************************************

Перем РежимТрассировки Экспорт; // 0/1 - определяет, используется ли при расчете режим трассировки хода расчета
Перем НазваниеТрассировки Экспорт; //

// Структура трассировки
//  1 - число - уровень сообщения трассировки
//  2 - таблица значений, список сообщений трассировки
//  3 - строка, описатель трассировки
Перем _Трассировка; // список значений
                        
Перем _фТрассировкаБылаПоказана; // 1 - трассировка показывалась, не надо открывать в деструкторе

Функция Конт(Конт) Возврат Конт; КонецФункции
Функция Сам() Возврат Конт(Контекст); КонецФункции

//------------------------------------ ------------------------------------ 
Процедура Конструктор()
	Сам().СоздатьТрассировку();
	_фТрассировкаБылаПоказана = 0;
	РежимТрассировки = 1;
КонецПроцедуры // Конструктор 
//------------------------------------ ------------------------------------ 
Процедура Деструктор()
	Если _фТрассировкаБылаПоказана = 0 Тогда
		Сам().ПоказатьТрассировку();	   
	КонецЕсли;
КонецПроцедуры // Деструктор
// ---------------------------------------  ---------------------------------
процедура ПриЗаписи_НазваниеТрассировки(ЗначениеДляУст)      
	НазваниеТрассировки = ЗначениеДляУст;
	_Трассировка.УстановитьЗначение(3, НазваниеТрассировки);
	//_Трассировка.Установить("Описание", НазваниеТрассировки);
КонецПроцедуры // ПриЗаписи_НазваниеТрассировки

// СоздатьТрассировку(Описание="")
//
// Параметры: 
// 	Описание - строка, описание трассировки - заголовок фрагмента трассировки
//
// Описание:
// 	Создает и заполняет начальными значениями список значений-трассировку
// 	Полученный список значений в дальнейшем используется в функциях 
//  СообщениеТрассировки
//  ПоказатьТрассировку
//
// Структура трассировки
//  1 - число - уровень сообщения трассировки
//  2 - таблица значений, список сообщений трассировки
//  3 - строка, описатель трассировки
//
Процедура СоздатьТрассировку(Описание) Экспорт 
	Если ТипЗначенияСтр(_Трассировка) <> "СписокЗначений" Тогда
		_Трассировка = СоздатьОбъект("СписокЗначений"); 
	Иначе
		_Трассировка.УдалитьВсе();
	КонецЕсли;                         
	НазваниеТрассировки = ?(ПустоеЗначение(Описание)=1, "Трассировка", Описание);
	
   //СписокСообщений = СоздатьОбъект("СписокЗначений");
   СписокСообщений = СоздатьОбъект("ТаблицаЗначений");
   СписокСообщений.НоваяКолонка("ТекстСообщения","Строка",,,"Текст сообщения",50);
   СписокСообщений.НоваяКолонка("ТипСообщения","Число",1);
   СписокСообщений.НоваяКолонка("Форма");
   СписокСообщений.НоваяКолонка("Объект");
   СписокСообщений.НоваяКолонка("Контрол","Строка",20);
   _Трассировка.ДобавитьЗначение(0);					// уровень сообщения трассировки
   _Трассировка.ДобавитьЗначение(СписокСообщений);		// список сообщений трассировки
   _Трассировка.ДобавитьЗначение(НазваниеТрассировки);	// описание трассировки 
   //_Трассировка.ДобавитьЗначение(Описание, "Описание");	// описание трассировки 
КонецПроцедуры      // СоздатьТрассировку()

Процедура ОчиститьТрассировку() Экспорт
	
	_Трассировка.ПолучитьЗначение(2).УдалитьСтроки();
   
	_Трассировка.УстановитьЗначение(1, 0);					// уровень сообщения трассировки
КонецПроцедуры	// ОчиститьТрассировку

//******************************************************************************
// ВывестиВОкноСообщений()
//
// Параметры:
//  <ИмяПараметра> - <ТипПараметра>, <ОписаниеПараметра>.
//
// Вызывается из формул элементов диалога:
// Вызывается из ячеек табличного документа:
//
// Описание:
//  

Процедура ВывестиВОкноСообщений()
	
	СписокСообщений = _Трассировка.ПолучитьЗначение(2); // таблица сообщений трассировки    
	Для Сч=1 По СписокСообщений.КоличествоСтрок() Цикл 
		СписокСообщений.ПолучитьСтрокуПоНомеру(Сч);
		Message(СписокСообщений.ТекстСообщения); // текст сообщения
	КонецЦикла;  
	
КонецПроцедуры // ВывестиВОкноСообщений()

//******************************************************************************
// void ПоказатьТрассировку()
//
// Описание:
// 	Отображает список сообщений трассировки в форме обработки _Трассировка
//

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

//******************************************************************************
// СообщениеТрассировки(Сообщение, ТипСообщения, ИзменениеУровняСообщения, стрПараметры, ...)
//
// Параметры: 
//  Сообщение - текст сообщения трассировки
//  ТипСообщения - число 0 - обычное сообщение (просто комментарий), 
//                                           1 - "красное" сообщение (фатальная ошибка)
//                                           -1 - "синее" сообщение (предупреждение)
//  ИзменениеУровняСообщения - число "1" - для увеличения уровня трассировки (сообщение имеет "вложенный" характер)
//           	                  Текущее сообщение и все последующие будут "на уровень больше" (правее)
//                             число "-1" - для уменьшения уровня трассировки
//  !!!  !!! !!!   	               Текущее сообщение и все последующие сообщения будут "на уровень меньше" (левее) !!! 
//
// стрПараметры - обозначения неопределенного числа параметров (например, "{Форма, 1,2, Контрол}" )
// может быть пара параметров
//  %%1, %%2 и т.п. - параметр, подставляемый в текст сообщения
//  сразу за ним - форматная строка, используемая для соответствующего параметра (ф.Формат)
//
// а также:
//  Форма -     необязательный параметр - форма, которую нужно открыть 
//              для обработки сообщения
//  Объект -    необязательный параметр - объект, который нужно активизировать (для форм списка) 
//				для обработки сообщения
//  Контрол -   необязательный параметр - контрол формы, который нужно активизировать для обработки сообщения
//
// Описание:
//  Вводит очередное сообщение трассировки, если параметр _Трассировка не является 
//  подходящим списком значений - выводится сообщение в окно Сообщений
//  При выводе сообщения производится подстановка подстроки %%1, %%2 и т.д. вместо соответствующих 
//  параметров в соответствующем формате.
//
// Например:
//           Трассировка.СообщениеТрассировки("Число: %%1", 0, 0, "{}", 340.23, "Ч(0)9.3")
//           приведет к сообщению - "Число 00340.230"
//
//           Трассировка.СообщениеТрассировки("Число: %%1", 1, 1, "{1,2,Форма}", 340.23, "Ч(0)9.3", Док)
//           приведет к красному сообщению со сдвигом вправо - "Число 00340.230" с расшифровкой
//

//Процедура СообщениеТрассировки(Сообщение, ТипСообщения, ИзменениеУровняСообщения, стрПараметры) Экспорт
Процедура СообщениеТрассировки(Сообщение, стрПараметры) Экспорт
	//Если (РежимТрассировки = 1) или (ТипСообщения<>0) Тогда 
	Если РежимТрассировки = 0 Тогда
		Возврат;
	КонецЕсли;                        

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

      ТекущийУровень = _Трассировка.ПолучитьЗначение(1);
// Артур -- !!!Внимание !! Изменил поведение
      //Если ИзменениеУровняСообщения>0 Тогда
      //      ТекущийУровень = ТекущийУровень+1;
      //      _Трассировка.УстановитьЗначение(1,ТекущийУровень);
      //КонецЕсли;
      ТекущийУровень = ТекущийУровень+ИзменениеУровняСообщения;
      _Трассировка.УстановитьЗначение(1,ТекущийУровень);
// завершение		  

      ТекстСообщения = "";

      Для Сч=1 По ТекущийУровень Цикл
            ТекстСообщения = ТекстСообщения+"    ";
      КонецЦикла;

      ТекстСообщения = ТекстСообщения+Сообщение;
      Если ИзменениеУровняСообщения<0 Тогда                                  
            ТекущийУровень = Макс(ТекущийУровень+ИзменениеУровняСообщения,0);
            _Трассировка.УстановитьЗначение(1,ТекущийУровень);
      КонецЕсли;

      ТЗ = _Трассировка.ПолучитьЗначение(2);
      ТЗ.НоваяСтрока();
      ТЗ.ТипСообщения = ТипСообщения;
      ТЗ.ТекстСообщения = ТекстСообщения;
      ТЗ.Форма = Форма;
      ТЗ.Объект = Объект;
      ТЗ.Контрол = Контрол;
КонецПроцедуры    // СообщениеТрассировки()   

//------------------------------------ ------------------------------------ 
Процедура Сообщить(Сообщение, Маркер) Экспорт
	Если Найти(Маркер, "!") > 0 Тогда                    
		//Тип = ?(Найти(Маркер, "!!!") > 0, 3, ?(Найти(Маркер, "!!") > 0, 2, 1));
		Сам().СообщениеТрассировки(Сообщение, "{Тип}", 1);
	ИначеЕсли Врег(Маркер)="I" Тогда
		Сам().СообщениеТрассировки(Сообщение, "{Тип}", -1);
	Иначе
		Сам().СообщениеТрассировки(Сообщение, "");
	КонецЕсли;
КонецПроцедуры // Сообщить  

//------------------------------------ ------------------------------------ 
Процедура СообщитьСОшибкой(Сообщение) Экспорт
	Сам().Сообщить(Сообщение, "!!");
КонецПроцедуры // СообщитьСОшибкой