//	+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++
//	|                     Обертка над методами классов компонент 1С++ и                         |
//	+                                        formex                                             +
//	|                                                                                           |
//	+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++

//---------------------------------------------------------------------------------------------
// Собственные атрибуты
Перем гСервис;
Перем гКэш;
Перем гИнформатор;
Перем гРасширениеФормы;


//******************************************************************************
// НормализоватьКонтекст(СсылаКонтекст)
//
// Параметры: 
//  СсылаКонтекст
//
// Возвращаемое значение:
//  Неопределенный
//
// Описание:
//  Возвращает ссылка на переданный контекст
//
Функция НормализоватьКонтекст(СсылаКонтекст)
	
	Возврат СсылаКонтекст;
	
КонецФункции // НормализоватьКонтекст()


//******************************************************************************
// _this()
//
// Параметры: 
//  СсылкаКонтекст			- контекст
//
// Возвращаемое значение:
//  ГрупповойКонтекст		- ссылка на контекст
//
// Описание:
//  Возвращает ссылку на контекст
//
Функция _this()
	
	Возврат НормализоватьКонтекст(Контекст);
	
КонецФункции // _this()


//******************************************************************************
// ПолучитьПеременную(Конт, Идентификатор)
//
// Параметры: 
//  Конт, Идентификатор
//
// Возвращаемое значение:
//  Нет
//
// Описание:
//  ТекстОписания
//
Функция ПолучитьПеременную(Конт, Идентификатор) Экспорт
	
	Результат	= "";
	гСервис.ПолучитьПеременнуюКонтекста(Конт, Идентификатор, Результат);
	
	Возврат Результат;
КонецФункции // ПолучитьПеременную()


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


//******************************************************************************
// ПолныйТипКонтекста(СсылкаКонтекст)
//
// Параметры: 
//  СсылкаКонтекст
//
// Возвращаемое значение:
//  Строка
//
// Описание:
//  Возвращает полный тип контекста
//
Функция ПолныйТипКонтекста(СсылкаКонтекст) Экспорт
	
	Результат		= "";
	ТипКонтекста	= ТипЗначенияСтр(СсылкаКонтекст);
	
	//---------------------------------------------------------------------------------------------
	// Бывают "пустые контексты", например список констант
	Если ПустаяСтрока(ТипКонтекста) = 1 Тогда
		Возврат Результат;
	КонецЕсли;
	
	//---------------------------------------------------------------------------------------------
	// Для групповых контекстов
	Если ТипКонтекста = "ГрупповойКонтекст" Тогда
		Если гИнформатор.СвойствоСуществует(СсылкаКонтекст, "Форма") = 1 Тогда
			//---------------------------------------------------------------------------------------------
			// Возвращаем полный тип контекста
			гРасширениеФормы.УстановитьФорму(СсылкаКонтекст.Форма);
			Результат	= гРасширениеФормы.ПолныйТипОбъекта();
		Иначе
			//---------------------------------------------------------------------------------------------
			// Пытаемся по наличию методов получить тип контекста
			Если гИнформатор.МетодСуществует(СсылкаКонтекст, "ОбработкаПроведения") = 1 Тогда
				Результат	= "Документ." + СсылкаКонтекст.Вид();
			ИначеЕсли гИнформатор.МетодСуествует("НачалоТекущегоПериода") = 1 Тогда
				Результат	= "ЗаписьЖурналаРасчетов." + СсылкаКонтекст.Вид();
			Иначе
				Результат	= "Константы";
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	Возврат Результат;
КонецФункции // ПолныйТипКонтекста()


//******************************************************************************
// ВыполнитьМетод(Конт, Идентификатор)
//
// Параметры: 
//  Конт, Идентификатор
//
// Возвращаемое значение:
//  Нет
//
// Описание:
//  ТекстОписания
//
Функция ВыполнитьМетод(Конт, Идентификатор) Экспорт
	Перем Результат;
	
	//---------------------------------------------------------------------------------------------
	// Для начала получим список переданных параметров
	СписокПараметров	= _this().ПолучитьСписокПараметров("ВыполнитьМетод");
	Если ТипЗначенияСтр(СписокПараметров) <> "СписокЗначений" Тогда
		СписокПараметров	= СоздатьОбъект("СписокЗначений");
	КонецЕсли;
	
	//---------------------------------------------------------------------------------------------
	// Проверим, существует ли вызываемый метод в объекте
	Если гИнформатор.МетодСуществует(Конт, Идентификатор) = 0 Тогда
		_this()._ВыброситьОшибку("В вызываемом контексте " + ПолныйТипКонтекста(Конт) + " не найден метод " + Идентификатор + " !");
		Возврат Результат;
	КонецЕсли;
	// Также необходимо определиться, что вызываем процедуру или функцию
	Если гИнформатор.ЯвляетсяФункцией(Конт, Идентификатор) = 1 Тогда
		гСервис.ВыполнитьФункцию(Конт, Идентификатор, СписокПараметров, Результат);
	Иначе
		гСервис.ВыполнитьПроцедуру(Конт, Идентификатор, СписокПараметров);
	КонецЕсли;
	
	Возврат Результат;
КонецФункции // ВыполнитьМетод()


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


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