/////////////////////////////////////////////////////////////////////////////
//! \file RClientDlg.cpp
//! \brief Implementation
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include <time.h>
#include "Xml.h"
#include "RClient.h"
#include "RClientDlg.h"
#include "CConnectDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

CRClientDlg *pCRDlg;

/////////////////////////////////////////////////////////////////////////////
//! \brief CAboutDlg dialog used for App About
/////////////////////////////////////////////////////////////////////////////
class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

/////////////////////////////////////////////////////////////////////////////
//! \brief Constructor
/////////////////////////////////////////////////////////////////////////////
CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

/////////////////////////////////////////////////////////////////////////////
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
//! \brief CRClientDlg dialog
/////////////////////////////////////////////////////////////////////////////
CRClientDlg::CRClientDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CRClientDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CRClientDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CRClientDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CRClientDlg, CDialog)
	//{{AFX_MSG_MAP(CRClientDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDCANCEL, OnCancel)
	ON_BN_CLICKED(IDC_CONNECT, OnConnectD)
	ON_BN_CLICKED(IDC_CONNECTX, OnConnectX)
	ON_BN_CLICKED(IDC_DISCONNECT, OnDisconnectD)
	ON_BN_CLICKED(IDC_DISCONNECTX, OnDisconnectX)
	ON_BN_CLICKED(IDC_SETUP, OnSetup)
	ON_BN_CLICKED(IDC_READSTATUS, OnReadStatus)
	ON_BN_CLICKED(IDC_GETIMAGE, OnGetImage)
	ON_BN_CLICKED(IDC_SETEXPOSURE, OnSetExposure)
	ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
//! \brief CRClientDlg initializaion.
/////////////////////////////////////////////////////////////////////////////
BOOL CRClientDlg::OnInitDialog()
{
	HFONT fCourier;
	LOGFONT lf;

	CDialog::OnInitDialog();
	CWinApp *pApp = AfxGetApp();
	m_pszKey = "Settings"; // Registry Key
	m_bConnectedD = false;
	m_bConnectedX = false;

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strMenu;
		strMenu.LoadStringA(IDS_ABOUTBOX);
		if (!strMenu.IsEmpty())
		{
			pSysMenu->AppendMenuA(MF_SEPARATOR);
			pSysMenu->AppendMenuA(MF_STRING, IDM_ABOUTBOX, strMenu);
		}
		strMenu.LoadStringA(IDS_CLEARTEXT);
		if (!strMenu.IsEmpty())
			pSysMenu->AppendMenuA(MF_STRING, IDM_CLEARTEXT, strMenu);
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	m_pStatus = (CEdit*) GetDlgItem(IDC_STATUS);
	m_pReceive = (CEdit*) GetDlgItem(IDC_RECEIVE);

	// Generate font
	memset(&lf, 0, sizeof(LOGFONT)); // zero out font structure
	lf.lfHeight = 14;
	lf.lfWeight = FW_NORMAL;
	strcpy_s(lf.lfFaceName, 32, "Courier New");
	fCourier = CreateFontIndirect(&lf);
	m_pStatus->SendMessage(WM_SETFONT, (WPARAM) fCourier, TRUE);
	m_pReceive->SendMessage(WM_SETFONT, (WPARAM) fCourier, TRUE);

	m_iIPAddress = pApp->GetProfileInt(m_pszKey,   "IP_ADDRESS", 1);
	m_iPortAddress = pApp->GetProfileInt(m_pszKey, "IP_PORT", 2222);
	m_bAutoCon = pApp->GetProfileInt(m_pszKey, "AUTO_CON", 0);
	m_bXmlWrite = pApp->GetProfileInt(m_pszKey, "XML_WRITE", 0);
	strcpy_s(m_ReadDir,  _MAX_DRIVE+_MAX_DIR, pApp->GetProfileStringA(m_pszKey, "READ_DIR", ".\\"));
	strcpy_s(m_WriteDir, _MAX_DRIVE+_MAX_DIR, pApp->GetProfileStringA(m_pszKey, "WRITE_DIR", ".\\"));
	strcpy_s(m_BMPDir, _MAX_DRIVE+_MAX_DIR, pApp->GetProfileStringA(m_pszKey, "BMP_DIR", ".\\"));
	m_pCXml = new CXml;

	// Start threads
	pCRDlg = this;
	m_yEventHandling = true;
	m_hReadThreadX = ::CreateThread(NULL, NULL, ReadProcX,
		(LPVOID)this, NULL, &m_dwReadThreadID);
	m_hReadThreadD = ::CreateThread(NULL, NULL, ReadProcD,
		(LPVOID)this, NULL, &m_dwReadThreadID);
	m_hDirThread   = ::CreateThread(NULL, NULL, WatchDirectory,
		(LPVOID)this, NULL, &m_dwReadThreadID);
	
	if (m_bAutoCon)
		CDialog::SetTimer(1, 5000, NULL);
	return TRUE;  // return TRUE  unless you set the focus to a control
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Message handler: Menu.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if (nID == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else if (nID == IDM_CLEARTEXT)
	{
		ClearText(m_pStatus);
		ClearText(m_pReceive);
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

/////////////////////////////////////////////////////////////////////////////
// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

/////////////////////////////////////////////////////////////////////////////
//! The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
/////////////////////////////////////////////////////////////////////////////
HCURSOR CRClientDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Message handler: Exit button.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnCancel()
{
	int Status;
	Status = MessageBoxA("Quit Program?", "Attention!", MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON2);

	if (Status == IDYES)
	{
		m_yEventHandling = false;
		delete m_pCXml;
		DisconnectD();
		DisconnectX();
		SetEvent(m_hChange);
		Sleep(200);
		CDialog::OnCancel();
	}
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Message handler: Connect XML port.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnConnectX()
{
	ConnectX(1);
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Message handler: Connect Data port.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnConnectD() 
{
	ConnectD(1);
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Message handler: Disconnect XML port.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnDisconnectX()
{
	DisconnectX();
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Message handler: Disconnect Data port.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnDisconnectD() 
{
	DisconnectD();
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Message handler: Setup.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnSetup()
{
	CConnectDlg oDlg;
	CWinApp *pApp = AfxGetApp();

	oDlg.m_iIPAddress = m_iIPAddress;
	oDlg.m_iPortAddress = m_iPortAddress;
	oDlg.m_bAutoCon = m_bAutoCon;
	oDlg.m_bXmlWrite = m_bXmlWrite;
	strcpy_s(oDlg.m_ReadDir,  _MAX_DRIVE+_MAX_DIR, m_ReadDir);
	strcpy_s(oDlg.m_WriteDir, _MAX_DRIVE+_MAX_DIR, m_WriteDir);
	strcpy_s(oDlg.m_BMPDir, _MAX_DRIVE+_MAX_DIR, m_BMPDir);

	if (oDlg.DoModal() == IDOK)
	{
		m_iIPAddress = oDlg.m_iIPAddress;
		m_iPortAddress = oDlg.m_iPortAddress;
		m_bAutoCon = oDlg.m_bAutoCon;
		m_bXmlWrite = oDlg.m_bXmlWrite;
		strcpy_s(m_ReadDir, _MAX_DRIVE+_MAX_DIR, oDlg.m_ReadDir);
		strcpy_s(m_WriteDir, _MAX_DRIVE+_MAX_DIR, oDlg.m_WriteDir);
		strcpy_s(m_BMPDir, _MAX_DRIVE+_MAX_DIR, oDlg.m_BMPDir);

		// Write values in Registry
		pApp->WriteProfileInt(m_pszKey, "IP_ADDRESS", m_iIPAddress);
		pApp->WriteProfileInt(m_pszKey, "IP_PORT",    m_iPortAddress);
		pApp->WriteProfileInt(m_pszKey, "AUTO_CON", m_bAutoCon);
		pApp->WriteProfileInt(m_pszKey, "XML_WRITE", m_bXmlWrite);
		pApp->WriteProfileStringA(m_pszKey, "READ_DIR", m_ReadDir);
		pApp->WriteProfileStringA(m_pszKey, "WRITE_DIR", m_WriteDir);
		pApp->WriteProfileStringA(m_pszKey, "BMP_DIR", m_BMPDir);

		if (m_bAutoCon)
			CDialog::SetTimer(1, 5000, NULL);
		else
			CDialog::KillTimer(1);
	}
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Message handler: Read Status.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnReadStatus()
{
	if (!m_bConnectedX)
		return;
	m_pCXml->ReadStatus();
}
/////////////////////////////////////////////////////////////////////////////
//! \brief Message handle: Get Image.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnGetImage()
{
	if (!m_bConnectedX)
		return;
	m_pCXml->ImageRequest();
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Message handle: Set Exposure.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnSetExposure()
{
	if (!m_bConnectedX)
		return;
	m_pCXml->SetExposure();
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Message handler: Timer function.
//!
//! Tries to connect sockets.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::OnTimer(UINT_PTR nIDEvent)
{
	if (m_bConnectedX == false && m_bConnectedD == false)
		PrintText("Try to connect...");
	if (m_bConnectedX == false)
		ConnectX(0);
	if (m_bConnectedD == false)
		ConnectD(0);

	CDialog::OnTimer(nIDEvent);
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Connect to XML port.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::ConnectX(int Show)
{
	struct sockaddr_in sin;
	char Text[256];

	if (Show)
		DisconnectX();

	m_sSocketX = socket(AF_INET, SOCK_STREAM, 0);
	
	sin.sin_family      = AF_INET;
	sin.sin_addr.s_addr = htonl(m_iIPAddress);
	sin.sin_port        = htons((u_short)m_iPortAddress);
	
	if (connect(m_sSocketX, (struct sockaddr *)&sin, sizeof(sin) ) < 0)
	{
		if (Show)
		{
			sprintf_s(Text, 256, "Cannot connect (%d).\n", WSAGetLastError());
			AfxMessageBox(Text);
		}
		m_bConnectedX = false;
	}
	else
	{
		m_bConnectedX = true;
		PrintText("Connected XML");
	}
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Connect to Data port.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::ConnectD(int Show)
{
	struct sockaddr_in sin;
	char Text[256];

	if (Show)
		DisconnectD();

	m_sSocketD = socket(AF_INET, SOCK_STREAM, 0);
	
	sin.sin_family      = AF_INET;
	sin.sin_addr.s_addr = htonl(m_iIPAddress);
	sin.sin_port        = htons((u_short)m_iPortAddress+1);
	
	if (connect(m_sSocketD, (struct sockaddr *)&sin, sizeof(sin) ) < 0)
	{
		if (Show)
		{
			sprintf_s(Text, 256, "Cannot connect (%d).\n", WSAGetLastError());
			AfxMessageBox(Text);
		}
		m_bConnectedD = false;
	}
	else
	{
		m_bConnectedD = true;
		PrintText("Connected Data");
	}
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Disconnect XML port.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::DisconnectX()
{
	if (m_bConnectedX)
	{
		closesocket(m_sSocketX);
		m_bConnectedX = false;
		PrintText("Disconnected XML");
	}
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Disconnect Data port.
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::DisconnectD()
{
	if (m_bConnectedD)
	{
		m_bConnectedD = false;
		closesocket(m_sSocketD);
		PrintText("Disconnected Data");
	}
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Print text in edit control.
//! \param Text Text
//! \param pControl Edit control
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::PrintText(CString Text, CEdit *pControl)
{
	CString temp;
	int i, j, k;

	if (pControl==NULL)
		pControl = m_pStatus;

	pControl->GetWindowText(temp);
	i = pControl->GetLineCount();
	
	if (i>200) // Limitation
	{
		for (k=0; k<i-200; k++)
		{
			j = temp.Find('\n'); // Clear first lines
			temp.Delete(0, j+1);
		}
	}

	temp += Text; // Append text
	temp += "\r\n";
	pControl->SetWindowText(temp);
	i = pControl->GetLineCount();
	pControl->LineScroll(i, 0);
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Clears text in edit control.
//! \param pControl Edit control
/////////////////////////////////////////////////////////////////////////////
void CRClientDlg::ClearText(CEdit *pControl)
{
	if (pControl==NULL)
		pControl = m_pStatus;

	pControl->SetWindowText("");
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Sends string.
//! \param Text String
//! \return Error code
/////////////////////////////////////////////////////////////////////////////
int CRClientDlg::Send(CString Text)
{
	if (m_sSocketX == INVALID_SOCKET)
		return -1;

	send(m_sSocketX, Text, Text.GetLength() , 0);
	return 0;
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Task: Read from Data socket.
//! \param pParam Pointer to CRClientDlg class.
/////////////////////////////////////////////////////////////////////////////
DWORD WINAPI CRClientDlg::ReadProcD(LPVOID pParam)
{
	static int ICount = 0;
	int i;
	unsigned int FSize;
	unsigned int Pos;
	char Buffer[128];
	char Header[4];
	char *FBuf;
	CString Text, FName;
	CFile WFile;
	CRClientDlg *pDlg = (CRClientDlg*)pParam;

	do
	{
		if (!pDlg->m_bConnectedD)
		{
			Sleep(50);
			continue;
		}

		i = recv(pDlg->m_sSocketD, Buffer, 4, 0);
		if (i <= 0)
		{
			pDlg->DisconnectD();
			continue;
		}

		i = recv(pDlg->m_sSocketD, Header, 4, 0);
		if (i <=0)
		{
			pDlg->DisconnectD();
			continue;
		}

		FSize = ((int*)Buffer)[0];
		if (FSize>0)
		{
			FName.Format("%sFile%d.%s", pDlg->m_BMPDir, ICount++, Header);
			Text.Format("FName: %s\r\nFSize: %d", FName, FSize);
			pDlg->PrintText(Text);
			Pos = 0;
			FBuf = new char[FSize];
			do
			{
				i = recv(pDlg->m_sSocketD, &FBuf[Pos], 128, 0);
				if (i>0)
				{
					Pos += i;
				}
			}	while (i>0 && Pos<FSize);

			if (WFile.Open(FName, CFile::modeCreate | CFile::modeReadWrite))
			{
				WFile.Write(FBuf, FSize);
				WFile.Close();
				pDlg->PrintText("OK");
			}
			delete FBuf;
		}
	} while (pDlg->m_yEventHandling == true);

	return 0;
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Task: Read from XML socket.
//! \param pParam Pointer to CRClientDlg class.
/////////////////////////////////////////////////////////////////////////////
DWORD WINAPI CRClientDlg::ReadProcX(LPVOID pParam)
{
	int nRest = 0;
	int nPos = 0;
	int nResult = 0;
	int XMLPos = 0;
	int end;
	int Num;
	bool bNewCommand;
	unsigned int FSize;
	char Buffer[256];
	char *XMLString, *SendString;
	BOOL bOk;
	time_t ltime;
	struct tm newtime;
	CString Text, WFName;
	CFile WFile;
	CRClientDlg *pDlg = (CRClientDlg*)pParam;

	XMLString = new char[1024*256];

	do
	{
		if (!pDlg->m_bConnectedX)
		{
			Sleep(50);
			continue;
		}

		//=== Still rest from last receive? ===
		bNewCommand = false;
		if (nRest)
		{
			if (strncmp(&Buffer[nPos], "<?xml", 5) == 0) // New command ?
				bNewCommand = true;
			else
			{
				do
				{
					XMLString[XMLPos] = Buffer[nPos];
					end = strncmp(&XMLString[XMLPos-12], "</VisionCam>", 12);
					XMLPos++;
					nPos++;
				} while (nPos<nResult && (end != 0));
			}
			nRest = 0;
		}

		if (bNewCommand == false)
		{
			nResult = recv(pDlg->m_sSocketX, Buffer, 128, 0);
			if (nResult == 0)
			{
				pDlg->DisconnectX();
				pDlg->DisconnectD();
				continue;
			}
			if (nResult < 0)
				continue;
		}

		//=== Assemble command ===
		end = 1;
		if (strncmp(Buffer, "<?xml", 5) == 0) // New command
		{
			bNewCommand = true;
			nPos = 0;
		}

		if (bNewCommand)
		{
			XMLPos = 0;
			do
			{
				XMLString[XMLPos] = Buffer[nPos];
				end = strncmp(&XMLString[XMLPos-12], "</VisionCam>", 12);
				XMLPos++;
				nPos++;
			} while (nPos<nResult && (end != 0));
		}
		else // append data
		{
			nPos = 0;
			do
			{
				XMLString[XMLPos] = Buffer[nPos];
				end = strncmp(&XMLString[XMLPos-12], "</VisionCam>", 12);
				XMLPos++;
				nPos++;
			} while (nPos<nResult && (end != 0));
		}

		//=== End of command found ===
		if (end == 0)
		{
			XMLString[XMLPos] = Buffer[nPos];
			XMLString[XMLPos+1] = 0;
			if (XMLString[0] == '\n')
				SendString = &XMLString[1];
			else
				SendString = XMLString;
			XMLPos = 0;
			if (nPos<nResult-1)
				nRest = 1;
			else
				nPos = nRest = 0;
			pDlg->PrintText(SendString, pDlg->m_pReceive);

			//=== Write file ===
			if (pDlg->m_bXmlWrite)
			{
				FSize = strlen(XMLString);
				time(&ltime);
				localtime_s(&newtime, &ltime);
				Num = 0;
				do
				{
					WFName.Format("%s%04d-%02d-%02d %02d-%02d-%02d-%03d.xml",
							pDlg->m_WriteDir, newtime.tm_year+1900, newtime.tm_mon+1,
							newtime.tm_mday, newtime.tm_hour, newtime.tm_min, newtime.tm_sec, Num);
					Num++;
					bOk = WFile.Open(WFName, CFile::modeRead);
					if (bOk)
						WFile.Close();
				} while (bOk);

				if (WFile.Open(WFName, CFile::modeCreate | CFile::modeReadWrite))
				{
					WFile.Write(SendString, FSize);
					WFile.Close();
				}
			}
		}
		else if (nPos<nResult)
			nRest = 1;
	} while (pDlg->m_yEventHandling == true);

	delete XMLString;
	return 0;
}

/////////////////////////////////////////////////////////////////////////////
//! \brief Task: Watch directory changes.
//! \param pParam Pointer to CRClientDlg class.
/////////////////////////////////////////////////////////////////////////////
DWORD WINAPI CRClientDlg::WatchDirectory(LPVOID pParam)
{
	CRClientDlg *pDlg = (CRClientDlg*)pParam;
	DWORD dwWaitStatus;
	DWORD FSize;
	BOOL bNext;
	bool bActive = true;
	HANDLE hFind;
	WIN32_FIND_DATA FindData;
	CString SFName, DFName;
	CFile RFile;
	char *FBuf;

	//=== Remove old files ===
	SFName.Format("%s\\*.xml", pDlg->m_ReadDir);
	hFind = FindFirstFileA(SFName, &FindData);
	if (hFind!= INVALID_HANDLE_VALUE)
	{
		DFName.Format("%s%s", pDlg->m_ReadDir, FindData.cFileName);
		DeleteFileA(DFName);
		do
		{
			bNext = FindNextFileA(hFind, &FindData);
			DFName.Format("%s%s", pDlg->m_ReadDir, FindData.cFileName);
			DeleteFileA(DFName);
		} while (bNext);
	}

	pDlg->m_hChange = CreateEvent(NULL, FALSE, FALSE, NULL);

	//=== Main loop ===
	while (bActive)
	{
		// Wait for exit notification.
		dwWaitStatus = WaitForSingleObject(pDlg->m_hChange, 100);
		if (dwWaitStatus == WAIT_OBJECT_0)
			bActive = false;
		else
		{
			// Check if a file was created.
			hFind = FindFirstFileA(SFName, &FindData);
			if (hFind != INVALID_HANDLE_VALUE)
			{
				DFName.Format("%s%s", pDlg->m_ReadDir, FindData.cFileName);

				if (RFile.Open(DFName, CFile::modeRead))
				{
					FSize = (DWORD)RFile.GetLength();
					FBuf = new char[FSize+1];
					RFile.Read(FBuf, FSize);
					RFile.Close();
					FBuf[FSize] = 0;
					pDlg->PrintText(FBuf);
					pDlg->Send(FBuf);
					delete FBuf;
					DeleteFileA(DFName);
				}
			}
		}
	}
	return 0;
}

/////////////////////////////////////////////////////////////////////////////

