#ifndef __HCM4A_CalcFs4A_ctrlHcmPack_h_
#define __HCM4A_CalcFs4A_ctrlHcmPack_h_

#include "dtPack.h"
#include "dtCtrl.h"
#include "ctrlReport.h"
#include "dbMask.h"

// open hcm pack dlg
struct OpenHcmDlg : public WithFrmOpenHcm<TopWindow> {
	void InitCtrl(){
		ed_FileTest.SetFont(Single<ItemGrid>().headFont);
		ed_FileRef.SetFont(Single<ItemGrid>().headFont);
	}
	void ToCtrl(){
		ed_FileTest.SetData(appCFG.cfgCalcRec.fPackTest);
		ed_FileRef.SetData(appCFG.cfgCalcRec.fPackRef);
	}
	void FromCtrl(){
		appCFG.cfgCalcRec.fPackTest = ed_FileTest.GetData();
		appCFG.cfgCalcRec.fPackRef =  ed_FileRef.GetData();
	}
	String SelFile(const String& dir, bool isTest){
		FileSel fs;
		fs.ReadOnlyOption(true);
		fs.MkDirOption(false);
		if(DirectoryExists(dir))
			fs.ActiveDir(dir);
		else{
			String tmpDir = isTest ? appCFG.cfgPathRec.GetCalcTestDir() : appCFG.cfgPathRec.GetCalcRefDir();
			if(DirectoryExists(tmpDir))
				fs.ActiveDir(tmpDir);
			else
				fs.ActiveDir(GetExeFolder());
		}
		fs.Types("Text files\t*.txt\nExcel files\t*.xlsx\nJson files\t*.json");
		if(fs.ExecuteOpen()){
			if(isTest)
				appCFG.cfgPathRec.SetCalcTestDir(GetFileFolder(fs.Get()));
			else
				appCFG.cfgPathRec.SetCalcRefDir(GetFileFolder(fs.Get()));
			return fs;
		}
		else
			return "";
	}
	void SetPackTest(){
		appCFG.cfgCalcRec.fPackTest = SelFile(testDir, true);
		testDir = GetFileFolder(appCFG.cfgCalcRec.fPackTest);
		ed_FileTest.SetData(appCFG.cfgCalcRec.fPackTest);
	}
	void SetPackRef(){
		appCFG.cfgCalcRec.fPackRef = SelFile(refDir, false);
		refDir = GetFileFolder(appCFG.cfgCalcRec.fPackRef);
		ed_FileRef.SetData(appCFG.cfgCalcRec.fPackRef);
	}
	OpenHcmDlg(AppCFG& appCFG):appCFG(appCFG){
		CtrlLayoutOKCancel(*this, t_("Choose an HCM data file"));
		//--------------------------------------------------------------------------------------
		InitCtrl();
		ToCtrl();
		refDir = GetFileFolder(appCFG.cfgCalcRec.fPackRef);
		testDir = GetFileFolder(appCFG.cfgCalcRec.fPackTest);
		//--------------------------------------------------------------------------------------
		btn_SelFileTest.SetImage(Images::SEL());
		btn_SelFileRef.SetImage(Images::SEL());
		btn_SelFileTest.WhenAction = [=] {SetPackTest();};
		btn_SelFileRef.WhenAction = [=] {SetPackRef();};
	}
protected:
	AppCFG& appCFG;
	String testDir;
	String refDir;
};
//!---------------------------------------------------------------------------------------


class PackHeadViewDlg: public WithHeadViewDlg<TopWindow> {
public:
	typedef PackHeadViewDlg CLASSNAME;
	void ToCtrl(const HcmHeader& header);
	void Clear();
	void Serialize(Stream& s);
	void BeforeFrmShow(const String& nameCtrl, VectorMap<String, String>& sMap);
	void BeforeFrmClose(const String& nameCtrl, VectorMap<String, String>& sMap);
	PackHeadViewDlg();
protected:
	LayHeadV layViewHeadV = {false, CveHeaderList().GetList()};
};
PackHeadViewDlg::PackHeadViewDlg(){
	CtrlLayoutOK(*this, t_("Head View Dlg-"));
	Sizeable().Zoomable();
	parentCtrl.Add(layViewHeadV.SizePos());
}
void PackHeadViewDlg::Serialize(Stream& s){
	layViewHeadV.Serialize(s);
}
void PackHeadViewDlg::ToCtrl(const HcmHeader& header){
	layViewHeadV.ToCtrl(header);
}
void PackHeadViewDlg::Clear(){
	layViewHeadV.Clear();
}
void PackHeadViewDlg::BeforeFrmShow(const String& nameCtrl, VectorMap<String, String>& sMap){
	int idx = sMap.Find(nameCtrl);
	if(idx != -1) LoadFromString(*this, sMap[idx]);
}
void PackHeadViewDlg::BeforeFrmClose(const String& nameCtrl, VectorMap<String, String>& sMap){
	int idx = sMap.Find(nameCtrl);
	if(idx == -1)
		sMap.Add(nameCtrl, StoreAsString(*this));
	else
		sMap[idx] = StoreAsString(*this);
}
//!---------------------------------------------------------------------------------------

class EntryViewDlg : public WithEntryViewDlg<TopWindow> {
public:
	typedef EntryViewDlg CLASSNAME;
	void ToCtrl(const HcmIN& hcmIN);
	void Clear();
	void Serialize(Stream& s);
	void BeforeFrmShow(const String& nameCtrl, VectorMap<String, String>& sMap);
	void BeforeFrmClose(const String& nameCtrl, VectorMap<String, String>& sMap);
	EntryViewDlg();
protected:
	LayEntryGeneral layGeneral = false;
	LayEntryEquip layEquip = false;
	LayEntryAnt layAnt = false;
	VectorMap<String, String> seriaMap;
};
EntryViewDlg::EntryViewDlg(){
	CtrlLayoutOK(*this, t_("Entry View Dlg"));
	Sizeable().Zoomable();
	tab.Add(layGeneral.SizePos(), t_("\1[ [ [3*!Arial! General]]]"));
	tab.Add(layEquip.SizePos(), t_("\1[ [ [3*!Arial! Equipment]]]"));
	tab.Add(layAnt.SizePos(), t_("\1[ [ [3*!Arial! Antenna]]]"));
}
void EntryViewDlg::Serialize(Stream& s){
	// tab.Serialize(s);
	layGeneral.Serialize(s);
	layEquip.Serialize(s);
	layAnt.Serialize(s);
	SerializePlacement(s);
	seriaMap.Serialize(s);
}
void EntryViewDlg::Clear(){
	layGeneral.Clear();
	layEquip.Clear();
	layAnt.Clear();
}
void EntryViewDlg::ToCtrl(const HcmIN& hcmIN){
	layGeneral.ToCtrl(hcmIN);
	layEquip.ToCtrl(hcmIN);
	layAnt.ToCtrl(hcmIN);
}
void EntryViewDlg::BeforeFrmShow(const String& nameCtrl, VectorMap<String, String>& sMap){
	int idx = sMap.Find(nameCtrl);
	if(idx != -1) LoadFromString(*this, sMap[idx]);
}
void EntryViewDlg::BeforeFrmClose(const String& nameCtrl, VectorMap<String, String>& sMap){
	int idx = sMap.Find(nameCtrl);
	if(idx == -1)
		sMap.Add(nameCtrl, StoreAsString(*this));
	else
		sMap[idx] = StoreAsString(*this);
}
//!---------------------------------------------------------------------------------------------

class EntryEditDlg : public WithEntryEditDlg<TopWindow> {
public:
	typedef EntryEditDlg CLASSNAME;
	void ToCtrl(const HcmIN& hcmIN);
	void FromCtrl(HcmIN& hcmIN);
	bool IsModified()const{return isModified;}
	void Clear();
	void Serialize(Stream& s);
	void BeforeFrmShow(const String& nameCtrl, VectorMap<String, String>& sMap);
	void BeforeFrmClose(const String& nameCtrl, VectorMap<String, String>& sMap);
	EntryEditDlg(bool isEditable);
protected:
	bool isEditable;
	int mask_node_id;

	LayEntryGeneral layGeneral = isEditable;
	LayEntryEquip layEquip = isEditable;
	LayEntryAnt layAnt = isEditable;
	VectorMap<String, String> seriaMap;
	bool isModified = false;
	void ClearModify();
	void CheckModify();
	void FillFromMask();
};
EntryEditDlg::EntryEditDlg(bool isEditable):isEditable(isEditable){
	mask_node_id = 0;
	CtrlLayoutOKCancel(*this, t_("Entry Edit Dlg"));
	Sizeable().Zoomable();
	tab.Add(layGeneral.SizePos(), t_("\1[ [ [3*!Arial! General]]]"));
	tab.Add(layEquip.SizePos(), t_("\1[ [ [3*!Arial! Equipment]]]"));
	tab.Add(layAnt.SizePos(), t_("\1[ [ [3*!Arial! Antenna]]]"));
	layEquip.layFrecAtten.btn_mask << [=] { FillFromMask(); };
}
void EntryEditDlg::Serialize(Stream& s){
	layGeneral.Serialize(s);
	layEquip.Serialize(s);
	layAnt.Serialize(s);
	SerializePlacement(s);
	seriaMap.Serialize(s);
}
void EntryEditDlg::Clear(){
	layGeneral.Clear();
	layEquip.Clear();
	layAnt.Clear();
}
void EntryEditDlg::ToCtrl(const HcmIN& hcmIN){
	layGeneral.ToCtrl(hcmIN);
	layEquip.ToCtrl(hcmIN);
	layAnt.ToCtrl(hcmIN);
}
void EntryEditDlg::FromCtrl(HcmIN& hcmIN){
	if(!isEditable) return;
	layGeneral.FromCtrl(hcmIN);
	layEquip.FromCtrl(hcmIN);
	layAnt.FromCtrl(hcmIN);
	CheckModify();
}
void EntryEditDlg::FillFromMask(){
	MaskDlg dlg(layEquip.layFrecAtten.Get(), mask_node_id);
	if(dlg.Run() == IDOK){
		layEquip.layFrecAtten.ToCtrl(dlg.Get());
		isModified = true;
		mask_node_id = dlg.GetSaveNodeNum();
		// refresh grid rows
		for(int i = 0; i < layEquip.layFrecAtten.grid.GetRowCount(); i++){
			layEquip.layFrecAtten.grid.SetCursor(i);
		}
	}
}
void EntryEditDlg::BeforeFrmShow(const String& nameCtrl, VectorMap<String, String>& sMap){
	int idx = sMap.Find(nameCtrl);
	if(idx != -1) LoadFromString(*this, sMap[idx]);
}
void EntryEditDlg::BeforeFrmClose(const String& nameCtrl, VectorMap<String, String>& sMap){
	int idx = sMap.Find(nameCtrl);
	if(idx == -1)
		sMap.Add(nameCtrl, StoreAsString(*this));
	else
		sMap[idx] = StoreAsString(*this);
}
void EntryEditDlg::ClearModify(){
	isModified = false;
}
void EntryEditDlg::CheckModify(){
	if(!isEditable){
		isModified = false;
		return;
	}
	isModified = isModified || layGeneral.IsModified() || layEquip.IsModified() || layAnt.IsModified();
}
//!---------------------------------------------------------------------------------------------


class CoEntryEditDlg : public WithEntryEditDlg<TopWindow> {
public:
	typedef CoEntryEditDlg CLASSNAME;
	void ToCtrl(const HcmIN& hcmIN);
	void FromCtrl(HcmIN& hcmIN);
	bool IsModified()const{return isModified;}
	void Clear();
	void Serialize(Stream& s);
	void BeforeFrmShow(const String& nameCtrl, VectorMap<String, String>& sMap);
	void BeforeFrmClose(const String& nameCtrl, VectorMap<String, String>& sMap);
	CoEntryEditDlg(bool isEditable);
protected:
	bool isEditable;
	LayCoEntry layGeneral = isEditable;
	VectorMap<String, String> seriaMap;
	bool isModified = false;
	void ClearModify();
	void CheckModify();
};
CoEntryEditDlg::CoEntryEditDlg(bool isEditable):isEditable(isEditable){
	CtrlLayoutOKCancel(*this, t_("Entry Edit Dlg"));
	Sizeable().Zoomable();
	tab.Add(layGeneral.SizePos(), t_("\1[ [ [3*!Arial! General]]]"));
}
void CoEntryEditDlg::Serialize(Stream& s){
	layGeneral.Serialize(s);
	SerializePlacement(s);
	seriaMap.Serialize(s);
}
void CoEntryEditDlg::Clear(){
	layGeneral.Clear();
}
void CoEntryEditDlg::ToCtrl(const HcmIN& hcmIN){
	layGeneral.ToCtrl(hcmIN);
}
void CoEntryEditDlg::FromCtrl(HcmIN& hcmIN){
	if(!isEditable) return;
	layGeneral.FromCtrl(hcmIN);
	CheckModify();
}
void CoEntryEditDlg::BeforeFrmShow(const String& nameCtrl, VectorMap<String, String>& sMap){
	int idx = sMap.Find(nameCtrl);
	if(idx != -1) LoadFromString(*this, sMap[idx]);
}
void CoEntryEditDlg::BeforeFrmClose(const String& nameCtrl, VectorMap<String, String>& sMap){
	int idx = sMap.Find(nameCtrl);
	if(idx == -1)
		sMap.Add(nameCtrl, StoreAsString(*this));
	else
		sMap[idx] = StoreAsString(*this);
}
void CoEntryEditDlg::ClearModify(){
	isModified = false;
}
void CoEntryEditDlg::CheckModify(){
	if(!isEditable){
		isModified = false;
		return;
	}
	isModified = isModified || layGeneral.IsModified();
}
//!---------------------------------------------------------------------------------------------


/// LayHcmPackView = LayHcmHeadH + LayHcmEntrisH
class LayHcmPackView : public WithLayHcmPackView<ParentCtrl> {
public:
	typedef LayHcmPackView CLASSNAME;
	LayViewHeadH layHead;
	LayViewEntrisH layEntris;
	TabCtrl tab;
	WithLayGridCaption<ParentCtrl> layCaption;
	FrameTop<WithLayGridCaption<ParentCtrl>> frameCaption;
	Label  lbCaption;

	void GrEntrisPopMenu(Bar& bar);
	void GrHeadPopMenu(Bar& bar);

	void ToCtrl();
	void ViewEntry();
	void ViewHead();
	void ViewReport();

	const HcmPack& GetHcmPack()const{return hcmPack;};
	bool CheckHcmPack(String& slog);

	void OpenHcmPack();
	bool OpenHcmPack(const String& fileName);

	void CloseHcmPack();

	void SetCaption(const String& str){lbCaption.SetText(str);};
	void SetTabCaption(const String& str);

	void Clear();
	void Serialize(Stream& s);
	void BeforeFrmShow(const String& nameCtrl, VectorMap<String, String>& sMap);
	void BeforeFrmClose(const String& nameCtrl, VectorMap<String, String>& sMap);
	LayHcmPackView();
protected:
	bool isOpen;
	HcmPack hcmPack;
	VectorMap<String, String> seriaMap;
	void Setup();
	void OnChangeEntry();
};
LayHcmPackView::LayHcmPackView(){
	CtrlLayout(*this);
	Add(tab.SizePos());
	tab.Add(layHead.SizePos(), t_(Format("\1[ [ [3*!Arial! %s Header:]]]", ""))) ;
	tab.Add(layEntris.SizePos(), t_(Format("\1[ [ [3*!Arial! %s Data:]]]", ""))) ;
	lbCaption.SetFrame(BlackFrame());
	layCaption.Add(lbCaption.SizePos());
	frameCaption.Add(layCaption.SizePos());
	frameCaption.Height(Single<ItemGrid>().headFont.GetHeight()*2); // !!! Высота фрейма заголовка = высота шрифта + 3 !!!
	tab.AddFrame(frameCaption);
	lbCaption.SetFont(Single<ItemGrid>().headFont);
	lbCaption.SetText("");
	isOpen = false;
	Setup();
}
void LayHcmPackView::Setup(){
	layEntris.layEntris.grid.WhenChangeRow = [=] { OnChangeEntry(); };
	layEntris.layEntris.grid.WhenMenuBar = THISBACK(GrEntrisPopMenu);
	layEntris.layEntris.grid.WhenLeftDouble = THISBACK(ViewEntry);
	layHead.layHead.grid.WhenMenuBar = THISBACK(GrHeadPopMenu);
	layHead.layHead.grid.WhenLeftDouble = THISBACK(ViewHead);
}
void LayHcmPackView::SetTabCaption(const String& str){
	tab.GetItem(0).Text(t_(Format("\1[ [ [3*!Arial! %s Header:]]]", str)));
	tab.GetItem(1).Text(t_(Format("\1[ [ [3*!Arial! %s Data:]]]", str)));
}
void LayHcmPackView::Serialize(Stream& s){
	layEntris.Serialize(s);
	layHead.Serialize(s);
	seriaMap.Serialize(s);
}
void LayHcmPackView::BeforeFrmShow(const String& nameCtrl, VectorMap<String, String>& sMap){
	int idx = sMap.Find(nameCtrl);
	if(idx != -1) LoadFromString(*this, sMap[idx]);
}
void LayHcmPackView::BeforeFrmClose(const String& nameCtrl, VectorMap<String, String>& sMap){
	int idx = sMap.Find(nameCtrl);
	if(idx == -1)
		sMap.Add(nameCtrl, StoreAsString(*this));
	else
		sMap[idx] = StoreAsString(*this);
}
void LayHcmPackView::GrEntrisPopMenu(Bar& bar){
	bar.Add(t_("View .."), Images::VIEW_DATA(), THISBACK(ViewEntry));
	bar.Separator();
	bar.Add(t_("View as Txt .."), Images::VIEW_TXT(), THISBACK(ViewReport));
}
void LayHcmPackView::GrHeadPopMenu(Bar& bar){
	bar.Add(t_("View .."), Images::VIEW_DATA(), THISBACK(ViewHead));
}
void LayHcmPackView::Clear(){
	layHead.Clear();
	layEntris.Clear();
}
void LayHcmPackView::ToCtrl(){
	layHead.ToCtrl(hcmPack.GetHeader());
	layEntris.ToCtrl(hcmPack);
	layEntris.SetFirstRec();
}
void LayHcmPackView::OnChangeEntry(){
	int idx =  layEntris.GetCurSelID();
}
bool LayHcmPackView::OpenHcmPack(const String& fileName){
	CloseHcmPack();
	String ext = GetFileExt(fileName);
	isOpen = false;
	if(ext == ".json"){
		isOpen = hcmPack.FromJson(fileName);
	}else if(ext == ".xlsx"){
		isOpen = hcmPack.FromXLS(fileName);
	}else if(ext == ".txt"){
		isOpen = hcmPack.FromCSV(fileName);
	}
	if(isOpen){
		SetCaption(t_(Format(" hcm file:  %s", fileName)));
		ToCtrl();
	}
	return isOpen;
}
void LayHcmPackView::OpenHcmPack(){
	FileSel fs;
	fs.ReadOnlyOption(true);
	fs.MkDirOption(false);
	String wDir = Single<AppCFG>().cfgPathRec.GetCalcTestDir();
	if(wDir.IsEmpty() || !DirectoryExists(wDir))
		wDir = GetExeFolder();
	fs.ActiveDir(wDir);
	fs.Types("Text files\t*.txt\nExcel files\t*.xlsx\nJson files\t*.json");
	String fileName = "";
	if(fs.ExecuteOpen()){
		fileName = fs;
		if(!fileName.IsEmpty()){
			CloseHcmPack();
			Single<AppCFG>().cfgPathRec.SetCalcTestDir(GetFileFolder(fileName));
			isOpen = false;
			if(fs.GetActiveType()==0){
				isOpen = hcmPack.FromCSV(fileName);
			}
			if(fs.GetActiveType()==1){
				isOpen = hcmPack.FromXLS(fileName);
			}
			if(fs.GetActiveType()==2){
				isOpen = hcmPack.FromJson(fileName);
			}
			if(!isOpen){
				Clear();
				Exclamation(DeQtf(Format("Error opening file: \"%s\"\nThe selected file is not an hcm data file", fileName)));
				return;
			}
			SetCaption(t_(Format(" hcm file:  %s", fileName)));
			ToCtrl();
		}
	}
}
bool LayHcmPackView::CheckHcmPack(String& slog){
	slog << "Header" << ":\n";
	hcmPack.GetHeader().Check(slog);
	for(auto v: hcmPack.GetMap()){
		slog << Format("%s \"%s\":\n", HcmEntityToStr(v.GetEntity()), v.GetField("4A").GetStr());
		v.Check(slog);
	}
	return true;
}
void LayHcmPackView::CloseHcmPack(){
	if(hcmPack.IsEmpty()) return;
    hcmPack.Clear();
    hcmPack.GetHeader().Clear();
	SetCaption("");
    ToCtrl();
	OnChangeEntry();
}
void LayHcmPackView::ViewEntry(){
	EntryViewDlg dlg;
	dlg.BeforeFrmShow("ViewEntry", seriaMap);
	int idx =  layEntris.GetCurSelID();
	if(idx != -1){
		dlg.ToCtrl(hcmPack.GetHcmIN(idx));
		dlg.Execute();
	}
	dlg.BeforeFrmClose("ViewEntry", seriaMap);
}
void LayHcmPackView::ViewHead(){
	PackHeadViewDlg dlg;
	dlg.BeforeFrmShow("ViewHeader", seriaMap);
	DUMP(hcmPack.GetHeader());
	dlg.ToCtrl(hcmPack.GetHeader());
	dlg.Execute();
	dlg.BeforeFrmClose("ViewHeader", seriaMap);
}
void LayHcmPackView::ViewReport(){
	int idx =  layEntris.GetCurSelID();
	if(idx != -1){
		FormReport formReport;
		formReport.de_Report.SetData(hcmPack.GetHcmIN(idx).ToString());
		formReport.Run();
	}
}
//!---------------------------------------------------------------------------------------------

class LayHcmPackEdit : public WithLayHcmPackEdit<ParentCtrl> {
public:
	typedef LayHcmPackEdit CLASSNAME;

	LayHeadV layHeadEd = {true, CveHeaderList().GetList()};
	LayViewEntrisH layEntris;

	WithLayGridCaption<ParentCtrl> layCaption;
	FrameTop<WithLayGridCaption<ParentCtrl>> frameCaption;
	Label  lbCaption;
	Splitter spl;

	void GrEntrisPopMenu(Bar& bar);

	void ToCtrl();
	void ToCtrl(HcmPack& hcmPack);
	
	void EditEntry();
	void AddEntry();
	void CloneEntry();
	void DelEntry();

	const HcmPack& GetHcmPack()const{return hcmPack;};
	bool CheckHcmPack(String& slog);

	void OpenHcmPack();
	bool OpenHcmPack(const String& fileName);

	void CloseHcmPack();
	void SaveHcmPack();
	void SaveHcmPackAs();
	void NewHcmPack();

	void SetCaption(const String& str){lbCaption.SetText(str);};

	bool IsModified()const{return isModified;}
	void Clear();
	void Serialize(Stream& s);
	LayHcmPackEdit();
protected:
	bool isOpen;
	bool isModified;
	HcmPack hcmPack;
	VectorMap<String, String> seriaMap;
	void Setup();
};
LayHcmPackEdit::LayHcmPackEdit(){
	CtrlLayout(*this);
	Add(spl.Vert(layHeadEd.SizePos(), layEntris.SizePos()));
	lbCaption.SetFrame(BlackFrame());
	layCaption.Add(lbCaption.SizePos());
	frameCaption.Add(layCaption.SizePos());
	frameCaption.Height(Single<ItemGrid>().headFont.GetHeight()*2); // !!! Высота фрейма заголовка = высота шрифта + 3 !!!
	AddFrame(frameCaption);
	lbCaption.SetFont(Single<ItemGrid>().headFont);
	lbCaption.SetText("");
	isOpen = false;
	Setup();
}
void LayHcmPackEdit::Setup(){
	layEntris.layEntris.grid.WhenMenuBar = THISBACK(GrEntrisPopMenu);
	layEntris.layEntris.grid.WhenLeftDouble = [=] { EditEntry(); };
}
void LayHcmPackEdit::Serialize(Stream& s){
	spl.Serialize(s);
	layHeadEd.Serialize(s);
	layEntris.Serialize(s);
	seriaMap.Serialize(s);
}
void LayHcmPackEdit::GrEntrisPopMenu(Bar& bar){
	bar.Add(t_("Edit .."), Images::EDIT(),  THISBACK(EditEntry));
	bar.Add(t_("Add .."),  Images::ADD(),   THISBACK(AddEntry));
	bar.Add(t_("Copy .."), Images::CLONE(), THISBACK(CloneEntry));
	bar.Separator();
	bar.Add(t_("Del .."), Images::DEL(), THISBACK(DelEntry));
}
void LayHcmPackEdit::Clear(){
	layHeadEd.Clear();
	layEntris.Clear();
}
void LayHcmPackEdit::ToCtrl(){
	LOG("ToCtrl()");
	layHeadEd.ToCtrl(hcmPack.GetHeader());
	layEntris.ToCtrl(hcmPack);
	layEntris.SetFirstRec();
}
void LayHcmPackEdit::ToCtrl(HcmPack& hcmPack){
	LOG("ToCtrl(HcmPack)");
	layHeadEd.ToCtrl(hcmPack.GetHeader());
	layEntris.ToCtrl(hcmPack);
	layEntris.SetFirstRec();
}
bool LayHcmPackEdit::OpenHcmPack(const String& fileName){
	CloseHcmPack();
	String ext = GetFileExt(fileName);
	isOpen = false;
	if(ext == ".json"){
		isOpen = hcmPack.FromJson(fileName);
	}else if(ext == ".xlsx"){
		isOpen = hcmPack.FromXLS(fileName);
	}else if(ext == ".txt"){
		isOpen = hcmPack.FromCSV(fileName);
	}
	if(isOpen){
		ToCtrl();
	}
	return isOpen;
}
void LayHcmPackEdit::OpenHcmPack(){
	FileSel fs;
	fs.ReadOnlyOption(true);
	fs.MkDirOption(false);
	String wDir = Single<AppCFG>().cfgPathRec.GetEdWorkDir();
	if(wDir.IsEmpty() || !DirectoryExists(wDir))
		wDir = GetExeFolder();
	fs.ActiveDir(wDir);
	fs.Types("Text files\t*.txt\nExcel files\t*.xlsx\nJson files\t*.json");
	String fileName = "";
	if(fs.ExecuteOpen()){
		fileName = fs;
		if(!fileName.IsEmpty()){
			CloseHcmPack();
			Single<AppCFG>().cfgPathRec.SetEdWorkDir(GetFileFolder(fileName));
			isOpen = false;
			if(fs.GetActiveType()==0){
				isOpen = hcmPack.FromCSV(fileName);
			}
			if(fs.GetActiveType()==1){
				isOpen = hcmPack.FromXLS(fileName);
			}
			if(fs.GetActiveType()==2){
				isOpen = hcmPack.FromJson(fileName);
			}
			if(!isOpen){
				Clear();
				Exclamation(DeQtf(Format("Error opening file: \"%s\"\nThe selected file is not an hcm data file", fileName)));
				return;
			}
			if(isOpen){
				ToCtrl();
			}
		}
	}
}
void LayHcmPackEdit::SaveHcmPack(){
	if(hcmPack.IsEmpty()) return;
	if(hcmPack.GetPackFile().IsEmpty())
		SaveHcmPackAs();
	else{
		layHeadEd.FromCtrl(hcmPack.GetHeader());
		switch(hcmPack.GetFormat()){
			case HcmPackFormat::TXT:
				isModified = !hcmPack.ToCSV();
				break;
			case HcmPackFormat::JSON:
				isModified = !hcmPack.ToJson();
				break;
			case HcmPackFormat::XLS:
				isModified = !hcmPack.ToXLS();
				break;
		}
	}
}
void LayHcmPackEdit::SaveHcmPackAs(){
	if(hcmPack.IsEmpty()) return;
	layHeadEd.FromCtrl(hcmPack.GetHeader());
	FileSel fs;
	fs.ReadOnlyOption(true);
	fs.MkDirOption(false);
	fs.ActiveDir(GetExeFolder());
	fs.EditFileName(true);
	fs.Set(GetFileTitle(hcmPack.GetPackFile()));
	fs.Types("Text files\t*.txt\nExcel files\t*.xlsx\nJson files\t*.json");
	if(fs.ExecuteSaveAs()){
		const String fileName = fs;
		if(fs.GetActiveType()==0){
			isModified = !hcmPack.ToCSV(fileName);
		}
		if(fs.GetActiveType()==1){
			isModified = !hcmPack.ToXLS(fileName);
		}
		if(fs.GetActiveType()==2){
			isModified = !hcmPack.ToJson(fileName);
		}
	}
}
bool LayHcmPackEdit::CheckHcmPack(String& slog){
	slog << "Header" << ":\n";
	hcmPack.GetHeader().Check(slog);
	for(auto v: hcmPack.GetMap()){
		slog << Format("%s \"%s\":\n", HcmEntityToStr(v.GetEntity()), v.GetField("4A").GetStr());
		v.Check(slog);
	}
	return true;
}
void LayHcmPackEdit::CloseHcmPack(){
	if(hcmPack.IsEmpty()){
		return;
	}
	layHeadEd.FromCtrl(hcmPack.GetHeader());
	if(isModified || layHeadEd.IsModified()){
		if(PromptYesNo(t_("Do you want to save the changes to the HCM file?"))){
	        SaveHcmPack();
        }
    }
    hcmPack.Clear();
    hcmPack.GetHeader().Clear();
    layHeadEd.Clear();
    layEntris.Clear();
}
void LayHcmPackEdit::NewHcmPack(){
	CloseHcmPack();
	layHeadEd.ToCtrl(hcmPack.GetHeader());
}
void LayHcmPackEdit::EditEntry(){
	EntryEditDlg dlg(true);
	dlg.BeforeFrmShow("EditEntryDlg", seriaMap);
	int idx =  layEntris.GetCurSelID();
	if(idx != -1){
		dlg.ToCtrl(hcmPack.GetHcmIN(idx));
		if(dlg.Execute() == IDOK){
			dlg.FromCtrl(hcmPack.GetHcmIN(idx));
			layEntris.ToCtrl(hcmPack);
			isModified = dlg.IsModified();
		}
		else{
			// isModified = false;
		}
	}
	dlg.BeforeFrmClose("EditEntryDlg", seriaMap);
}
void LayHcmPackEdit::AddEntry(){
	hcmPack.Add();
	isModified = true;
	layEntris.ToCtrl(hcmPack);
}
void LayHcmPackEdit::CloneEntry(){
	int idx =  layEntris.GetCurSelID();
	if(idx != -1){
		hcmPack.Add(hcmPack.GetHcmIN(idx));
		isModified = true;
		layEntris.ToCtrl(hcmPack);
	}
}
void LayHcmPackEdit::DelEntry(){
	int idx =  layEntris.GetCurSelID();
	if(idx != -1){
		if(PromptYesNo(t_("Delete an entry?"))){
			bool isDel = hcmPack.Delete(idx);
			if(!isDel){
				PromptOK(t_("Сan't delete an entry!"));
				return;
			}else{
				isModified = true;
			}
			layEntris.Clear();
			layEntris.ToCtrl(hcmPack);
		}
	}
}
//!---------------------------------------------------------------------------------------------



#endif
