//	+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++
//	|                              Менеджер статических объектов                                |
//	+                                        ShmalevoZ                                          +
//	|                                         2008-07                                           |
//	+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++

//---------------------------------------------------------------------------------------------
// Собственные атрибуты класса
Перем гИдентификаторТаблицыОписаний;
Перем гИдентификаторТаблицыСсылок;


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


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


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


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


//******************************************************************************
// ПолучитьИдентификатор()
//
// Параметры: 
//  
//
// Возвращаемое значение:
//  Строка					: уникальный идентификатор
//
// Описание:
//  Формирует уникальный идентификатор с первым символом - НЕ ЦИФРОЙ и исключая дефисы
//
Функция ПолучитьИдентификатор()
	
	Идентификатор	= СоздатьОбъект("Guid");
	Результат		= "1";
	СтрокаЧисел		= "0123456789";
	
	Пока Найти(СтрокаЧисел, Лев(Результат, 1)) <> 0 Цикл
		Идентификатор.Новый();
		Результат	= Идентификатор.ВСтроку();
	КонецЦикла;
	
	Результат	= СтрЗаменить(Результат, "-", "");
	
	Возврат Результат;
КонецФункции // ПолучитьИдентификатор()


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


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


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


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


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


//******************************************************************************
// Количество()
//
// Параметры: 
//  
//
// Возвращаемое значение:
//  Число					: количество статических объектов
//
// Описание:
//  Возвращает количество статических объектов
//
Функция Количество() Экспорт
	
	Результат	= ПолучитьТаблицуОписаний().КоличествоСтрок();
	
	Возврат Результат;
КонецФункции // Количество()


//******************************************************************************
// Зарегистрирован(ИдентификаторПредставление)
//
// Параметры: 
//  ИдентификаторПредставление	: искомый идентификатор/представление
//
// Возвращаемое значение:
//  Число						: номер зарегистрированного объекта
//
// Описание:
//  Возвращает номер зарегистриованного объекта с искомым идентификатором/представлением,
//  0 в случае если такого объекта не найдено
//
Функция Зарегистрирован(НомерИдентификатор) Экспорт
	
	Результат	= Мин(1, ПолучитьНомерОбъекта(НомерИдентификатор, 0));
	
	Возврат Результат;
КонецФункции // Зарегистрирован()


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


//	+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++
//	|                                 Инициализация класса                                      |
//	+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++---+++

//******************************************************************************
// Инициализация()
//
// Параметры: 
//  
//
// Возвращаемое значение:
//  Нет
//
// Описание:
//  Создает необходимые глобальные структуры
//
Процедура Инициализация()
	
	//---------------------------------------------------------------------------------------------
	// Необходимые структуры
	глДанныеСтатическихОбъектовКонфигурации	= СоздатьОбъект("ТаблицаЗначений");
	глДанныеСтатическихОбъектовКонфигурации.НоваяКолонка(гИдентификаторТаблицыОписаний);
	глДанныеСтатическихОбъектовКонфигурации.НоваяКолонка(гИдентификаторТаблицыСсылок);
	глДанныеСтатическихОбъектовКонфигурации.НоваяСтрока();
	
	// инициализируем таблицу описаний
	ТаблицаОписаний	= СоздатьОбъект("ТаблицаЗначений");
	ТаблицаОписаний.НоваяКолонка("Идентификатор");		// GUID
	ТаблицаОписаний.НоваяКолонка("Тип");				// ТипЗначенияСтр(Объект)
	ТаблицаОписаний.НоваяКолонка("Представление");		// пользовательское представление
	ТаблицаОписаний.НоваяКолонка("Индекс");				// представление в верхнем регистре для поиска
	глДанныеСтатическихОбъектовКонфигурации.УстановитьЗначение(1, гИдентификаторТаблицыОписаний, ТаблицаОписаний);
	
	// и таблицу ссылок
	ТаблицаСсылок	= СоздатьОбъект("ТаблицаЗначений");
	ТаблицаСсылок.НоваяСтрока();
	глДанныеСтатическихОбъектовКонфигурации.УстановитьЗначение(1, гИдентификаторТаблицыСсылок, ТаблицаСсылок);
	
	//---------------------------------------------------------------------------------------------
	// Загрузим все классы, наследники от Общие.Статик.Объект
	Информатор			= СоздатьОбъект("MetaInfoClasses");
	СписокКлассов		= Информатор.ПолучитьВсеИменаКлассов();
	КоличествоКлассов	= СписокКлассов.РазмерСписка();
	Искомое				= "Общие.Статик.Объект";
	Для НомерКласса = 1 По КоличествоКлассов Цикл
		Идентификатор	= СписокКлассов.ПолучитьЗначение(НомерКласса);
		Если Информатор.ЯвляетсяОбъектом(Идентификатор, Искомое) = 1 Тогда
			Если Зарегистрирован(Идентификатор) = 0 Тогда
				// Достаточно создать объект этого типа. Метод регистрации он вызовет сам
				Объект	= СоздатьОбъект(Идентификатор);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры // Инициализация()


//******************************************************************************
// Конструктор()
//
// Параметры: 
//  
//
// Возвращаемое значение:
//  Нет
//
// Описание:
//  Вызывается при создании экземпляра класса
//
Процедура Конструктор()
	
	гИдентификаторТаблицыОписаний	= "Описания";
	гИдентификаторТаблицыСсылок		= "Ссылки";
	
	Тип	= ТипЗначенияСтр(глДанныеСтатическихОбъектовКонфигурации);
	Если Тип <> "ТаблицаЗначений" Тогда
		Инициализация();
	КонецЕсли;
	
КонецПроцедуры // Конструктор()
