#pragma once
#include "stdafx.h"
#include "Condition.h"

#ifdef APL_FAULT_MGR
	#define APL_CLASS_TYPE __declspec(dllexport)
#else
	#define APL_CLASS_TYPE __declspec(dllimport)
#endif

// Задание библиотек для линковки
#ifndef APL_FAULT_MGR
#ifdef _DEBUG
#ifdef UNICODE
#pragma comment (lib,"aplFaultManager_ud.lib")
#else
#pragma comment (lib,"aplFaultManagerD.lib")
#endif
#else
#ifdef UNICODE
#pragma comment (lib,"aplFaultManager_u.lib")
#else
#pragma comment (lib,"aplFaultManager.lib")
#endif
#endif
#endif

using namespace std;

#define TEST_DEDUCTION_CLASSIFIER_LVL			APL_T("Заключения об испытаниях")
#define CULPRIT_DEDUCTION_CLASSIFIER_LVL		APL_T("Заключения о виновнике")
#define REFUSAL_TYPE_CLASSIFIER_LVL				APL_T("Виды неисправностей")
#define REFUSAL_STAGE_CLASSIFIER_LVL			APL_T("Этапы обнаружения")
#define REFUSAL_CONDITIONS_CLASSIFIER_LVL		APL_T("Обстоятельства обнаружения")
#define REFUSAL_DOF_CLASSIFIER_LVL				APL_T("Характеры неисправностей")
#define REFUSAL_REASON_CLASSIFIER_LVL			APL_T("Причины неисправностей")
#define REFUSAL_METHOD_CLASSIFIER_LVL			APL_T("Способы устранения")
#define REFUSAL_CONSEQ_CLASSIFIER_LVL			APL_T("Последствия")
#define REFUSAL_MANIF_CLASSIFIER_LVL			APL_T("Внешние проявления неисправностей")

class CCondition;
class CaplXMLFile;
class CaplXMLNode;

class APL_CLASS_TYPE CaplFaultMgr
{
public:

	CaplFaultMgr();
	~CaplFaultMgr(void);

	// список условий для диалога поиска неисправностей
	CArray<CCondition*, CCondition*> m_caConditionTmpl;
	CArray<CConditionOperation*, CConditionOperation*> m_caOperationsTmpl;

protected:

	CaplAPI *m_api;
	CaplPreExploitationMgr *m_ExplMgr;

	// кол-во элементов для загрузки
	int m_nItemsPerOneLoad;	

	// сохраненные условные части SQL запроса
	CStringArray m_saSQLparts;

	// некоторые атрибуты являются ссылками на объекты
	CaplStrMap m_mapGuidDocument;

	// прогресс бар
	CStatusDlgThread *m_pStatus;

public:

	bool m_bReadOnly;

	// возвращаем рабочие объекты
	CaplAPI* GetAPI() { return m_api; };
	CaplPreExploitationMgr* GetExplMgr() { return m_ExplMgr; };

	// проверка работоспособности
	bool IsReadyForWork();

	// подключаем все необходимое для работы
	bool Attach(CaplAPI *api);

	bool LoadClassifiers(); // Читает из БД нужные классификаторы

	// загрузка всех атрибутов неисправности + загрузка атрибутов объектов, связанных с неисправностью 
	bool LoadRefusalInfo(CaplInstance *Refusal);
	bool LoadRefusalInfo(aplExtent &aeRefusal);

	// загрузка только GUID'ов для неисправностей
	bool LoadRefusalsGUID(aplExtent &aeItems);
	
	// загрузка характеристик и их атрибутов неисправности
	bool LoadRefusalCharacts(aplExtent &aeRefusal);
	
	// загрузка документов и их атрибутов 
	bool LoadRefusalDocuments(aplExtent &aeRefusal);
	
	// создать описание неисправности  ext_doc - массив документов, которые будут добавлены к неисправности
	// src_refusal - информация из которой берется как базовая
	CaplInstance* CreateRefusal(CaplInstance *ciParentRefusal, aplExtent &aeUpdatedRefusal, aplExtent *ext_doc=0, CaplInstance *src_refusal=0, CaplInstance *prd_inst=0);

	// отобразить карточку учета неисправности
	bool ShowRefusalProperty(CaplInstance *ciRefusal, aplExtent &aeUpdatedRefusal);


	bool UpdateRefusalInfoInWF(CaplInstance *ciRefusal,CaplInstance *old_planer); //только для Созвездия

	// экспорт/импорт XML
	bool ExportToXML(aplExtent &aeRefusal, CString path = _T(""), bool loadRefusalAttr = false, bool loadRefusalCharacts = false, bool loadRefusalDocs = false);
	bool ImportFromXML(CString path = _T(""));

	// собрать SQL запрос (поиска неисправностей) из частей
	// Если bUseOR == false - условия объесдиняюься через "AND", иначе "OR"
	CString BuildSQL(CStringArray &saSQLparts, bool bUseOR=false);

	// сформировать запрос поиска неисправностей на STEP_QL
	bool FindRefusalBySQLFilter(CString &sSQL, bool &b_add_to_last_found);

	// перевод в/обратно base64
	CString EncodeToBase64(unsigned char const* BYTEs_to_encode, unsigned int in_len);
	CString DecodeFromBase64(CString encoded_string);

	// создать уникальный GUID
	CString CreateGUID();

	// из пути оставляет только имя
	bool GetFileNameFromPath(CString &path);

	// обнулить время (часы, минуты, секунды) в дате
	CString NullTimeInDate(CString time);

	//Перенесено из ExplMgr
	/** Проверяет является ли переданная инстанс корневым изделием БД
		param PrdInst - проверяемая инстанс
	return <b>true</b>, если проверяемая инстанс - корневым изделием БД и <b>false</b> в противном случае*/
	bool IsPlaner(CaplInstance* PrdInst);

	/**	Возвращает массив родительских версий изделий
		param ext - массив. куда будут записаны указатели на Instance родительских элементов*/
	bool GetParentPdfs(aplExtent &ext);

	/** Получить отображаемое имя системы согласно установок отображения
		param System - указатель на Instance системы имя которой необходимо получить
		param name - <out>имя системы
		return <b>true</b> в случае успешного формирования имени и <b>false</b> в случае ошибки*/
	bool GetSystemName(CaplInstance* System, CString &name);

	bool GetPlanerName(CaplInstance *Planer, CString& name);
	bool GetPKIName(CaplInstance *pki, CString& name);

	/** Проверяет Item на вхождение в указанную систему
		param Item - проверяемый объект
		param System - система, в которой этот объект проверяется
		param bFromBase - делать запросы в БД (работает только для экземпляров)
		return true, если Item входит в указанную систему на любом уровне и false в противном случае*/
	bool IsChildItem(CaplInstance* Item, CaplInstance* Parent, bool bFromBase = true);


	

protected:

	/************************************************************************/
	/*                      ЭКСПОРТ                                         */
	/************************************************************************/

	// поиск гуида по объекту
	CString GetGuidFromMap(CaplInstance *ciDocument);

	// инициализация условий
	bool InitConditions();

	// очистка условий
	void ClearConditions();	

	// узнаем путь для сохранения
	CString AskForPath(BOOL open, CString sExtension, CString sFilter);

	// экспорт текстовых атрибутов неисправности
	bool XMLExportRefusalParams(CaplXMLNode *root, CaplInstance *ciRefusal);

	// создаем ссылки для атрибутов неисправности типа "Справочник"
	bool XMLExportFaultClassifierLvlsRef(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aeClassifierLvl);
	bool XMLExportFaultClassifierLvlRef(CaplInstance *ciRefusal, CaplXMLNode *root, CaplAttr *attr, CString name, aplExtent &aeClassifierLvl);

	// создаем узлы использованных справочников
	CaplXMLNode* XMLExportClassifierLvls(CaplXMLNode *root, aplExtent &aeClassifierLvl);
	CString XMLExportClassifierLvl(CaplXMLNode *root, CaplInstance *ciLvl);

	// создаем ссылки для атрибутов неисправности типа "Организация"
	bool XMLExportFaultOrganizationsRef(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aeOrganization);
	bool XMLExportFaultOrganizationRef(CaplInstance *ciRefusal, CaplXMLNode *root, CaplAttr *attr, CString name, aplExtent &aeOrganization);

	// создаем узлы использованных организаций
	CaplXMLNode* XMLExportOrganizations(CaplXMLNode *root, aplExtent &aeOrganization);
	CString XMLExportOrganization(CaplXMLNode *root, CaplInstance *ciOrg);

	// создаем ссылки для атрибутов неисправности типа "Партия"
	bool XMLExportFaultLotsRef(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aeLot);	
	bool XMLExportFaultLotRef(CaplInstance *ciRefusal, CaplXMLNode *root, CaplAttr *attr, CString name, aplExtent &aeLot);

	// создаем узлы использованных партий
	CaplXMLNode* XMLExportLots(CaplXMLNode *root, aplExtent &aeLot);
	CString XMLExportLot(CaplXMLNode *root, CaplInstance *ciLot);

	// создаем узлы значения хар-ки + ссылки для объекта типа "Характеристика"
	bool XMLExportCharactsValues(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aeCharact, aplExtent &aeOrganization);
	bool XMLExportCharactValue(CaplInstance *ciCharVal, CaplXMLNode *root, aplExtent &aeCharact, aplExtent &aeOrganization);

	// создаем узлы использованных характеристик
	CaplXMLNode* XMLExportCharacts(CaplXMLNode *root, aplExtent &aeCharact);
	CString XMLExportCharact(CaplXMLNode *root, CaplInstance *ciCharact);

	// создаем узлы документы + ссылки для объекта типа "Тип документа"
	bool XMLExportDocuments(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aeDocType);
	bool XMLExportDocument(CaplXMLNode *root, CaplInstance *ciDocument, aplExtent &aeDocType);
	bool XMLExportDocumentTypeRef(CaplXMLNode *root, CaplInstance *ciDocument, aplExtent &aeDocType);

	// создаем узлы использованных типов документов
	CaplXMLNode* XMLExportDocTypes(CaplXMLNode *root, aplExtent &aeDocType);
	CString XMLExportDocType(CaplXMLNode *root, CaplInstance *ciDocType);

	// создаем ссылки для атрибутов неисправности типа "Экземпляр изделия"
	bool XMLExportFaultPrdInstsRef(CaplXMLNode *root, CaplInstance *ciRefusal, aplExtent &aePrdInst);
	bool XMLExportFaultPrdInstRef(CaplInstance *ciRefusal, CaplXMLNode *root, CaplAttr *attr, CString name, aplExtent &aePrdInst);

	// создаем узлы использованных экземпляров изделия
	CaplXMLNode* XMLExportPrdInsts(CaplXMLNode *root, aplExtent &aePrdInst, aplExtent &aePdf);
	CString XMLExportPrdInst(CaplXMLNode *root, CaplInstance *ciPrdInst, aplExtent &aePdf);

	// создаем узлы использованных изделий (изделие + обозначение версии)
	CaplXMLNode* XMLExportPrds(CaplXMLNode *root, aplExtent &aePdf);
	CString XMLExportPrd(CaplXMLNode *root, CaplInstance *ciPdf);

	// экспорт всех атрибутов типа "Файл"
	bool XMLExportFiles(CaplXMLNode *root, CaplInstance *ciRefusal);

	// экспорт узла типа "Файл"
	bool XMLExportFile(CaplInstance *ciFile, CaplXMLNode *root);		

	// экспорт типа узла типа "Активная версия"
	bool XMLExportActiveDocVersion(CaplXMLNode *root, CaplInstance *ciDocument);

	// увеличить значение второостепенного прогресс бара
	bool SlaveUpdate(CStatusDlgThread *pStatus, CString text);

	// предупреждаем о слишком большом количестве отказов
	bool ExportWarningToManyRefusal(int size);

	// создаем xml узел
	CaplXMLNode* CreateNode(CaplXMLNode *root, CString name);

	// проставление ссылок
	void SetReference(CaplMap &map, CaplInstance *ciItem, CString sGuid);

	/************************************************************************/
	/*                      ИМПОРТ                                          */
	/************************************************************************/

	// загрузка только нужных данных
	bool LoadImportantPdfInfo(aplExtent &aeItems);
	bool LoadImportantPrdInstInfo(aplExtent &aeItems);
	bool LoadIPrdInstPdfAndPrdInfo(aplExtent &aeItems);

	// получить первый дочерний элемент по имени
	CaplXMLNode* GetChildNodeBN(CaplXMLNode *node, CString name);

	// загружать ли xml в базу
	bool ImportWarningToManyRefusal(CaplXMLFile *file, CString path);

	// узнать количество неисправностей в xml
	int XMLImportGetCount(CaplXMLFile *file, CString path);

	// гуиды всех неисправностей в базе
	bool GetGUIDfromBase(map<CString, long> &baseGUIDs);

	// импорт текстовых атрибутов
	bool XMLImportParams(CaplInstance *ciFault, CaplXMLNode *node);

	// находим соответствие справочников (xml - база_данных) по обозначению 
	bool XMLGetClassifierLevels(CaplXMLNode *node, map<CString, long> &mapLvl);

	// находим соответствие организаций (xml - база_данных) по обозначению 
	bool XMLGetOrganiztions(CaplXMLNode *node, map<CString, long> &mapOrg);

	// находим соответствие партий (xml - база_данных) по обозначению 
	bool XMLGetLots(CaplXMLNode *node, map<CString, long> &mapLot);
	
	// находим соответствие типов документов (xml - база_данных) по наименованию 
	bool XMLGetDocumentTypes(CaplXMLNode *node, map<CString, long> &mapDT);

	// находим соответствие изделий (xml - база_данных) по обозначению 
	bool XMLGetProducts( CaplXMLNode *node, map<pair<CString, CString>, long> &mapProducts );
	
	// находим соответствие экземпляров изделий (xml - база_данных) по обозначению и серийному номеру
	bool XMLGetProductInstances(CaplXMLNode *node, map<CString, long> &mapInstances, map<pair<CString, CString>, long> &mapProducts);

	// находим соответствие характеристик (xml - база_данных) по обозначению
	bool XMLGetCharactsAndTypes(CaplXMLNode *node, map<CString, long> &mapCharacts, map<CString, long> &mapCharactTypes);

	// формируем мап с типами харакетеристик для удобства в дальнейшем
	bool GetCharactTypes(map<CString, long> &mapCharactTypes);

	// импортируем изображения
	bool XMLImportPictures(CaplXMLNode *nodeFault, CaplInstance *ciRefusal);

	// импорт справочников
	bool XMLImprotClassifierLevels(CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapClassifierLevels);

	// импорт организаций
	bool XMLImprotOrganizations(CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapOrg);

	// импорт партий
	bool XMLImprotLots( CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapLots );
	
	// создать временный файл по содержанию
	CString CreateTemproryFileByContent(CString sName, CString sContent);

	// импортируем значения характеристик
	bool XMLImportCharValues(CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapCharacts, map<CString, long> &mapCharactTypes, map<CString, long> &mapOrg);

	// импортируем экземпляры изделий
	bool XMLImportProductInstances(CaplXMLNode *nodeFault, CaplInstance *ciRefusal,  map<CString, long> &mapInstances);

	// импортируем документы
	bool XMLImprotDocuments(CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapDocTypes, map<CString, long> &mapDocument);

	// создать файл на диске (тело файла берется из узла типа "FILE"
	CString CreateTemproryFileFromNode(CaplXMLNode *nodeFile);

	// импорт текстовых артибутов
	bool XMLImprotStringAttrs(CaplXMLNode *nodeFault, CaplInstance *ciRefusal, map<CString, long> &mapDocument);

	// добавляем новые неисправности в карту гуидов существующих
	bool AppendGuidMap(map<CString, long> &baseGuids, aplExtent &aeNewFaults);

	// проставляем родительско-дочерние связи
	bool MakeTreeStruct(map<CString, long> &baseGuids, map<CString, long> &childGuids);
	
	// функции выбора 
	static CaplInstance* SelectClassifier(CaplAPI *api, CaplPreExploitationMgr *mgr, CaplInstance *ciRoot, CString sTitle);
	static CaplInstance* SelectOrg(CaplAPI *api, CaplPreExploitationMgr *mgr,CaplInstance *ciRoot, CString sTitle);
	static CaplInstance*SelectMainPdf( CaplAPI *api, CaplPreExploitationMgr *mgr, CaplInstance *ciRoot, CString sTitle );
	static CaplInstance* SelectSystem( CaplAPI *api, CaplPreExploitationMgr *mgr, CaplInstance *ciRoot, CString sTitle );
	static CaplInstance* SelectItem( CaplAPI *api, CaplPreExploitationMgr *mgr, CaplInstance *ciRoot, CString sTitle );
};
