#include "stdafx.h"
#include "apl_api.h"
#include "OptionDlg.h"
#include "Options4AutoAccess.h"
#include "DlgFirewallProperties.h"
#include "DlgADProperies.h"
#include "PersonalOptionsDlg.h"


class nameOpt
{
public:
	CString m_name;
	int m_val_int;
	CString m_val_str;
	bool m_is_int;
	nameOpt(){m_name=_T(""),m_val_int=0;m_val_str=_T("");m_is_int=true;};
	nameOpt(const char *name,int val=0)
	{
		m_name=name;
		m_val_int=val;m_val_str=_T("");
		m_is_int=true;
	}
	nameOpt(const char *name,const char* val=0)
	{
		m_name=name;
		m_val_str=val;m_val_int=0;
		m_is_int=false;
	}
};




//************************************************
bool CaplOptionsManager::Attach(CaplAPI *api)
{
	m_params.Clear();
	if(api==0) {Detach();return false;}
	CaplStepManager::Attach(api);

	e_str=m_data->GetEntityBN(_T("apl_string_option"));
	e_int=m_data->GetEntityBN(_T("apl_integer_option"));
	a_str_name=m_data->GetAttrDefinition(e_str,_T("name"));
	a_str_value=m_data->GetAttrDefinition(e_str,_T("val"));
	a_int_name=m_data->GetAttrDefinition(e_int,_T("name"));
	a_int_value=m_data->GetAttrDefinition(e_int,_T("val"));
	
	e_inst = m_data->GetEntityBN(_T("apl_inst_option"));
	a_inst_name = m_data->GetAttrDefinition(e_inst,_T("name"));
	a_inst_value = m_data->GetAttrDefinition(e_inst,_T("val"));

	e_ext = m_data->GetEntityBN(_T("apl_aggr_option"));
	a_ext_name = m_data->GetAttrDefinition(e_ext, _T("name"));
	a_ext_value = m_data->GetAttrDefinition(e_ext, _T("val"));

	e_double = m_data->GetEntityBN(_T("apl_double_option"));
	a_double_name = m_data->GetAttrDefinition(e_double, _T("name"));
	a_double_value = m_data->GetAttrDefinition(e_double, _T("val"));

	m_bShowMessages=true;

	LoadDictionary();

	GetOptionValueBN(_T("Код установки"), m_sInstallCode, _T(""));
	m_sInstallCode.MakeLower();

	return true;
}
//************************************************
void CaplOptionsManager::Detach()
{
	e_str=0;
	e_int=0;
	a_str_name=0;
	a_str_value=0;
	a_int_name=0;
	a_int_value=0;

	e_inst = NULL;
	a_inst_name = NULL;
	a_inst_value = NULL;

	e_ext = NULL;
	a_ext_name = NULL;
	a_ext_value = NULL;

	e_double = NULL;
	a_double_name = NULL;
	a_double_value = NULL;

	m_params.Clear();
	m_paterns.Clear();

	m_sInstallCode=_T("");
}
//************************************************
bool CaplOptionsManager::LoadDictionary()
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return false;
	
	if(!e_str) return false;
	if(!e_int) return false;
	// Массив опций
	m_params.Clear();
	// Массив шаблонов доступа - заполняется он позже
	m_paterns.Clear();

	if(e_str==0 || e_int==0){
		return false;
	}
	
	int j;
	if(m_data->IsConnected())
	{
		CaplLoadData ld(m_data,DEF_SOURCE);
		j=ld.AddQuery(_T('e'),0,e_str,0,true,true);
			  //ld.AddQuery(_T('d'),j,0,a_str_name,true);
			  //ld.AddQuery(_T('d'),j,0,a_str_value,true);
		j=ld.AddQuery(_T('e'),0,e_int,0,true,true);
			  //ld.AddQuery(_T('d'),j,0,a_int_name,true);
			  //ld.AddQuery(_T('d'),j,0,a_int_value,true);
		j=ld.AddQuery(_T('e'), 0, e_inst, 0, true, true);
		j=ld.AddQuery(_T('e'), 0, e_ext, 0, true, true);
		j=ld.AddQuery(_T('e'), 0, e_double, 0, true, true);
        bool b=ld.LoadEx(true,0, APL_NO_T("Загрузка списка опций"));
		if(!b) return false;
	}

	aplExtent ext_str, ext_int, ext_inst, ext_ext, ext_double;
	m_data->GetEntityExtent(e_str,ext_str);
	m_data->GetEntityExtent(e_int,ext_int);
	m_data->GetEntityExtent(e_inst,ext_inst);
	m_data->GetEntityExtent(e_ext, ext_ext);
	m_data->GetEntityExtent(e_double, ext_double);
	int i;
	CString buf;
	for(i=0;i<ext_str.GetSize();i++)
	{
		if(ext_str[i]->GetAccessmode()>aplRO) continue;
		m_data->GetAttr(ext_str[i],a_str_name,buf);
		m_params.Add(buf,(long)ext_str[i]);
	}

	CaplInstance *val;
	aplExtent ext2load;

	for(i=0;i<ext_inst.GetSize();i++)
	{
		if(ext_inst[i]->GetAccessmode()>aplRO) continue;
		m_data->GetAttr(ext_inst[i], a_inst_name, buf);
		m_params.Add(buf, (long)ext_inst[i]);
		m_data->GetAttr(ext_inst[i], a_inst_value, val);
		if(val) ext2load.Add(val);
	}

	m_api->LoadExtentInfo(ext2load);
	
	for(i=0;i<ext_int.GetSize();i++)
	{
		if(ext_int[i]->GetAccessmode()>aplRO) continue;
		m_data->GetAttr(ext_int[i],a_int_name,buf);
		m_params.Add(buf,(long)ext_int[i]);
	}

	for(i=0; i<ext_ext.Size; ++i)
	{
		if (ext_ext[i]->GetAccessmode()>aplRO)
			continue;
		m_data->GetAttr(ext_ext[i], a_ext_name, buf);
		m_params.Add(buf, (long)ext_ext[i]);
	}

	for(i=0; i<ext_double.Size; ++i)
	{
		if (ext_double[i]->GetAccessmode()>aplRO)
			continue;
		m_data->GetAttr(ext_double[i], a_double_name, buf);
		m_params.Add(buf, (long)ext_double[i]);
	}

	//Установка автодоступа
	int iAutoSetAccess;
	GetOptionValueBN( APL_NO_T("Назначать доступ при создании"), iAutoSetAccess, 1);
	if(0==iAutoSetAccess)m_api->SetAutoUsurpire(false);
	else m_api->SetAutoUsurpire(true);
	
	//Даже autoSave не убрал...
	bool bOld(m_AutoSave);
	m_AutoSave = false;
	// для Workflow
	CaplInstance* option= NULL;
	option= FindOptionBN( APL_NO_T("Настройка Workflow\\Не давать присваивать статусы рабочим объектам процесса"));
	if(!option) CreateOption( APL_NO_T("Настройка Workflow\\Не давать присваивать статусы рабочим объектам процесса"), 0);
	option= FindOptionBN( APL_NO_T("Настройка Workflow\\Оставить два (обычный и высокий) приоритета процессов и заданий"));
	if(!option) CreateOption( APL_NO_T("Настройка Workflow\\Оставить два (обычный и высокий) приоритета процессов и заданий"), 0);
	option= FindOptionBN( APL_NO_T("Настройка Workflow\\Удалять статусы объектов при прерывании процесса"));
	if(!option) CreateOption( APL_NO_T("Настройка Workflow\\Удалять статусы объектов при прерывании процесса"), 0);
	option= FindOptionBN( APL_NO_T("Настройка Workflow\\Удалять процесс при перезапуске"));	
	if(!option) CreateOption( APL_NO_T("Настройка Workflow\\Удалять процесс при перезапуске"), 0);
	m_AutoSave = bOld;

	if(0!=m_api->m_wf_mgr) m_api->m_wf_mgr->LoadParamsFromDB();

	return true;
}
//************************************************
bool CaplOptionsManager::LoadOptionsInfo(CaplInstance *option)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return false;
	
	if(!option) return false;
	
	aplExtent ext;
	ext.Add(option);
	return LoadOptionsInfo(ext);

}
//************************************************
bool CaplOptionsManager::LoadOptionsInfo(aplExtent &ext)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return false;
	
	CaplLoadData ld_str(m_data,DEF_SOURCE);
	CaplLoadData ld_int(m_data,DEF_SOURCE);
	CaplLoadData ld_inst(m_data,DEF_SOURCE);
	CaplLoadData ld_ext(m_data,DEF_SOURCE);
	CaplLoadData ld_double(m_data, DEF_SOURCE);
	bool bLoadStr=false, bLoadDouble=false;
	bool bLoadInt=false, bLoadInst=false, bLoadExt=false;
	int i;
	for(i=0;i<ext.GetSize();i++)
	{
		if(!ext[i]) continue;if(ext[i]->GetAccessmode()>aplRO) continue;if(ext[i]->GetId()==0) continue;
		if(m_data->IsKindOf(ext[i],e_str)) {bLoadStr=true;ld_str.AddQuery(0,ext[i],true);}
		if(m_data->IsKindOf(ext[i],e_int)) {bLoadInt=true;ld_int.AddQuery(0,ext[i],true);}
		if(m_data->IsKindOf(ext[i],e_inst)) {bLoadInst=true;ld_inst.AddQuery(0,ext[i],true);}
		if(m_data->IsKindOf(ext[i],e_ext)) {bLoadExt=true;ld_ext.AddQuery(0,ext[i],true);}
		if(m_data->IsKindOf(ext[i],e_double)) {bLoadDouble=true;ld_double.AddQuery(0,ext[i],true);}
	}
	if(bLoadStr)
		ld_str.LoadEx();
	if(bLoadInt)
		ld_int.LoadEx();
	if(bLoadInst)
		ld_inst.LoadEx();
	if (bLoadExt)
		ld_ext.LoadEx();
	if (bLoadDouble)
		ld_double.LoadEx();
	int indx;
	// проверка на удаленные
	for(i=0;i<ext.GetSize();i++)
	{
		if(!ext[i]) continue;
		if(ext[i]->GetType()==0){
			indx=m_params.Find((long)ext[i]);
			if(indx!=-1){m_params.Remove(indx);}
		}
	}
	return true;
}
//************************************************
bool CaplOptionsManager::GetOptionName(CaplInstance *option, CString &name)
{	
	name=_T("");
	if(!m_api || !m_api->m_data.IsDictLoad()) return false;
	if(0==option) return false;
	if(option->GetType()==0) return false;

	if(m_data->IsKindOf(option,e_str))
	{
		m_data->GetAttr(option,a_str_name,name);
	}
	else if(m_data->IsKindOf(option,e_int))
	{
		m_data->GetAttr(option,a_int_name,name);
	}
	else if(m_data->IsKindOf(option,e_inst))
	{
		m_data->GetAttr(option,a_inst_name,name);
	}
	else if(m_data->IsKindOf(option, e_ext))
	{
		m_data->GetAttr(option, a_ext_name, name);
	}
	else if (m_data->IsKindOf(option, e_double))
	{
		m_data->GetAttr(option, a_double_name, name);
	}
	else return false;
	return true;
}
//************************************************
CaplInstance *CaplOptionsManager::FindOptionBN(const TCHAR *name)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;
	
	if(!name) return 0;
	return (CaplInstance *) m_params.GetP(name);
}

//************************************************
bool CaplOptionsManager::GetOptionValueBN(const TCHAR *name,CString &val,const TCHAR *def_value)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;
	
	if(!name) return false;
	CaplInstance *option=FindOptionBN(name);
	val=def_value;
	if(option)
	{
		if(option->GetType()==0) return false;
		if(option->GetAccessmode()>aplRO) return false;
		if(m_data->IsKindOf(option,e_str))
		{
			m_data->GetAttr(option,a_str_value,val);
			return true;
		}
	}
	return false;
}
//************************************************
bool CaplOptionsManager::GetOptionValueBN(const TCHAR *name,int &val,int def_value)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;
	
	if(!name) return false;
	CaplInstance *option=FindOptionBN(name);
	val=def_value;
	if(option)
	{
		if(option->GetType()==0) return false;
		if(option->GetAccessmode()>aplRO) return false;
		if(m_data->IsKindOf(option,e_int))
		{
			m_data->GetAttr(option,a_int_value,val);
			return true;
		}
	}
	return false;
}
//************************************************
bool CaplOptionsManager::GetOptionValueBN(const TCHAR *name,CaplInstance **val, CaplInstance* DefVal)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;
	
	if(name==NULL) return false;
	if(val==NULL) return false;
	*val = DefVal;
	CaplInstance *option=FindOptionBN(name);
	if(option)
	{
		if(option->GetType()==0) return false;
		if(option->GetAccessmode()>aplRO) return false;
		if(m_data->IsKindOf(option,e_inst))
		{
			CaplInstance *tmp;
			m_data->GetAttr(option,a_inst_value, tmp);
			*val = tmp;
			return true;
		}
	} 
	return false;
}
//************************************************
bool CaplOptionsManager::GetOptionValueBN(const TCHAR *name, aplExtent& val)
{
	if(!m_api || !m_api->m_data.IsDictLoad())
		return 0;

	if(name==NULL) 
		return false;

	CaplInstance *option=FindOptionBN(name);
	if(option)
	{
		if(option->GetType()==0) 
			return false;
		if(option->GetAccessmode()>aplRO) 
			return false;
		if(m_data->IsKindOf(option,e_ext))
		{
			aplExtent tmp_ext;
			m_data->GetAttr(option, a_ext_value, tmp_ext);
			val = tmp_ext;
			return true;
		}
	} 
	return false;
}
//************************************************
bool CaplOptionsManager::GetOptionValueBN(const TCHAR *name,double &val,double def_value)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;

	if(!name) return false;
	CaplInstance *option=FindOptionBN(name);
	val=def_value;
	if(option)
	{
		if(option->GetType()==0) return false;
		if(option->GetAccessmode()>aplRO) return false;
		if(m_data->IsKindOf(option,e_double))
		{
			m_data->GetAttr(option,a_double_value,val);
			return true;
		}
	}
	return false;
}
//************************************************
int CaplOptionsManager::GetCounterWithIncrementBN(const TCHAR *name)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return -1;
	if(!name) return -1;

	CaplInstance *option=FindOptionBN(name);
	if(0==option)
	{
		option=CreateOption(name,(int)1);
		m_api->m_data.NET_SaveExtent(option);
		return 1;
	}

	if(option->GetType()==0) return -1;
	if(option->GetAccessmode()>aplRO) return -1;
	if(!m_data->IsKindOf(option,e_int)) return -1;

	int val;

	while(!m_api->m_data.NET_LockInstanceForChange(option,5000))
	{
		if (!m_api->m_ModeInteractive) break;
		CString buf=APL_T("Ошибка блокировки счетчика '"); buf+=name; buf+=APL_T("' !\n\nПри нажатии 'отмена' счетчик будет увеличен без блокировки,\nпри этом возможны повторы!");
		if(IDRETRY !=AfxMessageBox(buf,MB_ICONSTOP|MB_RETRYCANCEL)) break;
	}

	CaplLoadData ld_int(m_data,DEF_SOURCE);
	ld_int.AddQuery(0,option,true);
	ld_int.LoadEx();
	m_data->GetAttr(option,a_int_value,val);
	val++;
	m_data->PutAttr(option,a_int_value,val);
	//m_api->SaveChanges();
	m_api->m_data.NET_SaveExtent(option);
	return val;
} 

//************************************************
int CaplOptionsManager::GetIntOptionValueBN(const TCHAR *name, int def_value)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return -1;
	
	if(!name) return def_value;
	CaplInstance *option=FindOptionBN(name);
	if(option)
	{
		if(option->GetType()==0) return false;
		if(option->GetAccessmode()>aplRO) return false;
		if(m_data->IsKindOf(option,e_int))
		{
			int val;
			m_data->GetAttr(option,a_int_value,val);
			return val;
		}
	} 
	return def_value;
}
//************************************************
CaplInstance *CaplOptionsManager::GetInstOptionValueBN(const TCHAR *name, CaplInstance* DefVal)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;
	
	if(name==NULL) return DefVal;
	CaplInstance *option=FindOptionBN(name);
	if(option)
	{
		if(option->GetType()==0) return 0;
		if(option->GetAccessmode()>aplRO) return 0;
		if(m_data->IsKindOf(option,e_inst))
		{
			CaplInstance *val;
			m_data->GetAttr(option,a_inst_value,val);
			return val;
		}
	} 
	return DefVal;
}
//************************************************
CaplInstance *CaplOptionsManager::CreateOption(const TCHAR *name,const TCHAR *value)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;
	
	if(name==0) return 0;
	if(name[0]==_T('\0')) return 0;
	CaplInstance * inst=FindOptionBN(name);
	if(inst)
	{
		if(0!=inst->GetType())
		{
			if(!m_api->m_data.IsKindOf(inst, e_str))
			{
				DeleteOption(inst);
				inst = NULL;
			}
		}
	}
	if(inst==NULL)
	{
		inst=m_api->m_data.CreateInstance(m_api->m_options_mgr.e_str);
		m_api->m_data.PutAttr(inst,m_api->m_options_mgr.a_str_name,name);
		m_params.Add(name,(long)inst);
	}
	m_api->m_data.PutAttr(inst,m_api->m_options_mgr.a_str_value,value);

	if(m_AutoSave) 
		m_api->m_data.NET_SaveExtent(inst);

	return inst;
}
//************************************************
CaplInstance *CaplOptionsManager::CreateOption(const TCHAR *name,int value)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;
	
	if(name==0) return 0;
	if(name[0]==_T('\0')) return 0;
	CaplInstance * inst=FindOptionBN(name);
	if(inst)
	{
		if(0!=inst->GetType())
		{
			if(!m_api->m_data.IsKindOf(inst, e_int))
			{
				DeleteOption(inst);
				inst = NULL;
			}
		}
	}
	if(inst==NULL)
	{
		inst=m_api->m_data.CreateInstance(m_api->m_options_mgr.e_int);
		m_api->m_data.PutAttr(inst,m_api->m_options_mgr.a_int_name,name);
		m_params.Add(name,(long)inst);
	}
	m_api->m_data.PutAttr(inst,m_api->m_options_mgr.a_int_value,value);

	if(m_AutoSave) 
		m_api->m_data.NET_SaveExtent(inst);

	return inst;
}
//************************************************
CaplInstance *CaplOptionsManager::CreateOption(const TCHAR *name,CaplInstance* value)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;
	
	if(name==0) return 0;
	if(name[0]==_T('\0')) return 0;
	CaplInstance * inst=FindOptionBN(name);
	if(inst)
	{
		if(!m_api->m_data.IsKindOf(inst, e_inst))
		{
			DeleteOption(inst);
			inst = NULL;
		}
	}
	if(inst==NULL)
	{
		inst=m_api->m_data.CreateInstance(m_api->m_options_mgr.e_inst);
		m_api->m_data.PutAttr(inst,m_api->m_options_mgr.a_inst_name,name);
		m_params.Add(name,(long)inst);
	}
	m_api->m_data.PutAttr(inst, m_api->m_options_mgr.a_inst_value, value);
	
	if(m_AutoSave) 
		m_api->m_data.NET_SaveExtent(inst);
	
	return inst;
}
//************************************************
CaplInstance* CaplOptionsManager::CreateOption(const TCHAR *name, aplExtent &ext)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;

	if(name==0) return 0;
	if(name[0]==_T('\0')) return 0;
	CaplInstance * inst=FindOptionBN(name);

	// если инстанс опции занят другой сущностью удаляем его
	if(inst)
	{
		if(!m_api->m_data.IsKindOf(inst, e_ext))
		{
			DeleteOption(inst);
			inst = NULL;
		}
	}

	// создаем инстанс для опции с именем name
	if(inst==NULL)
	{
		inst=m_api->m_data.CreateInstance(m_api->m_options_mgr.e_ext);
		m_api->m_data.PutAttr(inst,m_api->m_options_mgr.a_ext_name,name);
		m_params.Add(name,(long)inst);
	}

	// кладем аттрибут-экстент
	m_api->m_data.PutAttr(inst, m_api->m_options_mgr.a_ext_value, ext);

	if(m_AutoSave) 
		m_api->m_data.NET_SaveExtent(inst);

	return inst;
}
//************************************************
CaplInstance *CaplOptionsManager::CreateOption(const TCHAR *name, double value)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;

	if(name==0) return 0;
	if(name[0]==_T('\0')) return 0;
	CaplInstance * inst=FindOptionBN(name);
	if(inst)
	{
		if(!m_api->m_data.IsKindOf(inst, e_double))
		{
			DeleteOption(inst);
			inst = NULL;
		}
	}
	if(inst==NULL)
	{
		inst=m_api->m_data.CreateInstance(m_api->m_options_mgr.e_double);
		m_api->m_data.PutAttr(inst,m_api->m_options_mgr.a_double_name,name);
		m_params.Add(name,(long)inst);
	}
	m_api->m_data.PutAttr(inst,m_api->m_options_mgr.a_double_value,value);

	if(m_AutoSave) 
		m_api->m_data.NET_SaveExtent(inst);

	return inst;
}
//************************************************
CaplInstance *CaplOptionsManager::CreateOption(const TCHAR *name)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;
	
	CaplSetResourceHandle setres(module_inst);
	
	COptionDlg dlg;
	dlg.m_api=m_api;
	dlg.m_name=name;
	int rez=dlg.DoModal();
	
	if(rez!=IDOK) return 0;

	if(m_AutoSave) 
		m_api->SaveChanges();
	
	return dlg.m_option;
}
//************************************************
bool CaplOptionsManager::ShowOptionProperties(CaplInstance *option)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return false;
	
	if(!option) return false;
	if(option->GetType()==0) return false;
	if(option->GetAccessmode()>aplRO) return false;
	
	LoadOptionsInfo(option);

	CaplSetResourceHandle setres(module_inst);
		
	COptionDlg dlg;
	dlg.m_api=m_api;
	dlg.m_option=option;
	int rez=dlg.DoModal();
	if(rez!=IDOK) return false;
	
	if(m_AutoSave) 
		m_api->SaveChanges();

	return true;
}
//************************************************
bool CaplOptionsManager::DeleteOption(CaplInstance *option)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return false;	
	if(!option) return false;
	if(0==option->GetType()) return false;
	
	LoadOptionsInfo(option);
	if(option->GetAccessmode()>aplRO) return false;
	
	CString name;
	GetOptionName(option,name);
	int i=m_params.Find(name);
	m_params.Remove(i);

	m_data->DeleteInstance(option);

	if(m_AutoSave) 
		m_api->SaveChanges();

	return true;
}

//************************************************
bool CaplOptionsManager::SetPattern4AutoAccess()
{
	CaplSetResourceHandle setres(module_inst);

	COptions4AutoAccess dlg;
	dlg.m_api=m_api;
	bool b=dlg.DoModal()==IDOK;

	return b;
}

//************************************************
bool CaplOptionsManager::SetFirewallProperties()
{

	bool retval=false;
	CString sOptNameOn= APL_NO_T("Свойства Firewall\\Firewall включен");
	CString sOptNameWhite= APL_NO_T("Свойства Firewall\\Белый список");

	CaplSetResourceHandle setres(module_inst);

	CDlgFirewallProperties dlg;
	GetOptionValueBN(sOptNameOn, dlg.m_OnFirewall);
	GetOptionValueBN(sOptNameWhite, dlg.m_white_list);

	if(dlg.DoModal()==IDOK){
		CreateOption(sOptNameOn, dlg.m_OnFirewall);
		CreateOption(sOptNameWhite, dlg.m_white_list);
		
		if(m_AutoSave) 
			m_api->SaveChanges();
		retval=true;
	}
	return retval;
}

CString CaplOptionsManager::GetPdfSeriesOptionName() const
{
	return APL_NO_T("Редактор_КТС3\\Шифры изделий");
}

CString CaplOptionsManager::GetInventoryBookOrderFromOptionName() const
{
	return APL_NO_T("Редактор_КТС3\\Начиная с инвентарного номера");
}

CaplInstance* CaplOptionsManager::GetDefPatern(CaplEntity* entity)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return 0;
	
	CString sOptName;
	
	sOptName= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании ");
	
	if(m_api->m_data.IsKindOfEntity(entity,m_api->m_bp_mgr.e_bp))
		sOptName+=  APL_NO_T("бизнес-процессов");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_bp_mgr.e_apl_bp_ver))
		sOptName+=  APL_NO_T("бизнес-процессов");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_bp_mgr.e_apl_bp_inst))
		sOptName+=  APL_NO_T("экземпляров бизнес-процессов");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_doc_mgr.e_apl_doc))
		sOptName+=  APL_NO_T("документов");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_doc_mgr.e_apl_doc_rev))
		sOptName+=  APL_NO_T("версий документов");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_prd_mgr.e_prd))
		sOptName+=  APL_NO_T("изделий");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_prd_mgr.e_pdf))
		sOptName+=  APL_NO_T("изделий");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_change_mgr.e_chng))
		sOptName+=  APL_NO_T("изменений");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_categ_mgr.e_categ))
		sOptName+=  APL_T("категорий");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_folder_mgr.e_folder))
		sOptName+=  APL_NO_T("папок");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_prd_inst_mgr.e_lot))
		sOptName+=  APL_NO_T("партий изделий");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_prd_inst_mgr.e_prd_inst))
		sOptName+=  APL_NO_T("экземпляров изделий");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_message_mgr.e_message))
		sOptName+=  APL_NO_T("почтовых сообщений");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_message_mgr.e_subscr))
		sOptName+=  APL_NO_T("списков рассылки");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_project_mgr->e_project))
		sOptName+=  APL_NO_T("проектов");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_bp_mgr.e_bp_res))
		sOptName+=  APL_NO_T("ресурсов");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_classifier_mgr.e_apl_classifier_system))
		sOptName+=  APL_NO_T("систем классификации");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_classifier_mgr.e_apl_classifier_level))
		sOptName+=  APL_NO_T("уровней классификации");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_appr_mgr.e_apl_appr_pers_org))
		sOptName+=  APL_NO_T("статусов");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_charact_mgr.e_apl_charact_value))
		sOptName+=  APL_NO_T("характеристик");
	else if(m_api->m_data.IsKindOfEntity(entity,m_api->m_charact_mgr.e_apl_charact_value_ver))
		sOptName+=  APL_NO_T("характеристик");
	
	CString sOption, buf;
	aplExtent pats;
	
	CaplInstance* patern= (CaplInstance*)m_paterns.GetByIn((long)entity);
	if(-1==(long)patern)//вообще не нашли
	{
		patern= NULL;
		GetOptionValueBN(sOptName, sOption, _T(""));
		
		m_api->m_data.GetEntityExtent(m_api->m_appr_mgr.e_apl_acc_pat, pats);
		for(int i= 0; i<pats.GetSize() && !patern; i++)
		{
			m_api->m_data.GetAttr(pats[i], m_api->m_appr_mgr.a_apl_acc_pat_name, buf);
			if(buf.CompareNoCase(sOption)==0){
				patern=pats[i];
				break;
			}
		}
		
		m_paterns.Add((long)entity, (long)patern);
	}
	
	return patern;
}

BOOL CaplOptionsManager::GetDefTmplName(CaplEntity* entity, CString& sTmplName)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return FALSE;
	
	CaplInstance* patern= GetDefPatern(entity);
	if(patern)
	{
		m_api->m_data.GetAttr(patern, m_api->m_appr_mgr.a_apl_acc_pat_name, sTmplName);
		return TRUE;
	}
	
	return FALSE;
}

BOOL CaplOptionsManager::GetDefPatern(CaplEntity* entity, CString& sPatern)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return FALSE;
	
	CaplInstance* patern= GetDefPatern(entity);
	if(patern)
	{
		m_api->m_data.GetAttr(patern, m_api->m_appr_mgr.a_apl_acc_pat_pattern, sPatern);
		return TRUE;
	}
	return FALSE;
}

bool CaplOptionsManager::WherePatternUsed(CString &pattern_name, CString &option_used)
{
	if(!m_api || !m_api->m_data.IsDictLoad()) return FALSE;

	int i;
	CString opt_name,opt_val;
	CaplInstance* inst;
	option_used=_T("");

	for(i=0;i<m_params.GetSize();i++){
		opt_name=m_params.GetAt(i)->str;
		if(opt_name.Find( APL_NO_T("Назначать доступ при создании"),0)!=-1){
			inst=(CaplInstance*)m_params.GetAt(i)->val;
			if(opt_name.CompareNoCase( APL_NO_T("Назначать доступ при создании"))==0){
				//
			}else{
				m_api->m_data.GetAttr(inst,m_api->m_options_mgr.a_str_value,opt_val);
				if(opt_val.CompareNoCase(pattern_name)==0){
					option_used=opt_name;
					return true;
				}
			}
		}
	}
	return false;
}

//Инициализация массива наименований, 
//для которых используются целые значения
bool CaplOptionsManager::InitDefaultOptions()
{

	// Удаление устаревших шаблонов доступа
	if(m_api->m_data.IsAdmin())
	{
		bool bNeedSave=false;
		CaplInstance *opt;

		opt=FindOptionBN(APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании категорий"));
		if(0!=opt){m_api->m_data.DeleteInstance(opt); bNeedSave=true;}
		opt=FindOptionBN(APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании почтовых сообщений"));
		if(0!=opt){m_api->m_data.DeleteInstance(opt); bNeedSave=true;}
		opt=FindOptionBN(APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании списков рассылки"));
		if(0!=opt){m_api->m_data.DeleteInstance(opt); bNeedSave=true;}

		if(bNeedSave) m_api->SaveChanges();

	}

	CArray<nameOpt,nameOpt> intParams;
	nameOpt new_param;
	new_param.m_name= APL_NO_T("Уникальность изделия проверять по комбинации обозначения и наименования");intParams.Add(new_param);
	//new_param.m_name=APL_NO_T("Автоматически запрещать изменения статусов");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании");intParams.Add(new_param);
	new_param.m_is_int=false;
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании папок");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании изделий");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании документов");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании версий документов");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании характеристик");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании статусов");intParams.Add(new_param);
	
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании изменений");intParams.Add(new_param);
//	new_param.m_name=APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании почтовых сообщений");intParams.Add(new_param);
//	new_param.m_name=APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании списков рассылки");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании бизнес-процессов");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании экземпляров бизнес-процессов");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании ресурсов");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании экземпляров изделий");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании партий изделий");intParams.Add(new_param);
//	new_param.m_name=APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании категорий");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании проектов");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании систем классификации");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа при создании уровней классификации");intParams.Add(new_param);

	new_param.m_name= APL_NO_T("Назначать доступ при создании\\Шаблон доступа сервера при создании любых инстансов при отсутствии шаблона пользователя");intParams.Add(new_param);
	
	new_param.m_name= APL_NO_T("Политики доступа\\Роль на разрешение операций с низкоуровневыми объектами");intParams.Add(new_param);

	new_param.m_is_int=true;
	new_param.m_name= APL_NO_T("Запретить пользователям изменение заданных настроек");intParams.Add(new_param);
	//new_param.m_name=APL_NO_T("Проекты");intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Проекты\\Иерархический контроль сроков");new_param.m_val_int=1;intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Проекты\\Запретить перевыполнение плана");new_param.m_val_int=1;intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Проекты\\Присваивать статус 'завершен' при достижении 100%");new_param.m_val_int=1;intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Проекты\\Автоматически присваивать статус 'завершен' проектам-родителям");new_param.m_val_int=1;intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Проекты\\Показывать ассоциированные проекты");new_param.m_val_int=1;intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Проекты\\Присоединять документы как рабочие объекты");new_param.m_val_int=0;intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Показывать историю экземпляров изделий");new_param.m_val_int=0;intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Запретить использование контейнеров AplCryptManager версии 0");new_param.m_val_int=0;intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Запретить вход в БД с пустым паролем");new_param.m_val_int=0;intParams.Add(new_param);
	new_param.m_name= APL_NO_T("Фиксировать неудачные попытки входа");new_param.m_val_int=0;intParams.Add(new_param);

	int i;
	for(i=0;i<intParams.GetSize();i++)
	{
		if(!m_api->m_options_mgr.FindOptionBN(intParams[i].m_name)){
			if(intParams[i].m_is_int){
				m_api->m_options_mgr.CreateOption(intParams[i].m_name,intParams[i].m_val_int);
			}else{
				m_api->m_options_mgr.CreateOption(intParams[i].m_name,intParams[i].m_val_str);
			}
		}
	}	
	return true;
}

INT_PTR CaplOptionsManager::CreateDlgADProperties ()
{
	CaplSetResourceHandle setres(module_inst);
	CDlgADProperies dlg;
	dlg.m_api=m_api;
	INT_PTR Result = dlg.DoModal();
	return Result ;
}

bool CaplOptionsManager::CheckInstallCode(LPCTSTR code)
{
	if(m_sInstallCode==_T("")) return false;
	CString buf=code;
	buf.MakeLower();
	if(buf==m_sInstallCode) return true;
	return false;
}

//*******************************************************************
//*******************************************************************
bool CaplOptionsManager::EditPersonalOptions()
{
	CaplSetResourceHandle setres(module_inst);
	CPersonalOptionsDlg dlg;
	dlg.m_api=m_api;
	if(IDOK!=dlg.DoModal()) return false;
	return true;
}

//*******************************************************************
//*******************************************************************

bool CaplOptionsManager::DivideStringOptions(LPCTSTR str, CStringArray &strings)
{
	strings.RemoveAll();

	if(0==str) return false;
	if(_T('\0')==str[0]) return false;

	CString buf,val=str;
	
	int pos_prev=0;
	int pos=val.Find(_T('|'));
	while(pos>=0)
	{
		if((pos-pos_prev)>1)
		{
			buf=val.Mid(pos_prev,pos-pos_prev);
			buf.TrimLeft();buf.TrimRight();
			if(buf!=_T(""))strings.Add(buf);
		}
		pos_prev=pos+1;
		pos=val.Find(_T('|'),pos+1);
	}

	buf=val.Right(val.GetLength()-pos_prev); 
	buf.TrimLeft();buf.TrimRight();
	if(buf!=_T(""))strings.Add(buf);
	
	return true;
}
//***********************************************************************************
bool CaplOptionsManager::LoadPersonalOptionString(CString &sOptions, CaplInstance *person)
{
	sOptions=_T("");
	if(0==person) person=m_api->m_appr_mgr.GetCurrentPerson();
	if(0==person) return false;

	CaplLoadData ld(&(m_api->m_data));
	ld.AddQuery(0,person,true);
	ld.LoadEx();

	m_api->m_data.GetAttr(person,m_api->m_appr_mgr.a_pers_options,sOptions);
	if(sOptions==_T("")) return true;
	
	// Проверяем на blob
	long lBlobSize;
	bool bOldHideMode=m_api->m_data.SetHideMode(true);
	bool bIsBlob=m_api->m_data.NET_GetBlobSize(person,m_api->m_appr_mgr.a_pers_options,lBlobSize);
	m_api->m_data.SetHideMode(bOldHideMode);

	if(!bIsBlob) return true; // Значит данные в сточке
	if(0==lBlobSize) return true;

	BYTE *buf=new BYTE[lBlobSize+2]; // 2байта на случай юникода 
	if(!m_api->m_data.NET_LoadBlob2Memory(person,m_api->m_appr_mgr.a_pers_options,buf,lBlobSize, APL_T("Чтение персональнях настроек")))
	{
		sOptions=_T("");
		return false;
	}
	buf[lBlobSize]=_T('\0');

	// Данные могут быть в ANSI или UCS2
	bool bIsUCS2=false;
	if(lBlobSize>=2)
	{
		//if(0==buf[1] || 0x04==buf[1]) bIsUCS2=true;
		if(((unsigned char)buf[1]) < 32) bIsUCS2=true;
	}

#ifdef _UNICODE

	if(bIsUCS2)
		sOptions=(LPCWSTR)buf;
	else
	{
		// Такое не работает при нерусской локали
		//CStringA tmp((LPCSTR)buf);
		//sOptions=tmp;

		int len= MultiByteToWideChar(1251, 0,(LPSTR) buf, -1, NULL, 0);
		wchar_t *wide_str = new wchar_t[len+1];
		MultiByteToWideChar(1251, 0, (LPSTR) buf, -1, wide_str, sizeof(wchar_t)*(len+1));
		wide_str[len]= _T('\0');
		sOptions=wide_str;
		delete wide_str;
	}
#else
	if(bIsUCS2)
	{
		// Такое не работает при нерусской локали
		//CString tmp((LPCWSTR)buf);
		//sOptions=tmp;

		int len= WideCharToMultiByte(1251, 0, (LPCWSTR) buf, -1, NULL, NULL, NULL, NULL);
		char *ansi_str = new char[len+1];
		WideCharToMultiByte(1251, 0, (LPCWSTR) buf, -1, ansi_str, len+1,NULL, NULL);
		ansi_str[len]= '\0';
		sOptions=ansi_str;
		delete ansi_str;
	}
	else 
		sOptions=(LPCSTR)buf;
#endif


	delete buf;
	return true;
}

bool CaplOptionsManager::SavePersonalOptionString(CString &sOptions)
{
	CaplInstance *curperson=m_api->m_appr_mgr.GetCurrentPerson();
	if(0==curperson) return false;

	CString sBlob;
	m_api->m_data.GetAttr(curperson,m_api->m_appr_mgr.a_pers_options,sBlob);
	if(sBlob!=_T("")) m_api->m_data.NET_DeleteBlob(curperson,m_api->m_appr_mgr.a_pers_options);

	if(sOptions==_T("")) m_api->m_data.PutAttr(curperson,m_api->m_appr_mgr.a_pers_options,(LPCTSTR)0);
	else
	{
		long code;
		if(!m_api->m_data.NET_SaveFileFromMemory(curperson,m_api->m_appr_mgr.a_pers_options,(BYTE*)LPCTSTR(sOptions),sizeof(TCHAR)*(sOptions.GetLength()+1),code,APL_T("Сохранение персональнях настроек"))) return false;
	}
	m_api->SaveChanges();

	return true;

}

//***********************************************************************************
int  CaplOptionsManager::GetIntPersonalOptionValueBN(CString &sOptions, const TCHAR *name, int def_value)
{
	if(sOptions==_T("")) return def_value;
	CString sName=name;
	if(sName==_T("")) return false;

	sName+=_T(':');
	int i=sOptions.Find(sName);
	if(i<0 ) return def_value;

	i+=sName.GetLength();
	int j=sOptions.Find(_T('\n'),i);

	CString sVal;
	if(j>0) sVal=sOptions.Mid(i,j-i);
	else sVal=sOptions.Right(sOptions.GetLength()-i);
	sVal.TrimLeft();
	if(sVal==_T("")) return def_value;

	return _atoi(LPCTSTR(sVal));
}

//***********************************************************************************
bool  CaplOptionsManager::SetIntPersonalOptionValueBN(CString &sOptions, const TCHAR *name, int value)
{
	CString sName=name;
	if(name==_T("")) return false;

	CString sVal;

	sName+=_T(':');
	int i=sOptions.Find(sName);
	if(i<0) // не было такой опции
	{
		if(sOptions!=_T("")) // есть другие опции
		{
			TCHAR c=sOptions[sOptions.GetLength()-1];
			if(c!=_T('\n')) 
				sOptions+=_T('\n');
		}
		sVal.Format(_T("%i"),value);
		sOptions+=sName;
		sOptions+=sVal;
		return true;
	}

	i+=sName.GetLength();
	int j=sOptions.Find(_T('\n'),i);
	if(j<0) j=sOptions.GetLength();

	sOptions.Delete(i,j-i);
	sVal.Format(_T("%i"),value);
	sOptions.Insert(i,sVal);

	return true;
}

//***********************************************************************************
bool  CaplOptionsManager::DeletePersonalOptionValueBN(CString &sOptions, const TCHAR *name)
{
	CString sName=name;
	if(name==_T("")) return false;

	sName+=_T(':');
	int i=sOptions.Find(sName);
	if(i<0) return true;

	int j=sOptions.Find(_T('\n'),i+sName.GetLength());
	if(j<0) j=sOptions.GetLength();
	else j++;
	sOptions.Delete(i,j-i);
	return true;
}

//***********************************************************************************
int CaplOptionsManager::GetIntPersonOption(CaplInstance *person, LPCTSTR sOption) // Если опции нет - возвращает 0
{
	if(0==sOption) return 0;
	if(_T('\0')==sOption[0]) return 0;
	if(0==person) person=m_api->m_appr_mgr.GetCurrentPerson();
	if(0==person) return 0;

	CString sOptionsData;
	if(!LoadPersonalOptionString(sOptionsData,person)) return 0;

	if(sOptionsData==_T("")) return 0;
	return GetIntPersonalOptionValueBN(sOptionsData,sOption,0);
}
