// TransportSocketClient.h: interface for the CtransportSocketClient class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_TRANSPORTSOCKETCLIENT_H__130138C3_0463_4571_836D_127B95B69339__INCLUDED_)
#define AFX_TRANSPORTSOCKETCLIENT_H__130138C3_0463_4571_836D_127B95B69339__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <aplSocketTransport.h>
#include <aplAggr.h>
#include "MiddleWare.h"
#include "DlgReconnect.h"

#define	FILL_SERVICE_TEST(param) \
	code=param; test_ver_buf.Add(&code,4); cs_buf=param##_header; size=cs_buf.GetLength()+1; test_ver_buf.Add(&size,4); test_ver_buf.Add((void*)(const char*)cs_buf, size);


#define SPEC_ERR_CODES(err_code) \
	err_code!=APL_NET_OK && \
	err_code!=APL_NET_SRV_SINGLE_CONNECT_DB && \
	err_code!=APL_NET_SRV_SINGLE_CONNECT_LITE_D && \
	err_code!=APL_NET_SRV_EXPIRE_SRC_LIC_D && \
	err_code!=APL_NET_SRV_EXPIRE_KEY_IN_SRV_LIC_EXCLUSIVE && \
	err_code!=APL_NET_SRV_MISSED_KEY_IN_SRV_LIC

#define APL_ERROR_CONDITION SPEC_ERR_CODES(aplError)

#define APL_ERROR_STOP_TIME 5000

#define DEF_PORT_NUM 7239

///////////////////////////////////////////////////////////
// Мы в реестре используем эти ключи
//	#define REG_KEY "Software\\НИЦ CALS \"Прикладная логистика\"\\NetApi"
#define		REG_KEY _T("Software\\CALS Centre \"Applied Logistic\"\\NetApi\\Client")

#define PROXY_TEXT__USE_IE APL_T("Из настроек Internet Explorerа")
#define PROXY_TEXT__USE_DIRECT APL_T("Соединение без прокси")
#define PROXY_TEXT__USER_PROXY APL_T("Задано пользователем")


/****************************************************************************/
/* параметры авторизации (временное хранение для скрытого восстановления соединения)
/****************************************************************************/
struct apl_NET_LoginData
{
	apl_NET_LoginData(){Clear();}
	void Clear()
	{
		client_ip = 0; s1 = 0; s2 = 0; client_id = 0; user_id = 0; type_license = _T("");
		username=_T(""); domain=_T("") ;pwd=_T(""); name_base=_T("");
		/*isKerberos=false; isCurrDomainUser=false;*/sOsUser=_T("");name_connect=_T("");
	}
	/// имя пользователя
	CString username;
	/// домен
	CString domain;
	/// пароль пользователя или хеш пароля (для пользователей в контексте сервера Qt)
	CString pwd;
	/// имя БД в контексте сервера приложений
	CString name_base;
	/// IP-адрес клиента, определенный на стороне клиента
	UINT32 client_ip;
	// Дополнительные параметры клиента для учета лицензий внутри одного процесса клиента (например, лицензировать сеансы веб-сервера)
	UINT32 s1;
	UINT32 s2;

	/// Идентификатор процесса клиента
	UINT32 client_id;
	/// идентификатор пользователя (атрибут id инстансы типа apl_user)
	UINT32 user_id;
	/// тип лицензии
	CString type_license;
	/*	на будущее, если будем переносить сюда керберос и AD
	/// флаг: аутентификация через Керберос
	bool isKerberos;
	*/
	/// флаг: аутентификация под текущим доменным пользователем ОС
	bool isCurrDomainUser;
	/// имя пользователя операционной системы
	CString sOsUser;
	/// 	Имя подключения к БД
	CString name_connect;

};

class CaplNetStepData;
class CConnectInfo;

class CTransportSocketClient 
{
	friend CaplNetStepData;
public:
	CTransportSocketClient(CaplNetStepData* data);
	~CTransportSocketClient();
	void OnClose();
	
	// !!! здесь специально const char* чтобы не переделывать работу с типами параметров 
	AplNetErrors TestParamIdent(CaplDataBuf &dbuf, FuctionCodes code, const char* _param_def);
	AplNetErrors TestParamIdent(CaplDataBuf &dbuf, FuctionCodes code, CaplTAggr<const char*, const char*, APLAGGR_LIST> &params, int &param);

	// !!! здесь специально const char* чтобы не переделывать работу с типами параметров 
	bool FillStdHeader(CaplDataBuf &dbuf, FuctionCodes code, const char* _param_cur);

	// добавляет в буфер значение переменной m_source (место в исходниках, откуда вызвана функция NET_xx)
	inline void AddSource2Dbuf(CaplDataBuf &dbuf);

	// читает из буфера флаги варингов, возможность повтора операции, текст
	void ReadErrAdditionalBuf(CaplDataBuf &dbuf, CaplDataBuf &dbuf_add, AplNetErrors &aplError, BYTE &is_warning_data, BYTE &can_repeat);

	bool Call(CaplDataBuf &dbuf, CaplDataBuf *dbuf_ext, bool can_break=true, bool pause_wait_dlg=true, bool wait_answer=true, bool can_reconnect=true);

	bool ABO_DCQueryListBase(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_out);
	bool ABO_DCGetLicenseStatus(/*[in,out]*/ AplNetErrors &aplError, CString &status, /*[out]*/UINT32 *ServerCode);

	bool ABO_DCLockServ(/*[in,out]*/ AplNetErrors &aplError);
	
	// Получить версию и тип сервера приложений
	bool AT_DCQueryServerVersion(/*[in,out]*/ AplNetErrors &aplError, CString *ver_srv, CString *type_srv, CString *ClassSrv, CString *build_date);

	// Функция общается с API Kerberos или API ExternalAuthentication на своем компе и транслирует буфер от него на сервер для передачи API
	// Kerberos или ExternalAuthentication там; получает обратно буфер от серверного Kerberos и обрабатывает его своим API до получения
	// положительного или отрицательного результата аутентификации
	bool DC_AuthExternal(LPCTSTR _username, LPCTSTR _pwd, LPCTSTR _domain);
	// непосредственно передача буфера на сервер
	bool AT_DCAuthExternal(/*[out]*/ AplNetErrors &aplError, CaplDataBuf &dbuf_in, CaplDataBuf &dbuf_out);

	// Отрабатываем попытку соединения клиента с некоторой базой
	//bool AT_DCConnect(/*[in,out]*/ AplNetErrors &aplError, /*[in]*/ long *size, /*[in,size_is(size)]*/ apl_NET_LoginData *LoginData, bool *can_find_in_blob);
	bool AT_DCConnectEx(AplNetErrors &aplError, UINT32 *user_id = 0, CString *ver_srv = 0, CString *type_srv = 0, 
							UINT32 *ServerAUSessionId = 0, bool *can_find_in_blob = 0, CString *class_srv = 0);
	bool AT_DCDisconnect(/*[in,out]*/ AplNetErrors &aplError);

	bool AT_DCLicOperate(AplNetErrors &aplError, LicOperate command, CStringArray &listIn, CStringArray &listOut);

	bool AT_DCStartAdminMode(AplNetErrors &aplError, LPCTSTR username, LPCTSTR pwd, UINT32 *admin_id, int code1, int code2, LPCTSTR str_about);
	bool AT_DCExitAdminMode(AplNetErrors &aplError, UINT32 *user_id);
	bool AT_DCLoadEntityTables(AplNetErrors &aplError, CaplMap &Entity2Tabl);
	bool AT_DCGetOraAlias(AplNetErrors &aplError, LPCTSTR username, LPCTSTR pwd, int code1, int code2, CaplDataBuf &data_out);

	bool AT_DCSessionPartsOperate(AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out);
	
	bool AT_DCBeginLongOperation(AplNetErrors &aplError, UINT32 time_in_minuts);

	// Генерит по запросу буфер и запоминает указатель на него в m_TempStor, а размер в m_TempSize
	bool AT_DCLoad(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, 
											CaplDataBuf &data_out, CaplDataBuf *data_out2, __int64 *size_64_1);
	// Генерит буфер, содержащий удаленные инстансы
	bool AT_DCQuerDelInst(AplNetErrors &aplError, CaplDataBuf &data_out);
	// Служебные операции с шаблонами доступа
	bool AT_DCServiceAccessPatterns(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out);
	
	bool AT_DCQuerSysTime(/*[in,out]*/ AplNetErrors &aplError, /*[out, size_is(8)]*/ BYTE Result[8]);
	bool AT_DCQuerActiveUserList(/*[in,out]*/ AplNetErrors &aplError, /*[in,out]*/ CaplDataBuf &data_out);
	bool AT_DCQuerActiveUserListEx(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, /*[in,out]*/ CaplDataBuf &data_out);


	// Присоединение к итератору существующего БЛОБа или вновь созданного
	bool AT_DCCreateIterator(/*[in,out]*/ AplNetErrors &aplError, /*[in]*/ UINT32 *SizeNameBLOB, /*[in,out,size_is(*SizeNameBLOB)]*/ BYTE *NameBLOB,
		/*[in]*/ UINT32 SizeNameFile, /*[in,out,size_is(SizeNameFile)]*/ BYTE *NameFile, /*[in]*/ UINT32 *SizeDose, /*[in,out*/UINT32 *SizeBLOB,
		/*[in]*/ UINT32 inst_id = 0, /*[in,out*/ int crc32 = 0);
	bool AT_DCCreateIterator64(/*[in,out]*/ AplNetErrors &aplError, /*[in]*/ UINT32 *SizeNameBLOB, /*[in,out,size_is(*SizeNameBLOB)]*/ BYTE *NameBLOB,
		/*[in]*/ UINT32 SizeNameFile, /*[in,out,size_is(SizeNameFile)]*/ BYTE *NameFile, /*[in]*/ UINT32 *SizeDose, /*[in,out*/__int64 *SizeBLOB,
		/*[in]*/ UINT32 inst_id = 0, /*[in,out*/ int crc32 = 0);
	// Отсоединение итератора от блоба
	bool AT_DCCloseIterator(/*[in,out]*/ AplNetErrors &aplError);
	// Удаление итератора вместе с файлом
	bool AT_DCDeleteIterator(/*[in,out]*/ AplNetErrors &aplError, int inst_id, int attr_id);
	// Чтение из блоба, присоединенного к итератору
	bool AT_DCReadFromIterator(/*[in,out]*/ AplNetErrors &aplError, /*[in]*/ UINT32 *SizeDose, /*[out,size_is(SizeDose)]*/ BYTE *Dose, /*[out]*/ UINT32 *LastDose);
	// Запись в блоб, присоединенный к итератору
	bool AT_DCWriteToIterator(/*[in,out]*/ AplNetErrors &aplError, /*[in]*/ UINT32 SizeDose, /*[in,size_is(SizeDose)]*/ BYTE *Dose, /*[in]*/ UINT32 LastDose);

	//  Присоединение к итератору для чтения нескольких БЛОБов
	bool AT_DCCreateMultiIterator(AplNetErrors &aplError, /*[in]*/ CaplDataBuf &data_in, /*[in]*/ UINT32 *SizeDose, /*[in,out*/ CaplDataBuf &data_out);
	bool AT_DCCreateMultiIterator64(AplNetErrors &aplError, /*[in]*/ CaplDataBuf &data_in, /*[in]*/ UINT32 *SizeDose, /*[in,out*/ CaplDataBuf &data_out);
	// Отсоединение от мульти-итератора
	bool AT_DCCloseMultiIterator(/*[in,out]*/ AplNetErrors &aplError);
	// Чтение из блоба, присоединенного к итератору
	bool AT_DCReadFromMultiIterator(/*[in,out]*/ AplNetErrors &aplError, /*[in]*/UINT32 *SizeDose, /*[out]*/ CaplDataBuf &data_out, /*[out]*/ CaplDataBuf &data_out2);
	// Возвращает максимально возможный размер БЛОБа (для оракла он ограничен размером файла данных БД)
	// Произвольный доступ к BLOB
	bool AT_DCBlobRandomCreate(AplNetErrors &aplError, CString &NameBLOB, __int64 start_size, __int64 &actual_size);
	bool AT_DCBlobRandomRead(AplNetErrors &aplError, __int64 offset, __int64 size, CaplDataBuf &data_out, __int64 &actual_read);
	bool AT_DCBlobRandomWrite(AplNetErrors &aplError, __int64 offset, CaplDataBuf &data, __int64 &actual_written);
	bool AT_DCBlobRandomResize(AplNetErrors &aplError, __int64 new_size);

	bool AT_GetMaxBlobSize64(/*[in,out]*/ AplNetErrors &aplError, /*[in]*/ __int64 &MaxSizeBLOB);
	// Возвращает клиенту список файлов в каталоге, предназначенном для автообновления. (новая версия, для новых серверов, возвращает так же crc32 файлов)
	bool AT_DCAutoupdate_LoadListNamesFiles(/*[in,out]*/AplNetErrors &aplError, /*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out);
	// Возвращает клиенту список файлов в каталоге, предназначенном для автообновления. На входе - 2 строки 1) с именем программы 2) с маской имени файла
	// Отличия от CAplTransport__Autoupdate_LoadListNamesFiles:
	// есть заголовок версии буфера
	// маска разделена переводами строк а не пробелами
	// Если в маске указаны файлы "*.luf", то разбирает все имеющиеся luf и возвращает список для файлов, подлежащих обновлению
	bool AT_DCAutoupdate_LoadListNamesFilesEx(/*[in,out]*/AplNetErrors &aplError, /*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out);
	//  Присоединение к итератору для чтения нескольких БЛОБов
	bool AT_DCAutoupdate_CreateMultiIterator(AplNetErrors &aplError, /*[in]*/ CaplDataBuf &data_in, /*[in]*/ UINT32 *SizeDose, /*[in,out*/ CaplDataBuf &data_out);
	// Отсоединение от мульти-итератора
	bool AT_DCAutoupdate_CloseMultiIterator(/*[in,out]*/ AplNetErrors &aplError);
	// Чтение из блоба, присоединенного к итератору
	bool AT_DCAutoupdate_ReadFromMultiIterator(/*[in,out]*/ AplNetErrors &aplError, /*[in]*/UINT32 *SizeDose, /*[out]*/  CaplDataBuf &data_out, /*[out]*/ CaplDataBuf &data_out2);

	// Сохраняет БЛОБ на диск минуя клиента
	bool AT_DCSaveBlob2Srv(/*[in,out]*/ AplNetErrors &aplError, /*[in]*/ UINT32 SizeNameBLOB, /*[in,out,size_is(*SizeNameBLOB)]*/ BYTE *NameBLOB,
								/*[in]*/ UINT32 SizeNameFile, /*[in,out,size_is(SizeNameFile)]*/ BYTE *NameFile);
	// Создаем блоб из файла по абсолютному пути минуя клиента
	bool AT_DCReadBlobFromSrv(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/ UINT32 *SizeNameBLOB,/*[in,out,size_is(*SizeNameBLOB)]*/ BYTE *NameBLOB,/*[in]*/ UINT32 SizeNameFile,/*[in,out,size_is(SizeNameFile)]*/ BYTE *NameFile, /*[in,out*/UINT32 *SizeBLOB);
	bool AT_DCReadBlobFromSrv64(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/ UINT32 *SizeNameBLOB,/*[in,out,size_is(*SizeNameBLOB)]*/ BYTE *NameBLOB,/*[in]*/ UINT32 SizeNameFile,/*[in,out,size_is(SizeNameFile)]*/ BYTE *NameFile,/*[in,out*/__int64 *SizeBLOB);
	
	// Вносит изменения от клиента в рабочую базу
	bool AT_DCSaveChanges(/*[in,out]*/ AplNetErrors &aplError,/*[in,out]*/ CaplDataBuf &data_in, CaplDataBuf &data_out);
	// 
	bool AT_DCQuery(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/  CaplDataBuf &data_in, CaplDataBuf &data_out);
	bool AT_DCQueryEx(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/  CaplDataBuf &data_in, CaplDataBuf &data_out,CaplDataBuf &data_out2, LPCTSTR def_source, __int64 *size_all = 0);
	//Установить список доступа
	bool AT_DCSetUsersAccess(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/ CaplDataBuf &data_in);
	//Установить список доступа с упорядочением по инстансам
	bool AT_DCSetUsersAccessBI(/*[in,out]*/ AplNetErrors &aplError,/*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out);
	//Получить список доступа
	bool AT_DCGetUsersAccess(/*[in,out]*/ AplNetErrors &aplError,CaplDataBuf &data_in, CaplDataBuf &data_out);
	//Получить список доступа с упорядочением по инстансам
	bool AT_DCGetUsersAccessBI(/*[in,out]*/ AplNetErrors &aplError,CaplDataBuf &data_in, CaplDataBuf &data_out);
	//Получить имя схемы и путь к файлу схемы
	bool AT_DCGetDictName(/*[in,out]*/ AplNetErrors &aplError,/*[in,out]*/ UINT32 *BufNameSize, /*[in,out, size_is(*BufNameSize)]*/ BYTE *BufName,/*[in,out]*/ UINT32 *BufFilePathSize,/*[in,out, size_is(*BufFilePathSize)]*/ BYTE *BufFilePath);
	//Проверяет, есть ли инстансы с данными условиями
	bool AT_DCTestUniqueAttrValues(/*[in,out]*/AplNetErrors &aplResult,/*[in]*/ CaplDataBuf &data_in);
	//Генерит список инстансов с данными условиями
	bool AT_DCFindInstancesWithAttrValuesQuery(/*[in,out]*/AplNetErrors &aplResult,/*[in]*/ CaplDataBuf &data_in,CaplDataBuf &data_out);
	//Создает и удаляет индексы
	bool AT_DCOperateIndexes(/*[in,out]*/AplNetErrors &aplError,/*[in]*/ UINT32 attr_id, UINT32 state);

	bool AT_DCTest(/*[in,out]*/AplNetErrors &aplError,/*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out);
	//Вернуть для списка инстансов кто и когда их создал/последний раз изменил
	bool AT_DCLoadInstUserDataTimeInfo(/*[in,out]*/AplNetErrors &aplError,/*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out);
	// Выполняет SQL-запрос и если есть результат - возвращает клиенту (только для ORACLE или Postgre)
	bool AT_DCExecuteSQL(/*[in,out]*/AplNetErrors &aplError,/*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out, LPCTSTR def_source);
	// Выполняет SQL-запрос и если есть результат - возвращает клиенту aplExtent (только для ORACLE или Postgre)
	bool AT_DCExecuteSQLEx(/*[in,out]*/AplNetErrors &aplError,/*[in]*/ CaplDataBuf &data_in, CaplDataBuf &data_out, bool old, CaplDataBuf &data_out2, LPCTSTR def_source);

	// запрашивает служебные параметры БД
	bool AT_DCLoadBDInfo(/*[in,out]*/AplNetErrors &aplError, /*[OUT]*/ CaplDataBuf &data_out);
	//запрашивает историю коннекта пользователей
	bool AT_DCQueryUsersLog(/*[in,out]*/AplNetErrors &aplError,/*[OUT]*/ CaplDataBuf &data_out);
	//запрашивает историю коннекта пользователей c фильтром
	bool AT_DCQueryUsersLogEx(/*[in,out]*/AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out);
	//чистит историю коннекта пользователей
	bool AT_DCClearUsersLog(/*[in,out]*/AplNetErrors &aplError,/*[OUT]*/ CaplDataBuf &data_in);
	
	// Записывает клиентское сообщение в лог и (если ORACLE) в таблицу
	bool AT_DCWriteToLog(/*[in,out]*/ AplNetErrors &aplError,/*[in,out]*/ CaplDataBuf &data_in);
	
	bool AT_DCControlAccessDoc(/*[in,out]*/ AplNetErrors &aplError,/*[in,out]*/ CaplDataBuf &data_in, UINT32 &result);

	// Копирование доступа поинстансово с экстента на экстент
	bool AT_DCCopyAccessFromExt2Ext(/*[in,out]*/AplNetErrors &aplError,/*[IN]*/ CaplDataBuf &data_1,/*[IN]*/ CaplDataBuf &data_2, int code1, int code2);
	// Копирование доступа поинстансово с инстанса на экстент
	bool AT_DCCopyAccessFromInst2Ext(/*[in,out]*/AplNetErrors &aplError,/*[OUT]*/ CaplDataBuf &data_in, int code1, int code2);
	// Запрос доступного метода аутентификации - один раз перед логином
	bool AT_DCServiceGetAuthParam(/*[in,out]*/ AplNetErrors &aplError, UINT32 param, CString &value);
	// Проверка соответствия версий буферов сервера и клиента - один раз при логине
	bool AT_DCServiceTestVersions(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in);
	// Получить историю изменения атрибутов
	bool AT_DCGetAttrsHistory(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out);
	// Получить список атрибутов, в которых живут идентификтаоры БЛОБов
	bool AT_DCGetAttrs4Blobs(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_out);
	// Принять с клиента новый словарь и запустить обновление словарей посредством запуска БДАдмина
	bool AT_DCRunUpdateDictionary(/*[in,out]*/ AplNetErrors &aplError,/*[in,out]*/ CaplDataBuf &data_in);
	bool AT_DCRunApp(/*[in,out]*/ AplNetErrors &aplError,/*[in,out]*/ CaplDataBuf &data_in);
	// Заблокировать на запись инстанс или пачку инстансов
	bool AT_DCLockInstance(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, int &result);
	// Служебные операции сервера по запросу клиента
	bool AT_DCServiceOp(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_in, CaplDataBuf &data_out);
	// Возвращает строку временного пароля для дублицирования сессии
	bool AT_DCGetString4DupSession(CString &spetial_string);
	bool AT_DCGetString4DupSession(/*[in,out]*/ AplNetErrors &aplError, CaplDataBuf &data_out);

	// Возвращает все варианты значений определенного атрибута
	bool AT_DCGetAllAttrValues(/*[in,out]*/AplNetErrors &aplError,/*[in]*/ CaplDataBuf &data_in, /*[out]*/ CaplDataBuf &data_out);



	bool IsOperated();
	void Disconnect();
	bool IsConnected();
	bool Reconnect(bool asked=true, LPCTSTR file = 0, int line = 0, LPCTSTR date = 0);
	bool ForceReconnect();
	apl_NET_LoginData m_login_data;

	bool m_is_saved_login;

	// количество попыток повторить неудачный запрос данных с сервера
	int m_num_auto_repeat;
	// интервал в секундах между попытками повтора неудачного запроса сервера
	int m_timer_auto_repeat;

	// сообщение об ошибке чтения/повреждения данных не надо выводить чаще чем раз в секунду
	CaplTimeMeter m_tick_repeated_mess_time;

	// NetStepData устанавливает этот парметр в true когда выполнит все процедуры по установке соединения
	// а до того - показывать диалог восстановления соединения некорректно
	bool m_need_reconnect;
	// с сервера пришла команда с требованием заново залогиниться
	bool m_need_relogin;

	CDlgReconnect *m_dlg_reconnect;
	// управление поведением функций коннекта
	// 0 - первоначальная или ручная установка соединения
	// 1 - восстановление соединения при разрыве
	// 2 - переконнект по команде с сервера
	int m_internal_reconnect;
	// флаг завершения соединения
	bool m_isGlobalClose;

	void CloseReconnectDlg();

	DWORD m_tick_op;
	void ClearTickOp(){m_tick_op = 0;}
	DWORD GetTickOp(){return m_tick_op;}

	// При разрыве соединения транспорт показывает диалог с кнопками "восстановить" и "завершить работу"
	// если приложению надо отрабатывать завершение работы - оно утсанавливает эту функцию
	long (__cdecl *m_application_close_funct)(LPVOID param);
	CString m_application_reconnect_text;
	CaplNetStepData* m_data;

	void SetApplicationLevelLogMessage(bool (__cdecl *_ApplicationLevelLogMessageDlg)(LPCTSTR message));


protected:
	CConnectInfo* m_cif;

	CString m_am_user;
	CString m_am_pwd;
	int m_am_code1;
	int m_am_code2;

	// при ошибке сервера на клиенте появляется диалог с кнопками "повторить-пропустить-прервать"
	// Теперь принажатии "прервать" все запросы к серверу на 2 сек будут сразу возвращать false
	DWORD m_TickStop;

	bool m_server_stopping;
	CString m_def_server_name;
	CString m_description_serv_error;

	CString m_class_info;
	int m_used_version;
	CWnd* m_parent_wnd;

	CaplSocketClient* m_aplSocket;
	CString m_last_calling;

	AplNetErrors m_aplError;
	ASC_ERROR_CODES m_ascError;
	int m_wsaError;
	bool m_hide_mode;
	SOCKET m_temp_socket;
	DWORD m_thread_id;

	// Поддерживает ли сервер приложений работу с новыми лицензиями
	bool m_IsServer4AddLic; 

public:
	CaplDataBuf m_tmp_buf;
	CaplDataBuf m_TempStore;
	CString m_source;

protected:
	HANDLE m_event_TempStore; //?? Надо бы переделать на простой булевый флаг
	CRITICAL_SECTION m_CS_TempStore;
	CString m_CompName;

public:

	//определение ip адреса машины клиента (только если установлено соединение с сервреом!)
	UINT32 GetCompIp(){if(m_aplSocket == 0)return 0; return m_aplSocket->GetCompIp();}
	//определение ip адреса машины клиента (только если установлено соединение с сервреом!)
	bool GetCompName(CString &name);
	bool GetCompName();
	// трансляция функций CaplSocketClient-а в наши функции
	ASC_ERROR_CODES GetLastAscError();
	void ClearInternalData();
	bool TestTempStoreFree(bool block);
	CString	GetDescriptionLastError();
	CString	GetDescriptionServError();
	bool Connect(bool bDlgMode = true);
	void SetWaitDlgText(LPCTSTR waitdlg_text = 0);
	bool IsServerLocal();
	void SetBreak(bool state);
	void SetManageMode(int manage_mode);
	void SetHideMode(bool mode = false);
	void Attach();
	void Detach();
	void SetHalt();
	
		

	// Соединение с сервером. Еслим сервер локальный - пытается запустить его
	// Внимание! При ошибке генерит исключение!
	bool ConnectWithTestLocal(CConnectInfo* cif, CString def_server_name, bool foreground_main_wnd=true, bool bDlgMode = true);

	// рассоединение на уровне tcp
	void DisconnectFull();

};

void TestReadServError(CaplDataBuf &readed_data_buf, CaplNetStepData* m_data, CString &m_description_serv_error);

#endif // !defined(AFX_TRANSPORTSOCKETCLIENT_H__130138C3_0463_4571_836D_127B95B69339__INCLUDED_)
