	// aplClassifierMgr.h: interface for the CaplClassifierMgr class.
//
//////////////////////////////////////////////////////////////////////
#pragma once

#include <StepData.h>
#include <aplNetStepData.h>
#include <apl_gui.h>
#include "aplStepManager.h"

// таблица фильтров характеристик
class TArrElValChar: public CaplTAggr<ElValChar*,ElValChar*,APLAGGR_UNIQUE_LIST_AUTOKILLREF>
{
/**<Клонировать список. Элементы нового 
списка создаются оператором new и инициализируются 
оператором присваивания из элементов старого списка
Т.е. тип должен иметь корректный оператор присваивания!*/
public:
	void Clone(CaplTAggr <ElValChar*,ElValChar*,APLAGGR_UNIQUE_LIST_AUTOKILLREF> *original_aggr)
	{
		ElValChar* new_el;
		Clear();
		if(original_aggr==0)return;
		for(int i=0;i<original_aggr->Size;i++){
			new_el= new ElValChar(original_aggr->GetAt(i));
			Add(new_el);
		}
	}
};


#define APL_INSTANCE_CLIPBOARDFORMAT _T("APL_INSTANCE_CLIPBOARDFORMAT")

#define APL_SELECT_CLASSIFIER_SYSTEM	0x0001	//Выбор справочника
#define APL_SELECT_CLASSIFIER_LEVEL		0x0002	//Выбор элемента структуры справочника
#define APL_SELECT_CLASSIFIER_ITEM		0x0004	//Выбор объекта из справочника
#define APL_USE_SYSTEM_SETTINGS			0x0008
#define APL_CLASSIFIER_EDITOR			0x0010	//Запуск в режиме редактирования
#define APL_CLASSIFIER_EXE_EDITOR		0x0020	//Запуск из EXE модуля в режиме редактирования
#define APL_CONCEPT						0x0040	//Выбор элемента структуры справочника понятий
                                            //Если флаг установлен, то только из справочника понятий, если не установлен, то  из справочника понятий  и объектов
#define APL_HIDE_ESQUISSE				0x0080	//Не отображать окно с эскизом
#define APL_HIDE_TABLE					0x0100	//Не отображать окно с таблицей (работает только для справочников понятий с предустановленным соединением)
#define APL_AUTO_HIDE_TABLE				0x0200	//Автоматически скрывать таблицу для справочников понятий с предустановленным соединением
#define APL_SHOW_ESQUISSE	            0x0400  // Принудительный показ эскизов. 

// уровень доступа элемента структуры справочника, необходимый для операций с объектами
#define ACCESS2LEVEL_FOR_OBJECT aplRW
#define ACCESS2LEVEL_FOR_OBJECT_DESCR APL_T("доступ на изменение")
// уровень доступа справочника, необходимый для операций со структурой 
#define ACCESS2SYSTEM_FOR_STRUCTURE aplOWN
#define ACCESS2SYSTEM_FOR_STRUCTURE_DESCR APL_T("полный доступ")
// уровень доступа элемента структуры справочника, необходимый для операций со структурой справочника
#define ACCESS2LEVEL_FOR_STRUCTURE aplRW
#define ACCESS2LEVEL_FOR_STRUCTURE_DESCR APL_T("доступ на изменение")

/*
	Структура для описания фильтра в диалоге "показать как справочник"
	Ограничения:
	*) В полях отбора можно использовать только атрибуты типа aplSTRING. Атрибуты остальных типов будут проигнорированы
	*) В default_relation можно использовать только отношения для строк: CaplQLQuery::aplEQUAL, CaplQLQuery::aplLIKE,CaplQLQuery::aplNOTLIKE,
			CaplQLQuery::aplLIKELEFT, CaplQLQuery::aplLIKERIGHT,CaplQLQuery::aplNOTEQUAL,CaplQLQuery::aplNOTLIKELEFT,CaplQLQuery::aplNOTLIKERIGHT
		Значение по умолчанию - CaplQLQuery::aplLIKE
	*) В полях для отображения ...
*/

struct CLASS_DECL_APL_STEP_MGR  SSelectItemFilter												 
{																		 
	SSelectItemFilter();												 
																		 
	CaplEntity* search_entity; // ентити, по которой надо искать		 
	CString search_entity_name;	// имя типа для отображения пользователю 

	CaplTAggr <CaplAttr*,CaplAttr*,APLAGGR_UNIQUE|APLAGGR_LIST> selection_array; // Поля отбора 
	CStringArray selection_array_names; // Поля отбора - имена атрибутов для отображения в выпадающем списке

	CaplAttr*	default_selection; // Поле отбора по умолчанию	
	CaplQLQuery::aplQLLogRelation	default_relation; // Отношение отбора по умолчанию.
	CString	default_value; // Значение для отбора по умолчанию	

	CaplTAggr <CaplAttr*,CaplAttr*,APLAGGR_UNIQUE|APLAGGR_LIST>	display_array; // Отображаемые поля	
	CaplAttr* sorting_field; // Поле сортировки

};

class CLASS_DECL_APL_STEP_MGR CaplClassifierMgr : public CaplStepManager  
{
public:
	/**	Выбор объекта из справочника, элемента структуры справочника и справочника
		@param Item  результат, выбранный элемент (элемент структуры или объект)
		@pBaseClassifierSystems/BaseClassifierSystem корневой справочник/справочник
		@param mode режим выбора (объект, справочник, элемент структуры)

		APL_SELECT_CLASSIFIER_SYSTEM	Выбор справочника                    (нельзя комбинировать с APL_SELECT_CLASSIFIER_ITEM)
		APL_SELECT_CLASSIFIER_LEVEL		Выбор элемента структуры справочника (нельзя комбинировать с APL_SELECT_CLASSIFIER_ITEM)
		APL_SELECT_CLASSIFIER_ITEM		Выбор объекта из справочника         (нельзя комбинировать с APL_SELECT_CLASSIFIER_LEVEL и APL_SELECT_CLASSIFIER_SYSTEM)
		APL_USE_SYSTEM_SETTINGS			
		APL_CLASSIFIER_EDITOR			Запуск в режиме редактирования
		APL_CLASSIFIER_EXE_EDITOR		Запуск из EXE модуля в режиме редактирования
		APL_CONCEPT						Ограничение выбора элемента структуры справочника понятий (только для режима справочника понятий (CClassifierSelectDlg)
													//Если флаг установлен, то выбор возможен только из справочника понятий, если не установлен, то  из справочника понятий  и объектов
		APL_HIDE_ESQUISSE				Не отображать окно с эскизом (только для режима справочника понятий и объектов (CSelectClassifierItemDlg)

		APL_HIDE_TABLE					Не отображать окно с таблицей (работает только для справочников понятий и объектов с предустановленным соединением)
		                                Если установлен, то всегда открывается диалог справочника понятий и объектов, но без таблицы
										
		APL_SHOW_ESQUISSE	            Принудительный показ эскизов.  Актуально долько для APL_SELECT_CLASSIFIER_SYSTEM и APL_SELECT_CLASSIFIER_LEVEL
										Если установлен, то справочник понятий открывается в режиме справочника понятий и объектов, но включается APL_HIDE_TABLE
										(Нужно, например, для выбора level c показом эскизов)

		@param lpszTitle заголовок окна выбора
		@param pWnd указатель на MainWnd (служит для присвоения этой переменной указателя на диалог выбора, чтобы работа приложения
		не завершилась стразу после выхода из функции WinApp::InitInstance())
		extItems - если !=0, то появляется кнопка "Добавить".  Можно выбирать элементы и нажимать "добавить", при этом они будут накапливаться как в корзине
		@return <b>true</b> в случае нажатия кнопки ОК <b>false</b> в противном случае*/
	bool SelectItem(CaplInstance **Item, aplExtent &BaseClassifierSystems, UINT mode = APL_SELECT_CLASSIFIER_ITEM, LPCTSTR lpszTitle = NULL, SSelectItemFilter* filter = NULL);
	bool SelectItem(CaplInstance **Item, CaplInstance* BaseClassifierSystem=NULL, UINT mode = APL_SELECT_CLASSIFIER_ITEM, LPCTSTR lpszTitle = NULL, CWnd **pWnd=NULL, aplExtent *extItems=0);

	/** Создает справочник. Если обозначение или наименование не заданы - выводит диалог
	создания справочника
		@param ParentElement справочник верхнего уровня
		@param id обозначение создаваемоого справочника
		@param name наименование создаваемоого справочника
		@param descr описание создаваемоого справочника
		@param TestUnique если true - перед созданием будет выполнена проверка на существование
		справочника с аналогичным id 
		@return указатель на справочник при удачном выполнении и 0 в случае ошибки */	
	CaplInstance* CreateClassifierSystem(CaplInstance *ParentElement=NULL,LPCTSTR id = NULL, LPCTSTR name = NULL, LPCTSTR descr = NULL, bool TestUnique = true);

	/** Создает  элемент структуры справочника. Если обозначение или наименование не заданы - выводит диалог
	создания элемента структуры справочника
		@param ClassifierSystem справочник (обязательный параметр)
		@param ParentElement элемент структуры вышестоящего уровня
		@param id обозначение создаваемого элемента структуры
		@param name наименование создаваемого элемента структуры
		@param descr описание создаваемого элемента структуры
		@param TestUnique если true - перед созданием будет выполнена проверка на существование
		уровня с аналогичным id у указанного справочника
		@return указатель на элемент структуры справочника при удачном выполнении и 0 в случае ошибки */	
	CaplInstance* CreateClassifierLevel(CaplInstance* ClassifierSystem, CaplInstance *ParentElement=NULL, LPCTSTR id = NULL, LPCTSTR name = NULL, LPCTSTR descr = NULL, LPCTSTR code = NULL, bool TestUnique = true);

	/** Удаляет справочник или элемент структуры. Уровни, входящие в справочник в зависимости
	от выбора пользователя или удаляются, или переносятся в родительский справочник (если 
	таковая задана для удаляемого справочника); также удаляются ассоциаторы, связанные с элементом струткуры 
		@param ClassifierSystem удаляемый справочник или элемент структуры справочника
		@param bCheckXmlReferences проверять использование в xml индексах
		@return true при удачном выполнении и false в случае ошибки */	
	bool DeleteClassifierItem(CaplInstance* Item, bool bCheckXmlReferences = true);

	/** Показывает свойства справочника или элемента структуры справочника
		@return true при удачном выполнении и false в случае ошибки */	
	bool ShowClassifierProperties(CaplInstance* Item);

	/** Записывает в элемент структуры справочника или в справочник эскиз
		@param Item элемент структуры справочника или справочник
		@param name_file имя файла, из который будет взят эскиз
		@return true при удачном выполнении и false в случае ошибки */	
	bool PutClassifierEsquisse(CaplInstance *Item,const TCHAR* name_file);

	/** Записывает в элемент структуры справочника или в справочник эскиз из буфера в оперативной памяти.
		@param Item элемент структуры справочника или справочник 
		@param blob_dest ссылка на указатель, из которого будет взят буфер с эскизом
		@param size_buf размер буфера
		@return true при удачном выполнении и false в случае ошибки */	
//	bool PutClassifierEsquisse(CaplInstance *Item, BYTE* blob_dest,long size_buf);

	/** Читает из элемента структуры справочника или справочника эскиз и записывает его
	во временный файл в каталоге temp или аналогичном. Удалить файл после использования 
	должно вызывающее приложение
		@param Item элемент структуры справочника или справочник 
		@param name_file имя файла, в который был записан эскиз
		@return true при удачном выполнении и false в случае ошибки */	
	bool GetClassifierEsquisse(CaplInstance *Item, CString &name_file, CString *original_name=NULL);

	/** Читает из элемента структуры справочника или справочника  эскиз и записывает его
	в буфер в оперативной памяти. Очистить память после использования 
	должно вызывающее приложение
		@param Item элемент структуры справочника или справочник 
		@param blob_dest ссылка на указатель, в который был записан буфер с эскизом
		@param size_buf размер буфера
		@return true при удачном выполнении и false в случае ошибки */	
	bool GetClassifierEsquisse(CaplInstance *Item, BYTE** blob_dest,long &size_buf,CString &only_name, CString *original_name=NULL);

	/** Удаляет эскиз элемента структуры справочника или справочника 
		@param Item элемент структуры справочника или справочник  
		@return true при удачном выполнении и false в случае ошибки */	
	bool DelClassifierEsquisse(CaplInstance *Item);

	
	/** Возвращает список форм для справочника. Если для текущего элемента структуры 
	или справочника	список форм не задан и параметр recursive=true - рекурсивно проходит по родителям 
	уровней, справочникам и родителям справочников пока не найдет объект с заданным списоком форм или корневой справочник 
		@param Item элемент структуры справочника или справочник
		@param name_file имя файла, в который был записан эскиз
		@return true при удачном выполнении и false в случае ошибки */	
	bool GetClassifierForms(CaplInstance *Item, 
					aplExtent &list_forms, bool recursive=true, pCaplInstance *based_item=0);

	/** Переносит справочник от одного родителя к другому
		@param ClassifierSystem справочник
		@param ParentElement новый родительский справочник. Если не задано - справочник становится корневым
		@return true при удачном выполнении и false в случае ошибки */	
	bool MoveClassifierSystem(CaplInstance* MovedSystem, CaplInstance *NewParent=NULL);

	/** Переносит элемент структуры от одного родителя к другому
		@param ClassifierElement элемент структуры
		@param ParentElement новый родительский элемент структуры справочника. Если не задано - элемент структуры справочника становится корневым
		@return true при удачном выполнении и false в случае ошибки */	
	bool MoveClassifierLevel(CaplInstance* MovedElement, CaplInstance *NewParent=NULL, bool bMoveBetweenSystems = false);

	/** Возвращает справочник с указанным именем
	Внимание! Не загружает атрибуты справочника с сервера!
		@param name имя справочника
		@return указатель на справочник при удачном выполнении и 0 в случае ошибки */	
	CaplInstance* GetClassifierSystemBN(LPCTSTR name, bool bFromBase = false);

	/** Возвращает справочник с указанным идентификатором
	Внимание! Не загружает атрибуты справочника с сервера!
		@param id идентификатор справочника
		@return указатель на справочник при удачном выполнении и 0 в случае ошибки */	
	CaplInstance* GetClassifierSystemById(LPCTSTR id, bool bFromBase = false);

	/** Возвращает элемент структуры с указанным именем принадлежащий указанному справочнику. 
	Внимание! Не загружает атрибуты элемента структуры с сервера!
		@param name имя уровня
		@param ClassifierSystem справочник
		@return указатель на элемент структуры справочника при удачном выполнении и 0 в случае ошибки */	
	CaplInstance* GetClassifierLevelByName(LPCTSTR name, CaplInstance* ClassifierSystem);

	/** Возвращает элемент структуры с указанным идентификатором принадлежащий указаннму справочнику
	Внимание! Не загружает атрибуты элемента структуры с сервера!
		@param id идентификатор уровня
		@param ClassifierSystem справочник
		@return указатель на элемент структуры справочника при удачном выполнении и 0 в случае ошибки */	
	CaplInstance* GetClassifierLevelById(LPCTSTR id, CaplInstance* ClassifierSystem, bool bFromBase = true);

	/** Загружает с сервера и возвращает список характеристик-типов для справочника или элемента структуры
		@param item справочник или элемент структуры
		@param out_ext список характеристик-типов
		@param all_level только для элементов структуры - если false то возвращаются
	характеристики только текущего элемента структуры, если true - то характеристики всех родительских уровней и
	справочника, в которую входит элемент структуры
		@param chek_unique только для элемента структуры и если all_level=true - проверяет 
	характеристики родительских элементов структуры и справочника на дублирование. Если пара хапрактеристика-тип
	уже включена в выходной список, она второй раз не включается
		@param load_from_bd если true - то атрибуты справочников предварительно загружаются с сервера; если false - поиск идет в уже загруженном в кеш
		@return true при удачном выполнении и false в случае ошибки */	
	bool GetClassifierCharacteristic(CaplInstance* item,  aplExtent &out_ext,bool all_level=false,bool chek_unique=true,bool load_from_bd=true);
	
	bool GetClassifierElementFilters(CaplInstance* item,TArrElValChar** filters);

	/** Загружает с сервера и возвращает объекты, связанные с заданным  элементом структуры справочника
	(и загружает атрибуты всех объектов)
		@param ClassifierLevel элемент структуры.   Если задать справочник, то функция вернет всё содержимое справочника.
		@param out_ext список объектов
		@param rels указатель на экстент для списка ассоциаторов 
		@param load_data загружать ли аттрибуты для найденных объектов
		@param load_from_bd если true - то ассоциаторы предварительно загружаются с сервера; если false - поиск идет в уже загруженном в кеш
		@return true при удачном выполнении и false в случае ошибки */	
	bool GetSubItems(CaplInstance* ClassifierLevel, aplExtent &out_ext, aplExtent *rels=NULL,bool load_data=true,bool load_from_bd=true);

	/** Загружает с сервера и возвращает объекты, связанные с заданными элементами структуры справочника  
	(и загружает атрибуты всех объектов)
		@param ClassifierLevels список элементов структуры справочника
		@param out_ext список объектов
		@param rels указатель на экстент для списка ассоциаторов 
		@param load_data загружать ли аттрибуты для найденных объектов
		@param load_from_bd если true - то ассоциаторы предварительно загружаются с сервера; если false - поиск идет в уже загруженном в кеш
		@return true при удачном выполнении и false в случае ошибки */	
	bool GetSubItems(aplExtent &ClassifierLevels, aplExtent &out_ext, aplExtent *rels=NULL,bool load_data=true,bool load_from_bd=true);


	
	/** Получить список справочников.
		@param ClassifierSystem справочник родитель. Если равен 0, то будут возвращены справочники верхнего уровня. 
		В противном случае будут возвращены справочники входящие в ClassifierSystem.
		@param SubElements результат - список справочников.
		@param recursive если true - будут возвращены все справочники входящие в указанный рекурсивно. Если false - будет возвращен только 1 уровень.
		@param bFromBase загружать с сервера или только из кэша.
		@return true при удачном выполнении и false в случае ошибки */	
	bool LoadSubClassifierSystems(CaplInstance* ClassifierSystem, aplExtent &SubElements, bool recursive = false, bool bFromBase = true);

	
	/** Получить список элементов структуры справочника 
		@param ClassifierItem элемент структуры справочника - родитель. 
		@param SubElements результат - список элементов структуры справочника.
		@param recursive если true - будут возвращены все элементы структуры входящие в указанный рекурсивно. Если false - будет возвращен только 1 уровень.
		@param bFromBase загружать с сервера или только из кэша.
		@return true при удачном выполнении и false в случае ошибки */	
	bool LoadSubClassifierLevels(CaplInstance* ClassifierItem, aplExtent &SubElements, bool recursive = false, bool bFromBase = true);


	/** Создает ассоциацию между объектом и  элементом структуры справочника. При создании проверяет 
	соответсвие указанного элемента структуры настройкам контроля и соответствие типа связываемого объекта
		@param Item связываемый объект
		@param ClassifierLevel элемент структуры справочника
		@param TestUnique если true - перед созданием будет выполнена проверка на наличие 
		ассоциатора между указанным объектом и элементом структуры справочника
		@return указатель на ассоциатор при удачном выполнении и 0 в случае ошибки */	
	CaplInstance* CreateClassifierAssociation(CaplInstance *Item, CaplInstance* ClassifierLevel, bool TestUnique = true);

	/** Создает ассоциации между списком объектов и элементом структуры справочника. При создании проверяет 
	соответсвие указанного элемента структуры настройкам контроля и соответствие типа связываемых объектов
		@param Items список связываемых объектов
		@param ClassifierLevel элемент структуры справочника
		@param TestUnique если true - перед созданием будет выполнена проверка на наличие 
		ассоциатора между указанными объектами и элементом структуры справочника
		@param Associators если задан - в него при удачном выполнении записывается список ассоциаторов 
		@return true при удачном выполнении и false в случае ошибки */	
	bool CreateClassifierAssociation(aplExtent &Items, CaplInstance* ClassifierLevel, bool TestUnique = true, aplExtent *Associators=0);

	/** Проверяет налимчие связи между объектом и элементом структуры справочника
	@param Item связываемый объект
	@param ClassifierLevel элемент структуры справочника
	@return <btrue</b> Если такая связь существует и <b>false</b> в противном случае*/
	bool TestClassifierAssociation(CaplInstance *Item, CaplInstance *ClassifierItem,pCaplInstance *association=0);

	/** Поиск справочников, в которые входит item 
		@param item искомый объект
		@param classifiers возвращаемый список уровней справочников
		@return true при удачном выполнении и false в случае ошибки */
	bool FindClassifiersContained(CaplInstance *item, aplExtent &classifiers, aplExtent *assoc_ext = NULL);
	bool FindClassifiersContained(aplExtent &items, aplExtent &classifiers, aplExtent *assoc_ext = NULL);

	/// Проверяет наличие item в справочниках, обозначения которых заданы в classifiers_id
	/// classifiers_id - перечень справочников разделенных символом '|'.
	/// Возвращает truе, если есть и false, если нет
	bool CheckItemInClassifierById(CaplInstance *item, LPCTSTR classifiers_id);

	/// Проверяет наличие item в справочниках, обозначения которых заданы опцией option
	/// см. CheckItemInClassifierById
	/// Возвращает truе, если есть и false, если нет
	/// Если bShowMsg==true - выводит сообщение "объект не находится в разрещенных справочниках"
	/// Если опция не задана - возвращает true
	bool CheckItemInClassifierByOption(CaplInstance *item, LPCTSTR option, bool bShowMsg);


	/** Поиск элементов структуры справочников для объектов
		@param map_item2level - карта: объект - уровень (уровень формирует функция
		@param bLoadClassifierInfo - зачитывать данные о справочниках в кэш
		@return true при удачном выполнении и false в случае ошибки */
	bool GetClassifierLevel4Items(CaplMap &map_item2level, bool bLoadClassifierInfo=true);

	/** Удаляет ассоциацию между объектом и элементом структуры справочника. 
		@param Item объект
		@param ClassifierLevel элемент структуры
		@return true при удачном выполнении (и если ассоциатора нет) и false в случае ошибки */	
	bool DeleteClassifierAssociation(CaplInstance *Item, CaplInstance *ClassifierLevel);

	/** Загружает с сервера в локальный кеш информацию о справочнике или об элементе структуры. 
		@param inst элемент структуры справочника или справочник
		@return true при удачном выполнении и false в случае ошибки */	
	bool LoadClassifierInfo(CaplInstance* inst);

	/** Загружает с сервера в локальный кеш информацию о группе справочников или элементов структуры. 
		@param ext список уровней и (или) справочников
		@return true при удачном выполнении и false в случае ошибки */	
	bool LoadClassifierInfo(aplExtent &ext);

	/** Загружает с сервера в локальный кеш информацию о всех справочниках. 
		@return true при удачном выполнении и false в случае ошибки */	
	bool LoadDictionary();

	/** Возвращает номер текущего уровеня в справочнике. 
		@param element проверяемый элемент структуры
		@return номер уровня элемента структуры */	
	int GetLevelClassifierLevel(CaplInstance* element);

	/** Для указанного элемента структуры определяет настройки контроля уровней справочника понятий и
	номер текущего уровня. Если контроль задан - проверяет, удовлетворяет ли текущий уровень
	настройкам
		@param element провряемый элемент структуры
		@return true при совпадении настроек (или отсутствии контроля) и false в случае несовпадения */	
	bool TestConceptLevelOfElement(CaplInstance* element);

	/** Для указанного элемента структуры определяет настройки контроля уровней справочника объектов и
	номер текущего уровня. Если контроль задан - проверяет, удовлетворяет ли текущий уровень
	настройкам
		@param element проверяемый элемент структуры
		@param supress_mesage если false и установлен флаг m_ModeInteractive - в случае отрицательного 
	результата функция выводит сообщение с описанием проблемы. Если true - никаких сообщений не 
	выводится
		@return true при совпадении настроек (или отсутствии контроля) и false в случае 
	несовпадения или если родительская система не может быть использована как справочник 
	объектов */	
	bool TestObjectLevelOfLevel(CaplInstance* element,bool supress_mesage=false);
	

	/** Для указанного элемента структуры определяет настройки контроля типов справочника объектов;
	тип вставляемого объекта. Если контроль задан - проверяет, удовлетворяет ли тип 
	вставляемого объекта настройкам
		@param element проверяемый элемент структуры
		@param object проверяемый вставляемый объект
		@return true при совпадении настроек (или отсутствии контроля) и false в случае 
	несовпадения */	
	bool TestObjectType(CaplInstance* element,CaplInstance* object);

	/** Отображает содержимое элемента структуры справочника в виде таблицы
		@param Item элемент структуры или справочник
		@param is_hide_move_button
		@param redraw если во время вызова функции были изменены параметры справочника/элемента структуры,
		требующие перерисовки дерева, то в этом параметре возвращается true
		@param show_subelements показывать в таблице входящие элементы структуры (для справочника
		входящие элементы структуры показываются всегда)
		@return true при удачном выполнении и false в случае ошибки */	
	bool MakeTable(CaplInstance *Item,bool is_hide_move_button=true,bool *redraw=NULL,bool show_subelements=true);

	/** Возвращает настройки контроля уровней для справочника понятий. Если для текущего элеменнта структуры 
	или справочника	контроль не задан и параметр recursive=true - рекурсивно проходит по родителям 
	элементов структуры, справочникам и родителям справочников пока не найдет объект с заданными настройками контроля 
	или корневой справочник.
		@param Item элемент структуры или справочник, для которого определяются настройки
		@param is_concept_control - в параметре возвращается наличие контроля. Если true - настройки 
		контроля есть
		@param is_last_level - если возвращается true, то для выбора понятий предназначены только 
		листья дерева элементов структуры. Если false - то для выбора доступен диапазон уровней элементов структуры
		определенный следующими параметрами
		@param min_level - возвращает нижнюю границу диапазона
		@param max_level - возвращает верхнюю границу диапазона
		@param recursive - если true - то искать родительские уровни и справочника. Если 
		false - возвращает настройки только текущего уровня/системы
		@return если объект с настройками контроля не найден - возвращает 0. Если найден - возвращает 
	    объект с настроками */	
	CaplInstance* GetConceptLevelParameters(CaplInstance *Item,bool &is_concept_control,bool &is_last_level,int &min_level,int &max_level);

	/** Возвращает настройки доступности и контроля уровней для справочника объектов. Если для 
	текущего элемента структуры или справочника контроль не задан и параметр recursive=true - рекурсивно проходит 
	по родителям элементов, справочникам и родителям справочников пока не найдет объект с заданным уровнем или 
	корневой справочник.
		@param Item элемент структуры или справочник, для которого определяются настройки
		@param can_object - может ли справочник работать как справочник объектов.
		@param is_object_control - в параметре возвращается наличие контроля. Если true - настройки 
		контроля есть
		@param is_last_level - если возвращается true, то для выбора объектов предназначены только 
		листья дерева элементов структуры справочника. Если false - то для выбора доступен диапазон уровней 
		определенный следующими параметрами
		@param min_level - возвращает нижнюю границу диапазона
		@param max_level - возвращает верхнюю границу диапазона
		@param recursive - если true - то искать родительские элементы структуры и справочника. Если 
		false - возвращает настройки только текущего элемента структуры/справочника
		@return если объект с настройками контроля не найден - возвращает 0. Если найден - возвращает 
	    объект с настроками */		
	CaplInstance* GetObjectLevelParameters(CaplInstance *Item,bool &can_object,bool &is_object_control,bool &is_last_level,int &min_level,int &max_level,bool &is_multi_object);

	/** Возвращает настройки контроля типов объектов для справочника объектов. Если для 
	текущего элемента структуры или справочника контроль не задан и параметр recursive=true - рекурсивно 
	проходит по родителям элементов структуры, справочникам и родителям справочников пока не найдет объект с 
	заданным уровнем или корневой справочник.
		@param Item элемент иструктуры ли справочник, для которого определяются настройки
		@param is_object_type_control - в параметре возвращается наличие контроля. Если true - настройки 
		контроля есть
		@param stored_entity - возвращает entity, которые могут быть присоединены к данному справочнику
		@param recursive - если true - то искать родительские элементы структуры справочника. Если 
		false - возвращает настройки только текущего элемента структуры / справочника
		@return если объект с настройками контроля не найден - возвращает 0. Если найден - возвращает 
	    объект с настроками */		
	CaplInstance* GetObjectTypeParameters(CaplInstance *Item,bool &is_object_type_control,CaplEntity **stored_entity,bool recursive=true);
	
	void AddIfNotFound(aplExtent &base,aplExtent &added);

	int GetNextLevelIndex(CaplInstance* instLevel, bool bRecalc = false);
	bool SetIndexToUnindexedAssociations(CaplInstance* instLevel);
	bool GetObjectCode(CaplInstance* instAssociation, CString &code);
	bool GetObjectCode(CaplInstance* instSystem, CaplInstance* instObject, CString &code);

	/**
		Отображает форму, связанную с элементом структуры, в режиме создания объекта
		Если объект успешно создан, создает его связь с элементом структуры
		@param ClassifierElement элементом структуры, для которого создается объект
		@return true при удачном выполнении и false в случае ошибки */	
	bool CreateObjectWithForm(CaplInstance* ClassifierElement,aplExtent *created_objects=0,aplExtent *created_associations=0);

	virtual bool Attach(CaplAPI *api);
	virtual void Detach();

	CaplClassifierMgr();
	virtual ~CaplClassifierMgr();

	CaplEntity*	e_apl_classifier_system;//Справочник
	CaplAttr*	a_apl_classifier_system_id;
	CaplAttr*	a_apl_classifier_system_name;
	CaplAttr*	a_apl_classifier_system_descr;
	CaplAttr*	a_apl_classifier_system_parent;
	CaplAttr*	a_apl_classifier_system_childs;
	CaplAttr*	a_apl_classifier_system_template;
	CaplAttr*	a_apl_classifier_system_is_multi_object;
	CaplAttr*	a_apl_classifier_system_inner_label;

	CaplAttr*	a_apl_classifier_system_is_concept_level_control;
	CaplAttr*	a_apl_classifier_system_is_concept_last_level;
	CaplAttr*	a_apl_classifier_system_concept_maxlevel;
	CaplAttr*	a_apl_classifier_system_concept_minlevel;
	CaplAttr*	a_apl_classifier_system_can_store_object; 
	CaplAttr*	a_apl_classifier_system_is_object_level_control; 
	CaplAttr*	a_apl_classifier_system_is_object_last_level;
	CaplAttr*	a_apl_classifier_system_object_maxlevel;
	CaplAttr*	a_apl_classifier_system_object_minlevel;
	CaplAttr*	a_apl_classifier_system_is_type_control;
	CaplAttr*	a_apl_classifier_system_forms;
	CaplAttr*	a_apl_classifier_system_stored_entity;
	CaplAttr*	a_apl_classifier_system_list_characteristics;
	CaplAttr*	a_apl_classifier_system_esquisse;
	CaplAttr*	a_apl_classifier_system_esquisse_name;
	CaplAttr*	a_apl_classifier_system_view_format;


	CaplEntity*	e_apl_classifier_level;//Элемент структуры справочника
	CaplAttr*	a_apl_classifier_level_id;
	CaplAttr*	a_apl_classifier_level_code;
	CaplAttr*	a_apl_classifier_level_name;
	CaplAttr*	a_apl_classifier_level_name_eng;
	CaplAttr*	a_apl_classifier_level_descr;
	CaplAttr*	a_apl_classifier_level_parent;
	CaplAttr*	a_apl_classifier_level_childs;
	CaplAttr*	a_apl_classifier_level_system;
	CaplAttr*	a_apl_classifier_level_list_characteristics;
	CaplAttr*	a_apl_classifier_level_forms;
	CaplAttr*	a_apl_classifier_level_esquisse;
	CaplAttr*	a_apl_classifier_level_esquisse_name;
	CaplAttr*	a_apl_classifier_level_next_index;
	CaplAttr*	a_apl_classifier_level_construction;
	CaplAttr*	a_apl_classifier_level_wiring;
	CaplAttr*	a_apl_classifier_level_wiring_controls;
	CaplAttr*	a_apl_classifier_level_combustible_mat;
	CaplAttr*	a_apl_classifier_level_section_type;
	CaplAttr*	a_apl_classifier_level_req_characts;
	CaplAttr*	a_apl_classifier_level_related_pdf;
	CaplAttr*	a_apl_classifier_level_inner_label;
	CaplAttr*	a_apl_classifier_level_okpd_code;
	CaplAttr*	a_apl_classifier_level_is_system_level;
	
	CaplEntity*	e_apl_classifier_association;//ассоциация элемента структуры справочника с объектом БД
	CaplAttr*	a_apl_classifier_association_item;
	CaplAttr*	a_apl_classifier_association_classifier;
	CaplAttr*	a_apl_classifier_association_index;
	CaplAttr*	a_apl_classifier_association_id;
	CaplAttr*	a_apl_classifier_association_system;
	CaplAttr*	a_apl_classifier_association_pdf_count;
	CaplAttr*	a_apl_classifier_association_inner_label;

protected:

	// проверка и ругательство в случае использования в xml индексах
	bool ValidateClassifierElsXmlRefs( const aplExtent& exts );

protected:

	CaplMap m_list_filters;

private:

	static void FN_DeleteClassifierLevel(CaplAPI* api, CaplLoadData& loadData, DWORD dwData);
};

