// myZipView.cpp : implementation of the CMyZipView class
//

#include "stdafx.h"
#include "Afxdlgs.h"
#include "myZip.h"
#include "cfDlg.h"

#include "myZipDoc.h"
#include "myZipView.h"

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

char inpfolder[1024];
int options = 0;

char  Buffer[NFILES][BUFFERSIZE];
char  *Bufferptr;
Huffnode  *    heap[40];
int            hash[128];          /* hashes characters to their posisions in the codes
				    * array. */
CString  Filenames[NFILES];
int   fnum = 0;
int condense = 1;
float trhld1 = 0;
float trhld2 = 0;

/////////////////////////////////////////////////////////////////////////////
// CMyZipView

IMPLEMENT_DYNCREATE(CMyZipView, CScrollView)

BEGIN_MESSAGE_MAP(CMyZipView, CScrollView)
	//{{AFX_MSG_MAP(CMyZipView)
	ON_COMMAND(ID_ZIPFILE, OnZipFile)
	ON_COMMAND(ID_UNZIPFILE, OnUnZipFile)
	ON_COMMAND(ID_OPTIONS, OnOptions)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMyZipView construction/destruction

CMyZipView::CMyZipView()
{
	// TODO: add construction code here

}

CMyZipView::~CMyZipView()
{
}

BOOL CMyZipView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CMyZipView drawing

void CMyZipView::OnDraw(CDC* pDC)
{
	int i;
	CMyZipDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	TEXTMETRIC tm;
	int yval = 0;
	pDC->GetTextMetrics(&tm);
	for (i = 0; i < pDoc->line_number; i++) {
		pDC->TextOut(0, yval, pDoc->data_string[i]);
		yval += tm.tmHeight;
	}
}

void CMyZipView::OnInitialUpdate() {
	SetScrollSizes(MM_TEXT, GetDocument()->GetDocSize());
}

void CMyZipView::OnZipFile()
{
	//char str[100];
	int i;
	CMyZipDoc *pDoc = GetDocument();
	pDoc->prefix = "Ziping ";
	char FilterString[] = "Data files (*.dat)\0*.dat\0\0";
	CFileDialog dlg(TRUE);
	ASSERT_VALID(pDoc);
	dlg.m_ofn.lpstrFilter = (LPSTR) FilterString;
	dlg.m_ofn.lpstrTitle = "Zip file ...";
	dlg.m_ofn.Flags |= OFN_ALLOWMULTISELECT |
		OFN_FILEMUSTEXIST |
		OFN_NONETWORKBUTTON | OFN_NOTESTFILECREATE |
		OFN_PATHMUSTEXIST;
	if (dlg.DoModal() == IDOK) {
		POSITION ps = dlg.GetStartPosition();
		while (ps != NULL) {
			pDoc->msg = dlg.GetNextPathName(ps);
			pDoc->data_string[pDoc->line_number++] = pDoc->prefix + pDoc->msg;
			if (pDoc->line_number == MAX_LINES)
				pDoc->line_number = 0;
			Filenames[fnum++] = pDoc->msg;
			if (fnum == NFILES) {
				fnum = 0;
				encode(Filenames, NFILES, this);
			}
		}
		if (fnum) {
			for (i = 0; i < fnum; i++)
			encode(Filenames, fnum, this);
		}
	}
	// TODO: add draw code for native data here
	CClientDC dc(this);
	OnPrepareDC(&dc);
	TEXTMETRIC tm;
	int yval = 0;
	dc.GetTextMetrics(&tm);
	for (i = 0; i < pDoc->line_number; i++) {
		dc.TextOut(0, yval, pDoc->data_string[i]);
		yval += tm.tmHeight;
	}
}

void CMyZipView::OnUnZipFile()
{
	int i;
	char FilterString[] = "Data files (*.myzip)\0*.myzip\0\0";
	CFileDialog dlg(TRUE);
	CMyZipDoc* pDoc = GetDocument();
	pDoc->prefix = "Unziping ";
	ASSERT_VALID(pDoc);
	dlg.m_ofn.lpstrFilter = (LPSTR) FilterString;
	dlg.m_ofn.lpstrTitle = "Unzip file ...";
	dlg.m_ofn.Flags |= OFN_ALLOWMULTISELECT |
		OFN_FILEMUSTEXIST |
		OFN_NONETWORKBUTTON | OFN_NOTESTFILECREATE |
		OFN_PATHMUSTEXIST;
	if (dlg.DoModal() == IDOK) {
		POSITION ps = dlg.GetStartPosition();
		while (ps != NULL) {
			pDoc->msg = dlg.GetNextPathName(ps);
			pDoc->data_string[pDoc->line_number++] = pDoc->prefix + pDoc->msg;
			if (pDoc->line_number == MAX_LINES)
				pDoc->line_number = 0;
			extract(pDoc->msg.GetBuffer(pDoc->msg.GetLength()), this);
		}
	}
	// TODO: add draw code for native data here
	CClientDC dc(this);
	OnPrepareDC(&dc);
	TEXTMETRIC tm;
	int yval = 0;
	dc.GetTextMetrics(&tm);
	for (i = 0; i < pDoc->line_number; i++) {
		dc.TextOut(0, yval, pDoc->data_string[i]);
		yval += tm.tmHeight;
	}
}

/////////////////////////////////////////////////////////////////////////////
// CMyZipView diagnostics

#ifdef _DEBUG
void CMyZipView::AssertValid() const
{
	CView::AssertValid();
}

void CMyZipView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CMyZipDoc* CMyZipView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CMyZipDoc)));
	return (CMyZipDoc*)m_pDocument;
}

void extract(char *filename, CMyZipView *view) {
  HANDLE       file;
  Huffnode *   root;
  DWORD        dwActBytes;
  int          filenums, i;
  char         Filenames[50][200];
  int          filenamelength;
  CMyZipDoc *pDoc = view->GetDocument();

  // delete after debug
  //char str[100];

  file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

  ReadFile(file, &filenums, sizeof(int), &dwActBytes, NULL);
  for (i = 0; i < filenums; i++) {
	ReadFile(file, &filenamelength, sizeof(int), &dwActBytes, NULL);
    ReadFile(file, Filenames[i], sizeof(char) * filenamelength, &dwActBytes, NULL);
	Filenames[i][filenamelength] = '\0';
	pDoc->data_string[pDoc->line_number] = "        Created .\\dat\\";
	pDoc->data_string[pDoc->line_number] += Filenames[i];
	pDoc->data_string[pDoc->line_number++] += ".dat";
	if (pDoc->line_number == MAX_LINES)
		pDoc->line_number = 0;
  }

  CClientDC dc(view);
  view->OnPrepareDC(&dc);
  TEXTMETRIC tm;
  int yval = 0;
  dc.GetTextMetrics(&tm);
  for (i = 0; i < pDoc->line_number; i++) {
	dc.TextOut(0, yval, pDoc->data_string[i]);
	yval += tm.tmHeight;
  }
 
  root = constructtree(file);
  decodestream(file, root, Filenames, filenums);
  del(root);
}

Huffnode * constructtree(HANDLE filed) {
  char                  car;
  int                   freq;
  int                   size = 1;
  DWORD                 dwActBytes;

  // delete after debug
  //char str[100];

  while (1) {
    ReadFile(filed, &car, sizeof(char), &dwActBytes, NULL);
    if (car == '\b') 
      break;
    ReadFile(filed, &freq, sizeof(int), &dwActBytes, NULL);
    heap[size] = (Huffnode *)calloc(1, sizeof(Huffnode));
    heap[size]->car = car;
    heap[size++]->freq = freq;
  }
  size--;

  buildheap(heap, size);
  return buildcodetree(heap, size);
}

void decodestream(HANDLE filed, Huffnode *root, char filenames[NFILES][200], int filenums) {
  char        newfilename[100];
  int         length;
  short       Buffer[20000],
              bit;
  char        asci[BUFFERSIZE];
  char        *charptr;
  int         offset;
  short       posision;
  int         i, j,
              place = 0;
  Huffnode    *ptr = root;
  HANDLE      ascifile;
  DWORD       dwActBytes;
	char        str[1024];

	if (options) {
		wsprintf(str, "%s\\dat", inpfolder);
	}
	else
	  wsprintf(str, ".\\dat");

	CreateDirectory(str, NULL);
  for (j = 0; j < filenums; j++) {
    ReadFile(filed, &length, sizeof(int), &dwActBytes, NULL);
    ReadFile(filed, &posision, sizeof(short), &dwActBytes, NULL);
    ReadFile(filed, Buffer, length * sizeof(short), &dwActBytes, NULL);

    for (offset = 0; offset < length - 1; offset++) {
      for (i = sizeof(short) * 8 - 1; i >= 0; i--) {
        bit = Buffer[offset] >> i;
        if (bit & 1) {
		    if (ptr->right) {
	          ptr = ptr->right;
			}
	        else {
		      asci[place] = ptr->car;
			  if (asci[place] == '\n') {
				  asci[place] = '\r';
				  place++;
				  asci[place] = '\n';
			  }
			  if (asci[place] < '0' || asci[place] > '9') {
				  if (asci[place] == ' ') {
					place++;
					asci[place] = '\r';
					place++;
					asci[place] = '\n';
				  }
			  }
			  place++;
		      ptr = root->right;
			}	
		}
        else {
		  if (ptr->left) {
			ptr = ptr->left;
		  }
	      else {
	        asci[place] = ptr->car;
			if (asci[place] == '\n') {
				  asci[place] = '\r';
				  place++;
				  asci[place] = '\n';
			  }
			if (asci[place] < '0' || asci[place] > '9') {
				  if (asci[place] == ' ') {
					place++;
					asci[place] = '\r';
					place++;
					asci[place] = '\n';
				  }
			  }
			place++;
	        ptr = root->left;
		  }
		}
	  }
	}

    for (i = sizeof(short) * 8 - 1; i >= posision; i--) {
      bit = Buffer[offset] >> i;
      if (bit & 1) {
        if (ptr->right)
	      ptr = ptr->right;
        else {
	      asci[place] = ptr->car;
		  if (asci[place] == '\n') {
				  asci[place] = '\r';
				  place++;
				  asci[place] = '\n';
			}
		  if (asci[place] < '0' || asci[place] > '9') {
				  if (asci[place] == ' ') {
					place++;
					asci[place] = '\r';
					place++;
					asci[place] = '\n';
				  }
			  }
			place++;
	      ptr = root->right;
		}
	  }
      else {
        if (ptr->left)
	      ptr = ptr->left;
        else {
	      asci[place] = ptr->car;
		  if (asci[place] == '\n') {
				  asci[place] = '\r';
				  place++;
				  asci[place] = '\n';
			  }
		  if (asci[place] < '0' || asci[place] > '9') {
				  if (asci[place] == ' ') {
					place++;
					asci[place] = '\r';
					place++;
					asci[place] = '\n';
				  }
			  }
			place++;
	      ptr = root->left;
		}
	  }
	}

    if (!ptr->left) {
      asci[place++] = ptr->car;
	}

	strcpy(newfilename, str);
	strcat(newfilename, "\\");
    strcat(newfilename, filenames[j]);
    strcat(newfilename, ".test");
	//MessageBox(NULL, newfilename, "debug", MB_OK);
    ascifile = CreateFile(newfilename, GENERIC_WRITE, 0,
		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    WriteFile(ascifile, asci, place * sizeof(char), &dwActBytes, NULL);
    CloseHandle(ascifile);
	ptr = root;
	place = 0;
  }
  CloseHandle(filed);
  return;
}

void           buildheap(Huffnode   **heap, 
			             int        size) {
  int i;
  for (i = (int) size/2; i >= 1; i--)
    heapify(size, i);
}

Huffnode *     buildcodetree(Huffnode   **heap, 
			     int        size) {
  int          i,
               org_size = size;
  Huffnode     *left,
               *right,
               *newnode;
  
  for (i = 0; i < org_size - 1; i++) {
    newnode = (Huffnode *)calloc(1, sizeof(Huffnode));
    left = getmin(heap, &size);
    right = getmin(heap, &size);
    newnode->freq = left->freq + right->freq;
    newnode->left = left;
    newnode->right = right;
    insert(newnode, &size, heap);
  }
  return getmin(heap, &size);
}

void           heapify(int            size,
		               int            posision) {
  int          l,
               r,
               smallest;
  Huffnode *   tmp;

  l = left(posision);
  r = right(posision);
  if (l <= size && heap[l]->freq < heap[posision]->freq)
    smallest = l;
  else
    smallest = posision;
  if (r <= size && heap[r]->freq < heap[smallest]->freq)
    smallest = r;
  if (smallest != posision) {
    tmp = heap[smallest];
    heap[smallest] = heap[posision];
    heap[posision] = tmp;
    heapify(size, smallest);
  }
}

int left(int i) {
  return 2 * i;
}

int right(int i) {
  return 2 * i + 1;
}

Huffnode *     getmin(Huffnode **     heap, 
		      int *           size) {
  
  Huffnode *   min;

  if (*size < 1) {
    MessageBox(NULL, "Heap underflow", "Error", MB_OK);
    exit(0);
  }
  min = heap[1];
  heap[1] = heap[*size];
  (*size)--;
  heapify(*size, 1);
  return min;
}

void           insert(Huffnode *      newnode,
		      int *           size,
		      Huffnode **     heap) {
  int parent, child;
  Huffnode *tmp;

  (*size)++;
  heap[*size] = newnode;
  parent = (int)(*size)/2;
  child = *size;
  while (parent >= 1) {
    if (heap[parent]->freq > heap[child]->freq) {
      tmp = heap[parent];
      heap[parent] = heap[child];
      heap[child] = tmp;
      child = parent;
      parent /= 2;
    }
    else
      parent = 0;
  }
}

int parent(int i) {
  return (int) i/2;
}

void encode(CString filename[NFILES], int numfiles, CMyZipView *view) {
  
  int k, l;
  Huffnode      *root;
  int           size = 1;
  Codes         *codes;
  char          space = '\b';
  HANDLE        file;
  DWORD         dwActBytes;
  char          newfilename[200];
  char *        charptr;
  char *        Bufferptr = Buffer[0];
  int i, filenamelength;
  char car;
  CMyZipDoc *pDoc = view->GetDocument();

  // delete the following after debugging
  char str[100];
  
  for (i = 0; i < numfiles; i++) {
	Bufferptr = Buffer[i];
    file = CreateFile(filename[i], GENERIC_READ, FILE_SHARE_READ,
	  	NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (!file) {
      wsprintf(str, "did not open the %s", filename);
	  MessageBox(NULL, str, "error", MB_OK);
	  exit(0);
	}

    ReadFile(file, &car, sizeof(char), &dwActBytes, NULL);

    while (dwActBytes == 1) {
      *Bufferptr = car;
	  Bufferptr++;
	  ReadFile(file, &car, sizeof(char), &dwActBytes, NULL);
	}

    *Bufferptr = '\0';
    CloseHandle(file);
  }
	
  getfreq(&size, numfiles);

 /* for (l = 0 ; l < numfiles; l++) {

	strcpy(newfilename, filename[l]);
	charptr = strstr(newfilename, ".dat");
	strcpy(charptr, ".mytest");
	
	file = CreateFile(newfilename, GENERIC_WRITE, 0,
		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

	WriteFile(file, Buffer[l], strlen(Buffer[l]), &dwActBytes, NULL);

	CloseHandle(file);
  }*/

  strcpy(newfilename, filename[0]);
  charptr = strstr(newfilename, ".dat");
  strcpy(charptr, ".myzip");

  //here

  pDoc->data_string[pDoc->line_number] = "        Created ";
  pDoc->data_string[pDoc->line_number++] += newfilename;
  if (pDoc->line_number == MAX_LINES)
		pDoc->line_number = 0;

  CClientDC dc(view);
  view->OnPrepareDC(&dc);
  TEXTMETRIC tm;
  int yval = 0;
  dc.GetTextMetrics(&tm);
  for (i = 0; i < pDoc->line_number; i++) {
	dc.TextOut(0, yval, pDoc->data_string[i]);
	yval += tm.tmHeight;
  }


  file = CreateFile(newfilename, GENERIC_WRITE, 0,
		NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

  if (!file) {
    wsprintf(str, "failed to open file");
	MessageBox(NULL, str, "error", MB_OK);
  }

  WriteFile(file, &numfiles, sizeof(int), &dwActBytes, NULL);
  for (i = 0; i < numfiles; i++) {
	CString newfile;
	int     slash;
	slash = filename[i].ReverseFind('\\');
	if (slash != -1)
		newfile = filename[i].Right(filename[i].GetLength() - slash - 1);
	else 
		newfile = filename[i].Right(filename[i].GetLength());
	slash = newfile.ReverseFind('.');
	if (slash != -1)
		newfile.Delete(slash, 4);
	filenamelength = strlen(newfile);
    WriteFile(file, &filenamelength, sizeof(int), &dwActBytes, NULL);
	WriteFile(file, newfile, filenamelength * sizeof(char), &dwActBytes, NULL);
  }

  for (i = 1; i <= size; i++) {
    WriteFile(file, &heap[i]->car, sizeof(char), &dwActBytes, NULL);
	if (!dwActBytes) {
      wsprintf(str, "failed to write into the file");
	  MessageBox(NULL, str, "error", MB_OK);
	}
    WriteFile(file, &heap[i]->freq, sizeof(int), &dwActBytes, NULL);
	if (!dwActBytes) {
      wsprintf(str, "failed to write into the file");
	  MessageBox(NULL, str, "error", MB_OK);
	}
  }
  WriteFile(file, &space, sizeof(char), &dwActBytes, NULL);
  if (!dwActBytes) {
    wsprintf(str, "failed to write space into the file");
    MessageBox(NULL, str, "error", MB_OK);
  }
  buildheap(heap, size);
  root = buildcodetree(heap, size);
  codes = assigncodes(root, size);
  buildstream(file, codes, numfiles);
  CloseHandle(file);
  cleanup(root, codes);
}

void           del(Huffnode * root) {
  if (root->left != NULL)
    del(root->left);
  if (root->right != NULL)
    del(root->right);
  free(root);
}

Huffnode **    getfreq(int *size, int numfiles) {
  int          freq[128] = {0};
  int          i, j;
  int          length = strlen(Buffer[0]);

  // delete the following after debugging
  char str[100];

  for (j = 0; j < numfiles; j++) {
    for (i = 0; i < length; i++) {
	  freq[(int)Buffer[j][i]]++;
	}
	length = strlen(Buffer[j + 1]);
  }

  for (i = 0; i < 128; i++) {
    if (freq[i]) {
		heap[*size] = (Huffnode *)calloc(1, sizeof(Huffnode));
		if (!heap[*size]) {
			wsprintf (str, "did not allocate heap size is %i", (*size) - 1);
			MessageBox(NULL, str, "Error", MB_OK);
		}
      heap[*size]->freq = freq[i];
      heap[*size]->car = i;
      (*size)++;
    }
  }
  (*size)--;
  return heap;
}

Codes *        assigncodes(Huffnode   *root,
			   int        size) {
  Codes        *codes = (Codes *)calloc(size, sizeof(Codes));
  short        index = 0;

  getCodes(root, codes, 0, &index, 0);
  return codes;
}

void           buildstream(HANDLE       file, 
			               Codes *      codes,
						   int          numfiles) {
  char str[100];
  short           stream[20000] = {0};
  int             i, j, k;
  short           posision = sizeof(unsigned short) * 8;
  int             masklength;
  short           *streamptr = stream;
  unsigned short  mask,
                  bits;
  DWORD           dwActBytes;
  int             length = strlen(Buffer[0]);
  int tmp1, tmp2;
  Codes *ptr;
  int gh;

  /*for (gh = 0; gh < 19; gh++) {
	wsprintf(str, "%i code %i nbits %i", gh, codes[gh].code, codes[gh].nbits);
	MessageBox(NULL, str, "debug", MB_OK);
  }*/

  for (j = 0; j < numfiles; j++) {
    for (i = 0; i < length; i++) {
		tmp1 = Buffer[j][i];
		tmp2 = hash[tmp1];
		ptr = &codes[hash[Buffer[j][i]]]; 
		mask = codes[hash[Buffer[j][i]]].code;    //.code;
		masklength = codes[hash[Buffer[j][i]]].nbits;
		posision = posision - masklength;
      if (posision < 0) {
        bits = mask >> abs(posision);
        (*streamptr) |= bits;
        streamptr++;
        posision = sizeof(unsigned short) * 8 + posision;
        bits = mask << posision;
        (*streamptr) |= bits;
	  }
      else {
        bits = mask << posision;
        (*streamptr) |= bits;
        if (!posision) {
	      posision = sizeof(unsigned short) * 8;
	      streamptr++;
		}
	  }
	}
  
  /* write out the rest of the file */
    i = streamptr - stream + 1;
	//wsprintf(str, "%i", i);
	//MessageBox(NULL, str, "debug", MB_OK);
    WriteFile(file, &i, sizeof(int), &dwActBytes, NULL);
    WriteFile(file, &posision, sizeof(short), &dwActBytes, NULL);
    WriteFile(file, stream, i * sizeof(short), &dwActBytes, NULL);
    streamptr = stream;
	posision = sizeof(unsigned short) * 8;
	for (k = 0; k < i + 10; k++)
		stream[k] = 0;
	if (j + 1 < NFILES)
		length = strlen(Buffer[j + 1]);
  }
}

void           getCodes(Huffnode *      root, 
			            Codes *         codes,
                        unsigned short  prefix, 
			            short *         index, 
			            short           nbits) {
  if (root->left && root->right) {
    prefix = prefix << 1;
    getCodes(root->left, codes, prefix, index, (short)nbits + 1);
    prefix = prefix | 1;
    getCodes(root->right, codes, prefix, index, nbits + 1);
  }
  else {
    codes[*index].code = prefix;
    codes[*index].nbits = nbits;
    (*index)++;
    hash[root->car] = (*index) - 1;
  }
}

void           cleanup(Huffnode *     root, 
					   Codes *        codes) {


  /* deallocate the code tree */

  del(root);

  /* deallocate the code array */

  free(codes);
}


#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMyZipView message handlers

void CMyZipView::OnOptions() 
{
	// TODO: Add your command handler code here
	WIN32_FIND_DATA     fileinfo;
	char searchstr[200] = {0};
	char filename[1024];
	HANDLE handle;
	CcfDlg dlg;
  int len = strlen(inpfolder), i, j;
	CMyZipDoc* pDoc = GetDocument();
	pDoc->prefix = "Unziping ";
	options = 1;

	if (dlg.DoModal() == IDOK) {

		if (inpfolder[len-1] == '/' ||
				inpfolder[len-1] == '\\')
				inpfolder[len-1] = '\0';

		ZeroMemory(&fileinfo, sizeof(WIN32_FIND_DATA));
		wsprintf(searchstr, "%s/*.myzip", inpfolder);

		i = strlen(searchstr);

#if defined(WIN32) || defined(__EMX__)
		for(j = 0; j < i; j++) {
			if (searchstr[j] =='/')
				searchstr[j] = '\\';
		}
#endif // WIN32 || __EMX__

		handle = FindFirstFile(searchstr, &fileinfo);
		if (handle == INVALID_HANDLE_VALUE)
			return;

		wsprintf(filename,"%s\\%s", inpfolder, fileinfo.cFileName);

		pDoc->msg = filename;
		pDoc->data_string[pDoc->line_number++] = pDoc->prefix + pDoc->msg;
			if (pDoc->line_number == MAX_LINES)
				pDoc->line_number = 0;
		extract(pDoc->msg.GetBuffer(pDoc->msg.GetLength()), this);
		while (FindNextFile(handle, &fileinfo)) {
			if (handle == INVALID_HANDLE_VALUE)
				return;
	
			wsprintf(filename,"%s\\%s", inpfolder, fileinfo.cFileName);

			pDoc->msg = filename;
			pDoc->data_string[pDoc->line_number++] = pDoc->prefix + pDoc->msg;
			if (pDoc->line_number == MAX_LINES)
				pDoc->line_number = 0;
			extract(pDoc->msg.GetBuffer(pDoc->msg.GetLength()), this);
		}
	}
	// TODO: add draw code for native data here
	CClientDC dc(this);
	OnPrepareDC(&dc);
	TEXTMETRIC tm;
	int yval = 0;
	dc.GetTextMetrics(&tm);
	for (i = 0; i < pDoc->line_number; i++) {
		dc.TextOut(0, yval, pDoc->data_string[i]);
		yval += tm.tmHeight;
	}
	options = 0;
}
